@tangle-network/agent-runtime 3.0.17 → 3.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +1 -1
- package/dist/{delegate-B9hjoWtv.js → delegate-B5a4wCau.js} +2 -2
- package/dist/{delegate-B9hjoWtv.js.map → delegate-B5a4wCau.js.map} +1 -1
- package/dist/durable.js +2 -2
- package/dist/{graph-DITmb_sh.js → graph-HaMcqUWX.js} +2 -2
- package/dist/{graph-DITmb_sh.js.map → graph-HaMcqUWX.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/kernel.js +4 -4
- package/dist/{loop-runner-DYrzAEL1.js → loop-runner-Df3gLvJm.js} +2 -2
- package/dist/{loop-runner-DYrzAEL1.js.map → loop-runner-Df3gLvJm.js.map} +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +2 -2
- package/dist/mcp/index.js +2 -2
- package/dist/{runtime-Bv8Fg8_o.js → runtime-DuCYicSd.js} +4 -4
- package/dist/{runtime-Bv8Fg8_o.js.map → runtime-DuCYicSd.js.map} +1 -1
- package/dist/{server-CJKgAwAC.js → server-BP7d8yGG.js} +2 -2
- package/dist/{server-CJKgAwAC.js.map → server-BP7d8yGG.js.map} +1 -1
- package/dist/{supervise-Cm10bCQE.js → supervise-BHxxCvbk.js} +27 -17
- package/dist/supervise-BHxxCvbk.js.map +1 -0
- package/dist/testing.js +10 -10
- package/package.json +1 -1
- package/dist/supervise-Cm10bCQE.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-CJKgAwAC.js","names":[],"sources":["../src/mcp/delegation-trace.ts","../src/mcp/delegation-store.ts","../src/mcp/feedback-store.ts","../src/mcp/task-queue.ts","../src/mcp/tools/delegate.ts","../src/mcp/tools/delegate-feedback.ts","../src/mcp/tools/delegate-ui-audit.ts","../src/mcp/types.ts","../src/mcp/tools/delegation-history.ts","../src/mcp/tools/delegation-status.ts","../src/mcp/server.ts"],"sourcesContent":["/**\n *\n * Compact loop-trace tee for the delegation journal.\n *\n * The OTEL exporter ({@link createPropagatingTraceEmitter}) is a no-op\n * without `OTEL_EXPORTER_OTLP_ENDPOINT`, which leaves delegated work streams\n * dark in practice. This module derives the same loop → round → branch span\n * tree (via the shared {@link buildLoopSpanNodes} builder) into a small,\n * JSON-safe shape persisted directly on the `DelegationRecord` — observable\n * through `delegation_status` with no collector infrastructure. Both sinks\n * coexist: the OTEL export path is unchanged.\n *\n * Payload discipline: a record's trace is hard-capped (spans + serialized\n * bytes). Past the cap the OLDEST spans are dropped and the record carries a\n * `traceTruncated: true` marker — truncation is never silent.\n *\n * @experimental\n */\n\nimport { buildLoopSpanNodes } from '../otel-export'\nimport type { LoopTraceEmitter, LoopTraceEvent } from '../runtime/types'\n\n/**\n * One span of a delegation's compact trace. Flat (parent linkage by id), all\n * values JSON-safe scalars — `FileDelegationStore` round-trips records\n * through `JSON.stringify`. `meta` carries the span's attributes (GenAI\n * semconv keys + `tangle.loop.*` extensions) exactly as the OTEL sink emits\n * them, so a consumer can re-export journal traces losslessly.\n *\n * @experimental\n */\nexport interface DelegationTraceSpan {\n spanId: string\n /** Absent on the tree root. */\n parentSpanId?: string\n /** `'loop'` | `'loop.round'` | `'loop.iteration'` (or a sink-specific name). */\n name: string\n /** Topology level: loop root, plan round, or iteration branch. */\n kind: 'loop' | 'round' | 'branch'\n startMs: number\n endMs: number\n meta?: Record<string, string | number | boolean>\n}\n\n/** Default cap on spans retained per delegation record. @experimental */\nconst DELEGATION_TRACE_MAX_SPANS = 512\n\n/** Default cap on the serialized trace payload per record, in bytes. @experimental */\nconst DELEGATION_TRACE_MAX_BYTES = 256 * 1024\n\n/** @experimental */\ninterface DelegationTraceCaps {\n /** Default {@link DELEGATION_TRACE_MAX_SPANS}. */\n maxSpans?: number\n /** Default {@link DELEGATION_TRACE_MAX_BYTES}. Approximate — measured as the\n * sum of per-span `JSON.stringify` lengths. */\n maxBytes?: number\n}\n\n/** @experimental */\ninterface CappedDelegationTrace {\n trace: DelegationTraceSpan[]\n /** True when oldest spans were dropped to honor the caps. */\n truncated: boolean\n}\n\n/**\n * Derive the compact span tree for ONE loop run from its buffered\n * `LoopTraceEvent` stream. Same reconstruction as the OTEL exporter\n * ({@link buildLoopSpanNodes}); tolerates partial streams.\n *\n * @experimental\n */\nexport function buildDelegationTraceSpans(\n events: ReadonlyArray<LoopTraceEvent>,\n): DelegationTraceSpan[] {\n return buildLoopSpanNodes(events).map((node) => ({\n spanId: node.spanId,\n ...(node.parentSpanId !== undefined ? { parentSpanId: node.parentSpanId } : {}),\n name: node.name,\n kind: node.kind,\n startMs: node.startMs,\n endMs: node.endMs,\n ...(Object.keys(node.attrs).length > 0 ? { meta: node.attrs } : {}),\n }))\n}\n\n/**\n * Enforce the trace caps over an ordered (oldest-first) span list. Drops the\n * OLDEST spans first and reports `truncated: true` when anything was dropped;\n * the newest span always survives, so a non-empty input never caps to empty.\n * Dropping a parent may orphan surviving children's `parentSpanId` references\n * — acceptable for the flat journal shape; consumers treat unresolved parents\n * as roots.\n *\n * @experimental\n */\nexport function capDelegationTrace(\n spans: ReadonlyArray<DelegationTraceSpan>,\n caps?: DelegationTraceCaps,\n): CappedDelegationTrace {\n const maxSpans = caps?.maxSpans ?? DELEGATION_TRACE_MAX_SPANS\n const maxBytes = caps?.maxBytes ?? DELEGATION_TRACE_MAX_BYTES\n let start = Math.max(0, spans.length - maxSpans)\n const sizes = spans.map((span) => JSON.stringify(span).length + 1)\n let total = 0\n for (let i = start; i < sizes.length; i += 1) total += sizes[i]!\n while (start < spans.length - 1 && total > maxBytes) {\n total -= sizes[start]!\n start += 1\n }\n return { trace: spans.slice(start), truncated: start > 0 }\n}\n\n/**\n * Per-delegation trace collector. Buffers `LoopTraceEvent`s per runId\n * (mirroring the OTEL emitter's buffering) and hands the derived compact\n * spans to `onSpans` when a run reaches `loop.ended`. `settle()` drains runs\n * that never ended — a hard-aborted loop still leaves its partial tree in the\n * journal, unlike the OTEL path which drops it.\n *\n * @experimental\n */\ninterface DelegationTraceCollector {\n emitter: LoopTraceEmitter\n /** Flush buffered events of runs that never reached `loop.ended`. */\n settle(): void\n}\n\n/** Build a `DelegationTraceCollector` that buffers loop-trace events and converts them to spans on settle. @experimental */\nexport function createDelegationTraceCollector(\n onSpans: (spans: DelegationTraceSpan[]) => void,\n): DelegationTraceCollector {\n const buffers = new Map<string, LoopTraceEvent[]>()\n const flush = (events: LoopTraceEvent[]): void => {\n const spans = buildDelegationTraceSpans(events)\n if (spans.length > 0) onSpans(spans)\n }\n return {\n emitter: {\n emit(event: LoopTraceEvent): void {\n const buf = buffers.get(event.runId)\n if (buf) buf.push(event)\n else buffers.set(event.runId, [event])\n if (event.kind === 'loop.ended') {\n const events = buffers.get(event.runId) ?? [event]\n buffers.delete(event.runId)\n flush(events)\n }\n },\n },\n settle(): void {\n for (const events of buffers.values()) flush(events)\n buffers.clear()\n },\n }\n}\n\n/**\n * 16-hex-char span id for journal spans synthesized outside the shared loop\n * builder (e.g. the queue's detached-resume segment).\n *\n * @experimental\n */\nexport function generateDelegationSpanId(): string {\n const bytes = new Uint8Array(8)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 8; i += 1) bytes[i] = Math.floor(Math.random() * 256)\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Fan one `LoopTraceEvent` stream into several emitters — e.g. the\n * process-wide OTEL exporter AND the per-delegation journal collector.\n * `undefined` entries are skipped; returns `undefined` when nothing is left\n * so callers keep the kernel's \"no emitter, no events\" fast path.\n *\n * @experimental\n */\nexport function composeLoopTraceEmitters(\n ...emitters: ReadonlyArray<LoopTraceEmitter | undefined>\n): LoopTraceEmitter | undefined {\n const live = emitters.filter((e): e is LoopTraceEmitter => e !== undefined)\n if (live.length === 0) return undefined\n if (live.length === 1) return live[0]\n return {\n emit(event: LoopTraceEvent): void | Promise<void> {\n const pending: Promise<void>[] = []\n for (const emitter of live) {\n const result = emitter.emit(event)\n if (result) pending.push(result)\n }\n if (pending.length > 0) return Promise.all(pending).then(() => undefined)\n },\n }\n}\n","/**\n *\n * Persistence port for the MCP delegation queue.\n *\n * `DelegationTaskQueue` keeps its working set in memory (status/history\n * reads stay synchronous) and journals every record mutation through a\n * `DelegationStore`. `DelegationTaskQueue.restore({ store })` is the load\n * path: it reads the full record set once at construction and rehydrates\n * the queue from it. After that the store only sees writes.\n *\n * Records MUST be JSON-safe — `FileDelegationStore` round-trips them\n * through `JSON.stringify`/`JSON.parse`, so a `Date`, `Map`, or function\n * smuggled into `args`/`result` would corrupt the journal.\n *\n * @stable\n */\n\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { AgentEvalError } from '../errors'\nimport { errorMessage } from '../runtime/util'\nimport type { DelegationRecord } from './task-queue'\n\n/** @stable */\nexport interface DelegationStore {\n /**\n * Read every persisted record. Called once, by\n * `DelegationTaskQueue.restore`, before any write. A missing backing\n * file is an empty store; an unparseable one throws\n * `DelegationStateCorruptError`.\n */\n loadAll(): Promise<DelegationRecord[]>\n /** Insert or replace the record keyed by `record.taskId`. */\n upsert(record: DelegationRecord): Promise<void>\n /**\n * Resolve an idempotency key to the taskId that claimed it, if any.\n * The queue serves submit-time dedupe from its rehydrated in-memory\n * index; this read exists for consumers that share a store across\n * processes without holding the full record set.\n */\n lookupIdempotencyKey(key: string): Promise<string | undefined>\n /** Delete the named records — the retention-cap eviction path. */\n remove(taskIds: readonly string[]): Promise<void>\n}\n\n/**\n * The persisted delegation state exists but cannot be parsed into\n * records. Fail loud: silently starting empty over a corrupt journal\n * would erase delegation history and re-run idempotent work. Opt into\n * recovery explicitly via `FileDelegationStoreOptions.recoverCorrupt`\n * (the bin maps `AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1` onto it),\n * which archives the corrupt file and starts fresh.\n *\n * @stable\n */\nexport class DelegationStateCorruptError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n\n/**\n * A delegation-store read or write failed (filesystem error, store\n * called before `loadAll`, ...). Once the queue observes one, it stops\n * accepting new submissions — accepting work it cannot journal would\n * silently demote durable mode to in-memory mode.\n *\n * @stable\n */\nexport class DelegationPersistenceError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('config', message, options)\n }\n}\n\n/** In-memory `DelegationStore` — suitable for single-process use and tests. @stable */\nexport class InMemoryDelegationStore implements DelegationStore {\n private readonly records = new Map<string, DelegationRecord>()\n\n async loadAll(): Promise<DelegationRecord[]> {\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.records.set(record.taskId, cloneRecord(record))\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n for (const taskId of taskIds) this.records.delete(taskId)\n }\n}\n\n/** @stable */\nexport interface FileDelegationStoreOptions {\n /** Absolute path of the JSON state file. Parent directories are created on first write. */\n filePath: string\n /**\n * When the state file exists but cannot be parsed, archive it to\n * `<filePath>.corrupt-<timestamp>` and start empty instead of\n * throwing `DelegationStateCorruptError`. Default false.\n */\n recoverCorrupt?: boolean\n}\n\ninterface PersistedDelegationState {\n version: 1\n records: DelegationRecord[]\n}\n\nconst STATE_FORMAT_VERSION = 1\n\n/**\n * JSON-file persistence for the delegation queue. Each write serializes\n * the full record set and lands it atomically (write to a sibling tmp\n * file, then `rename`), so readers never observe a torn file — a crash\n * mid-write leaves the previous snapshot intact. Writes are serialized\n * internally; concurrent `upsert`/`remove` calls cannot interleave.\n *\n * Built for the MCP server's scale (one stdio process, hundreds of\n * records): full-snapshot writes keep the format trivially inspectable\n * and corruption-detectable without a database dependency.\n *\n * @stable\n */\nexport class FileDelegationStore implements DelegationStore {\n private readonly filePath: string\n private readonly recoverCorrupt: boolean\n private readonly records = new Map<string, DelegationRecord>()\n private loaded = false\n private writeTail: Promise<void> = Promise.resolve()\n private tmpSeq = 0\n\n constructor(options: FileDelegationStoreOptions) {\n this.filePath = options.filePath\n this.recoverCorrupt = options.recoverCorrupt ?? false\n }\n\n async loadAll(): Promise<DelegationRecord[]> {\n let raw: string\n try {\n raw = await readFile(this.filePath, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n this.loaded = true\n return []\n }\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to read ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n let state: PersistedDelegationState\n try {\n state = parsePersistedState(raw)\n } catch (err) {\n if (!this.recoverCorrupt) {\n throw new DelegationStateCorruptError(\n `FileDelegationStore: state file ${this.filePath} is corrupt (${errorMessage(err)}). ` +\n 'Repair or archive the file, or opt into automatic recovery ' +\n '(recoverCorrupt / AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1) to archive it and start empty.',\n { cause: err },\n )\n }\n const archivePath = `${this.filePath}.corrupt-${Date.now()}`\n await rename(this.filePath, archivePath)\n this.loaded = true\n return []\n }\n this.records.clear()\n for (const record of state.records) this.records.set(record.taskId, record)\n this.loaded = true\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.assertLoaded('upsert')\n this.records.set(record.taskId, cloneRecord(record))\n await this.enqueueWrite()\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n this.assertLoaded('lookupIdempotencyKey')\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n this.assertLoaded('remove')\n let changed = false\n for (const taskId of taskIds) {\n if (this.records.delete(taskId)) changed = true\n }\n if (changed) await this.enqueueWrite()\n }\n\n private assertLoaded(op: string): void {\n if (this.loaded) return\n // Writing before load would snapshot only the new records and clobber\n // whatever the file already holds.\n throw new DelegationPersistenceError(\n `FileDelegationStore: ${op} called before loadAll() — the on-disk state has not been read yet`,\n )\n }\n\n private enqueueWrite(): Promise<void> {\n const write = this.writeTail.then(() => this.writeSnapshot())\n this.writeTail = write.catch(() => {})\n return write\n }\n\n private async writeSnapshot(): Promise<void> {\n const state: PersistedDelegationState = {\n version: STATE_FORMAT_VERSION,\n records: [...this.records.values()],\n }\n const payload = `${JSON.stringify(state)}\\n`\n this.tmpSeq += 1\n const tmpPath = `${this.filePath}.tmp-${process.pid}-${this.tmpSeq}`\n try {\n await mkdir(dirname(this.filePath), { recursive: true })\n await writeFile(tmpPath, payload, 'utf8')\n await rename(tmpPath, this.filePath)\n } catch (err) {\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to write ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n }\n}\n\nfunction parsePersistedState(raw: string): PersistedDelegationState {\n const parsed: unknown = JSON.parse(raw)\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('top-level value is not an object')\n }\n const state = parsed as Record<string, unknown>\n if (state.version !== STATE_FORMAT_VERSION) {\n throw new Error(`unsupported state version ${JSON.stringify(state.version)}`)\n }\n if (!Array.isArray(state.records)) {\n throw new Error('`records` is not an array')\n }\n for (const record of state.records) {\n if (record === null || typeof record !== 'object') {\n throw new Error('a record entry is not an object')\n }\n const candidate = record as Record<string, unknown>\n if (typeof candidate.taskId !== 'string' || typeof candidate.status !== 'string') {\n throw new Error('a record entry is missing `taskId`/`status`')\n }\n }\n return { version: STATE_FORMAT_VERSION, records: state.records as DelegationRecord[] }\n}\n\nfunction cloneRecord(record: DelegationRecord): DelegationRecord {\n return structuredClone(record)\n}\n","/**\n *\n * Feedback persistence surface for the MCP layer.\n *\n * Feedback storage is product policy, so the MCP layer depends on this narrow\n * interface instead of choosing a knowledge store. The default implementation\n * is in-memory; consumers wire their own durable adapter via\n * `createMcpServer({ feedbackStore })`.\n *\n * Feedback events are append-only: every rating is a new event with a\n * fresh id, even when the same delegation is rated multiple times. The\n * caller decides how to roll up scores downstream.\n *\n * @stable\n */\n\nimport type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types'\n\n/** @stable */\nexport interface FeedbackEvent {\n id: string\n refersTo: DelegateFeedbackArgs['refersTo']\n rating: DelegateFeedbackArgs['rating']\n by: DelegateFeedbackArgs['by']\n capturedAt: string\n namespace?: string\n}\n\n/** @stable */\nexport interface FeedbackStore {\n /** Append a new event. Never dedupes — every rating is its own event. */\n put(event: FeedbackEvent): Promise<void>\n /**\n * List events filtered by `namespace`. When `namespace` is omitted, list\n * across all namespaces. Returns events in insertion order.\n */\n list(filter?: { namespace?: string; refersToRef?: string }): Promise<FeedbackEvent[]>\n}\n\n/** In-memory `FeedbackStore` — suitable for single-process use and tests. @stable */\nexport class InMemoryFeedbackStore implements FeedbackStore {\n private readonly events: FeedbackEvent[] = []\n\n async put(event: FeedbackEvent): Promise<void> {\n this.events.push({ ...event })\n }\n\n async list(filter: { namespace?: string; refersToRef?: string } = {}): Promise<FeedbackEvent[]> {\n let out = this.events\n if (filter.namespace !== undefined) {\n out = out.filter((event) => event.namespace === filter.namespace)\n }\n if (filter.refersToRef !== undefined) {\n out = out.filter((event) => event.refersTo.ref === filter.refersToRef)\n }\n return out.map((event) => ({ ...event }))\n }\n}\n\n/**\n * Project a `FeedbackEvent` down to the snapshot shape carried on\n * `delegation_history` entries.\n *\n * @stable\n */\nexport function eventToSnapshot(event: FeedbackEvent): DelegationFeedbackSnapshot {\n const snap: DelegationFeedbackSnapshot = {\n id: event.id,\n score: event.rating.score,\n by: event.by,\n notes: event.rating.notes,\n capturedAt: event.capturedAt,\n }\n if (event.rating.label) snap.label = event.rating.label\n return snap\n}\n","/**\n *\n * State machine for async MCP delegations:\n *\n * pending → running → completed | failed\n * ↘ cancelled (from any non-terminal state via cancel())\n *\n * Each `submit` returns a `taskId` immediately and kicks the work off in the\n * background. The work function receives an `AbortSignal` the queue fires\n * when `cancel(taskId)` is called. The queue does NOT supervise runtime\n * timeouts — the underlying `runAgentRounds` driver / sandbox imposes those.\n *\n * Idempotency: callers may supply an `idempotencyKey` (hash of the input).\n * A duplicate `submit` with a known key returns the existing task instead of\n * starting a new one. Mutated input → different key → different task.\n *\n * Durability: the working set lives in memory (reads stay synchronous) and\n * every record mutation is journaled through a `DelegationStore`. The default\n * `InMemoryDelegationStore` keeps today's semantics — a process restart drops\n * all state. Construct via `DelegationTaskQueue.restore({ store })` with a\n * `FileDelegationStore` to reload prior records on startup: terminal records\n * stay queryable, in-flight records either re-attach through the\n * `resumeDelegate` seam (when they carry a `detachedSessionRef`) or fail\n * loud with a driver-restart error so `delegation_status` tells the truth.\n *\n * @stable\n */\n\nimport { ValidationError } from '../errors'\nimport type { LoopTraceEmitter } from '../runtime/types'\nimport { fnv1a32Hex } from '../runtime/util'\nimport {\n DelegationPersistenceError,\n type DelegationStore,\n InMemoryDelegationStore,\n} from './delegation-store'\nimport {\n capDelegationTrace,\n createDelegationTraceCollector,\n type DelegationTraceSpan,\n generateDelegationSpanId,\n} from './delegation-trace'\nimport type { TraceContext } from './trace-propagation'\nimport type {\n DelegateCodeArgs,\n DelegateResearchArgs,\n DelegateUiAuditArgs,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusResult,\n} from './types'\n\n/** Arguments accepted by the durable delegation queue. @stable */\nexport type DelegationArgs = DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs\n\n/**\n * Must be JSON-safe end to end (`args`, `result`, `error`, `feedback`) —\n * persistent stores round-trip records through `JSON.stringify`.\n *\n * @stable\n */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegationArgs\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Sha-prefix hash of the canonical input — used for idempotency lookup. */\n idempotencyKey?: string\n /**\n * Caller-generated deterministic id of a detached run (e.g. the sandbox\n * session id a single-tick driver resumes by). Presence is what makes a\n * restored in-flight record resumable via `resumeDelegate`; without it a\n * restart settles the record as failed.\n */\n detachedSessionRef?: string\n /** Feedback events keyed by this delegation's taskId. */\n feedback: DelegationFeedbackSnapshot[]\n /**\n * Compact loop-trace span tree teed from the delegation's run, oldest\n * spans first. Appended when a delegated loop reaches `loop.ended` and\n * settled (partial buffers included) at the terminal transition. Capped\n * via `capDelegationTrace` — see `traceTruncated`.\n */\n trace?: DelegationTraceSpan[]\n /** Present when oldest trace spans were dropped to honor the trace caps. */\n traceTruncated?: true\n /**\n * Inherited trace identity (the queue's `traceContext` at submit time —\n * typically `readTraceContextFromEnv()`), distinct from the span payload:\n * a journal consumer joins records into the parent trace by these ids\n * without parsing spans. Restored records keep their persisted identity.\n */\n traceId?: string\n /** Caller span that dispatched the delegation, when one was inherited. */\n parentSpanId?: string\n}\n\n/** @stable */\nexport interface SubmitInput<Args extends DelegationArgs> {\n profile: DelegationProfile\n args: Args\n namespace?: string\n idempotencyKey?: string\n /**\n * Records the detached-run resume key on the new record. The submitted\n * `run` function still executes in-process exactly as without it — the\n * ref only matters after a restart, when `DelegationTaskQueue.restore`\n * hands it to the `resumeDelegate` seam instead of failing the record.\n */\n detachedSessionRef?: string\n /**\n * Runs the underlying delegation. The queue passes a fresh `AbortSignal`\n * and a `report` channel for incremental progress updates. The function\n * MUST resolve with the typed `DelegationResultPayload['output']`; the\n * queue wraps it with the profile tag.\n */\n run: (ctx: DelegationRunContext) => Promise<DelegationResultPayload['output']>\n}\n\n/** @stable Context handed to a `SubmitInput.run` function. */\nexport interface DelegationRunContext {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** The `detachedSessionRef` recorded at submit, when one was supplied. */\n detachedSessionRef?: string\n /**\n * Replace the record's detached-run resume key — the detached dispatch path\n * calls this once the sandbox id is known so the persisted ref names a\n * resolvable box. Ignored after the record settles (a cancel racing the\n * rebind is legitimate; the ref no longer matters then). Throws on an empty\n * ref — erasing the resume key would silently make the record unresumable.\n */\n updateDetachedSessionRef(ref: string): void\n /**\n * Per-delegation loop-trace sink, always provided by the queue. Events\n * emitted here are journaled onto the record as a compact span tree\n * (`record.trace`) when each loop run ends and at the delegation's\n * terminal transition. Delegates forward it into their `runAgentRounds` ctx,\n * composed with any process-wide OTEL emitter\n * (`composeLoopTraceEmitters`). Optional in the type so consumer-built\n * contexts stay source-compatible.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @stable */\nexport interface SubmitOutput {\n taskId: string\n /** True when a prior matching `idempotencyKey` returned an existing record. */\n reused: boolean\n}\n\n/**\n * One observation of a detached run, mapped 1:1 from a single-tick driver\n * (e.g. the sandbox SDK's `driveTurn`, which reports\n * completed | running | failed per pass). `running` schedules another tick\n * after `intervalMs`; `completed` / `failed` settle the record.\n *\n * @stable\n */\nexport type DelegationResumeTick =\n | { state: 'running' }\n | { state: 'completed'; output: DelegationResultPayload['output']; costUsd?: number }\n | { state: 'failed'; error: DelegationError }\n\n/** @stable */\nexport interface DelegationResumeContext {\n /** Fired by `cancel(taskId)`; the driver should stop the remote run when it can. */\n signal: AbortSignal\n report(progress: DelegationProgress): void\n}\n\n/**\n * Re-attaches restored in-flight records to their detached runs. The queue\n * calls `tick` repeatedly — it never awaits a whole run — so the driver can\n * be a thin wrapper over a one-pass primitive: resolve the run named by\n * `detachedSessionRef`, advance/poll it once, report where it stands. A\n * thrown error settles the record as failed; `failed` ticks are treated as\n * terminal and are not retried.\n *\n * @stable\n */\nexport interface DelegationResumeDriver {\n tick(\n task: { record: DelegationRecord; detachedSessionRef: string },\n ctx: DelegationResumeContext,\n ): Promise<DelegationResumeTick>\n /** Delay between `running` ticks, in milliseconds. Default 5000. */\n intervalMs?: number\n}\n\n/** @stable */\nexport interface DelegationTaskQueueOptions {\n /** ID generator override; default `randomTaskId`. */\n generateId?: () => string\n /** Clock override; default `() => new Date().toISOString()`. */\n now?: () => string\n /**\n * Journal for record mutations and the `restore()` load source. Default\n * `InMemoryDelegationStore` — observably identical to an unjournaled\n * queue. Pass a `FileDelegationStore` through\n * `DelegationTaskQueue.restore` for state that survives a restart;\n * constructing with `new` never loads prior state.\n */\n store?: DelegationStore\n /** Resume seam for restored in-flight records that carry a `detachedSessionRef`. */\n resumeDelegate?: DelegationResumeDriver\n /**\n * Maximum number of terminal (completed | failed | cancelled) records\n * retained; the oldest (by `completedAt`) are evicted from memory and\n * store once the cap is exceeded. Default unbounded.\n */\n maxTerminalRecords?: number\n /**\n * Observes the first store failure. After it fires, the queue refuses\n * new submissions and `flush()` rejects with the same error. Default:\n * rethrow on a microtask — an unhandled crash — because silently\n * degrading durable mode to memory-only would lie to the caller.\n */\n onPersistError?: (error: DelegationPersistenceError) => void\n /**\n * Inherited trace identity stamped on every submitted record\n * (`traceId` / `parentSpanId`). The bin passes\n * `readTraceContextFromEnv()` so journal consumers can join delegation\n * records into the caller's trace. Restored records keep the identity\n * they were persisted with.\n */\n traceContext?: TraceContext\n}\n\n/** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @stable */\nexport class DelegationTaskQueue {\n private readonly records = new Map<string, DelegationRecord>()\n private readonly controllers = new Map<string, AbortController>()\n private readonly byIdempotencyKey = new Map<string, string>()\n private readonly generateId: () => string\n private readonly now: () => string\n private readonly store: DelegationStore\n private readonly resumeDelegate?: DelegationResumeDriver\n private readonly maxTerminalRecords: number\n private readonly onPersistError: (error: DelegationPersistenceError) => void\n private readonly traceContext: TraceContext | undefined\n private persistTail: Promise<void> = Promise.resolve()\n private persistFailure: DelegationPersistenceError | undefined\n\n constructor(options: DelegationTaskQueueOptions = {}) {\n this.generateId = options.generateId ?? randomTaskId\n this.now = options.now ?? (() => new Date().toISOString())\n this.store = options.store ?? new InMemoryDelegationStore()\n this.resumeDelegate = options.resumeDelegate\n if (options.maxTerminalRecords !== undefined) {\n if (!Number.isInteger(options.maxTerminalRecords) || options.maxTerminalRecords < 1) {\n throw new ValidationError(\n `DelegationTaskQueue: maxTerminalRecords must be a positive integer, got ${String(options.maxTerminalRecords)}`,\n )\n }\n }\n this.maxTerminalRecords = options.maxTerminalRecords ?? Number.POSITIVE_INFINITY\n this.traceContext = options.traceContext\n this.onPersistError =\n options.onPersistError ??\n ((error) => {\n queueMicrotask(() => {\n throw error\n })\n })\n }\n\n /**\n * Construct a queue from previously-persisted state. Loads every record\n * from `options.store`, rebuilds the idempotency index (so a re-submitted\n * identical task returns the prior taskId and its terminal state), then:\n *\n * - terminal records stay queryable via `status()` / `history()`\n * - in-flight records with a `detachedSessionRef` re-attach through\n * `options.resumeDelegate` and report `running`\n * - other in-flight records settle as failed — their driver died with\n * the previous process and the result is unrecoverable\n *\n * The retention cap applies to the loaded set as well.\n */\n static async restore(options: DelegationTaskQueueOptions = {}): Promise<DelegationTaskQueue> {\n const queue = new DelegationTaskQueue(options)\n const loaded = await queue.store.loadAll()\n await queue.rehydrate(loaded)\n return queue\n }\n\n /**\n * Kick off a delegation in the background. Returns immediately. The\n * `taskId` is queryable via `status` once this method returns. Throws\n * the recorded `DelegationPersistenceError` once the store has failed —\n * the queue does not accept work it cannot journal.\n */\n submit<Args extends DelegationArgs>(input: SubmitInput<Args>): SubmitOutput {\n if (this.persistFailure) throw this.persistFailure\n if (input.idempotencyKey) {\n const existing = this.byIdempotencyKey.get(input.idempotencyKey)\n if (existing && this.records.has(existing)) {\n return { taskId: existing, reused: true }\n }\n }\n const taskId = this.generateId()\n const controller = new AbortController()\n const record: DelegationRecord = {\n taskId,\n profile: input.profile,\n namespace: input.namespace,\n args: input.args,\n status: 'pending',\n startedAt: this.now(),\n feedback: [],\n idempotencyKey: input.idempotencyKey,\n detachedSessionRef: input.detachedSessionRef,\n ...(this.traceContext !== undefined\n ? {\n traceId: this.traceContext.traceId,\n ...(this.traceContext.parentSpanId !== undefined\n ? { parentSpanId: this.traceContext.parentSpanId }\n : {}),\n }\n : {}),\n }\n this.records.set(taskId, record)\n this.controllers.set(taskId, controller)\n if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId)\n this.persist(record)\n\n // Fire-and-forget the run function. Errors flow into the record so the\n // status poll surfaces them; the promise itself is intentionally\n // unobserved by the queue.\n queueMicrotask(() => {\n this.execute(taskId, input, controller)\n })\n\n return { taskId, reused: false }\n }\n\n /**\n * Snapshot the current state of a delegation. Returns `undefined` for\n * unknown ids so callers can distinguish missing from terminal.\n * `includeTrace` attaches the journaled loop-trace span tree — off by\n * default so status polls stay light.\n */\n status(taskId: string, opts?: { includeTrace?: boolean }): DelegationStatusResult | undefined {\n const record = this.records.get(taskId)\n if (!record) return undefined\n return toStatusResult(record, opts)\n }\n\n /**\n * Abort an in-flight delegation. Returns `false` if the task is unknown\n * or already terminal. The underlying `run` function MUST honor the\n * abort signal for the cancel to take effect; the queue marks the\n * record `cancelled` regardless so a misbehaving runner cannot pin the\n * UI on `running` forever.\n */\n cancel(taskId: string): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n if (isTerminal(record.status)) return false\n const controller = this.controllers.get(taskId)\n controller?.abort()\n record.status = 'cancelled'\n record.completedAt = this.now()\n record.error = { message: 'cancelled by caller', kind: 'CancelledError' }\n this.persist(record)\n this.enforceRetention()\n return true\n }\n\n /**\n * Append a feedback event to the matching delegation. Returns `false`\n * when `ref` does not name a known taskId — the caller should still\n * record the feedback through a different surface (artifact/outcome\n * kinds are not queue-bound).\n */\n attachFeedback(taskId: string, snapshot: DelegationFeedbackSnapshot): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n record.feedback.push(snapshot)\n this.persist(record)\n return true\n }\n\n /**\n * Query the recorded delegations. Returns entries newest-first (by\n * `startedAt`), truncated to `limit`.\n */\n history(args: DelegationHistoryArgs = {}): DelegationHistoryEntry[] {\n const limit = clampLimit(args.limit)\n const since = args.since ? Date.parse(args.since) : Number.NEGATIVE_INFINITY\n const out: DelegationHistoryEntry[] = []\n for (const record of this.records.values()) {\n if (args.namespace && record.namespace !== args.namespace) continue\n if (args.profile && record.profile !== args.profile) continue\n if (Number.isFinite(since) && Date.parse(record.startedAt) < since) continue\n out.push(toHistoryEntry(record))\n }\n out.sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n return out.slice(0, limit)\n }\n\n /**\n * Await every journal write issued so far. Rejects with the recorded\n * `DelegationPersistenceError` when any of them failed. Call before\n * handing the store's backing file to another process.\n */\n async flush(): Promise<void> {\n // Drain to quiescence: a write that completes while we await the tail can\n // chain another (the resume loop persisting a settle, a late `report`,\n // retention removals). Awaiting a single snapshot of `persistTail` would\n // miss those follow-on writes, letting a `store.upsert` land after the\n // caller has torn the backing dir down. Re-await until the tail stops\n // advancing.\n let tail: typeof this.persistTail | undefined\n while (this.persistTail !== tail) {\n tail = this.persistTail\n await tail\n }\n if (this.persistFailure) throw this.persistFailure\n }\n\n /** Test-only — number of in-flight (non-terminal) records. */\n inflightCount(): number {\n let n = 0\n for (const record of this.records.values()) {\n if (!isTerminal(record.status)) n += 1\n }\n return n\n }\n\n private async execute<Args extends DelegationArgs>(\n taskId: string,\n input: SubmitInput<Args>,\n controller: AbortController,\n ): Promise<void> {\n const record = this.records.get(taskId)\n if (!record) return\n record.status = 'running'\n this.persist(record)\n // Journal tee: each finished loop run inside the delegation appends its\n // compact span tree to the record immediately (a long delegation's trace\n // is durable before the terminal transition); `settle()` below drains\n // partial buffers from runs that never reached `loop.ended`.\n const traceCollector = createDelegationTraceCollector((spans) => {\n if (isTerminal(currentStatus(record))) return\n this.appendTrace(record, spans)\n this.persist(record)\n })\n try {\n const output = await input.run({\n signal: controller.signal,\n report: (progress) => {\n if (record.status === 'running') {\n record.progress = progress\n this.persist(record)\n }\n },\n traceEmitter: traceCollector.emitter,\n ...(record.detachedSessionRef !== undefined\n ? { detachedSessionRef: record.detachedSessionRef }\n : {}),\n updateDetachedSessionRef: (ref) => {\n if (typeof ref !== 'string' || ref.length === 0) {\n throw new ValidationError(\n 'DelegationTaskQueue: updateDetachedSessionRef requires a non-empty ref',\n )\n }\n if (isTerminal(currentStatus(record))) return\n record.detachedSessionRef = ref\n this.persist(record)\n },\n })\n traceCollector.settle()\n // `cancel()` may have flipped the status to `cancelled` while the\n // run promise was pending. Read the field through a widening\n // helper so the narrowed `'running'` type from the assignment\n // above does not exclude that case at compile time.\n if (currentStatus(record) === 'cancelled') return\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = { profile: input.profile, output } as DelegationResultPayload\n this.persist(record)\n this.enforceRetention()\n } catch (err) {\n traceCollector.settle()\n if (currentStatus(record) === 'cancelled') return\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(taskId)\n }\n }\n\n private appendTrace(record: DelegationRecord, spans: DelegationTraceSpan[]): void {\n if (spans.length === 0) return\n const { trace, truncated } = capDelegationTrace([...(record.trace ?? []), ...spans])\n record.trace = trace\n if (truncated) record.traceTruncated = true\n }\n\n private async rehydrate(loaded: DelegationRecord[]): Promise<void> {\n const records = [...loaded].sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n for (const record of records) {\n this.records.set(record.taskId, record)\n if (record.idempotencyKey) this.byIdempotencyKey.set(record.idempotencyKey, record.taskId)\n }\n const restoreWrites: Promise<void>[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) continue\n if (record.detachedSessionRef && this.resumeDelegate) {\n record.status = 'running'\n restoreWrites.push(this.persist(record))\n this.startResume(record, record.detachedSessionRef, this.resumeDelegate)\n continue\n }\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = {\n message: record.detachedSessionRef\n ? `delegation driver restarted while the task was in flight; detached session \"${record.detachedSessionRef}\" needs a resumeDelegate to be resumed`\n : 'delegation driver restarted while the task was in flight; the run was not detached and cannot be resumed',\n kind: 'DriverRestartError',\n }\n restoreWrites.push(this.persist(record))\n }\n const retentionWrite = this.enforceRetention()\n if (retentionWrite) restoreWrites.push(retentionWrite)\n await Promise.all(restoreWrites)\n if (this.persistFailure) throw this.persistFailure\n }\n\n private startResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n ): void {\n const controller = new AbortController()\n this.controllers.set(record.taskId, controller)\n void this.driveResume(record, detachedSessionRef, driver, controller)\n }\n\n private async driveResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n controller: AbortController,\n ): Promise<void> {\n const intervalMs = driver.intervalMs ?? 5000\n const resumeStartMs = Date.parse(this.now())\n const ctx: DelegationResumeContext = {\n signal: controller.signal,\n report: (progress) => {\n if (currentStatus(record) !== 'running') return\n record.progress = progress\n this.persist(record)\n },\n }\n try {\n while (!controller.signal.aborted && currentStatus(record) === 'running') {\n const tick = await driver.tick({ record: structuredClone(record), detachedSessionRef }, ctx)\n if (currentStatus(record) === 'cancelled') return\n if (tick.state === 'completed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs)\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = {\n profile: record.profile,\n output: tick.output,\n } as DelegationResultPayload\n if (tick.costUsd !== undefined) record.costUsd = tick.costUsd\n this.persist(record)\n this.enforceRetention()\n return\n }\n if (tick.state === 'failed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, tick.error.message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = tick.error\n this.persist(record)\n this.enforceRetention()\n return\n }\n await abortableDelay(intervalMs, controller.signal)\n }\n } catch (err) {\n if (currentStatus(record) === 'cancelled') return\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, errorToShape(err).message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(record.taskId)\n }\n }\n\n /**\n * Journal the resumed segment of a detached run as one compact span. The\n * resume driver re-attaches after a process restart, so the original\n * process's loop events are gone — this span records the post-restart\n * observation window (re-attach → terminal tick) under the\n * `'detached-resume'` driver tag, keeping restored delegations observable\n * in the journal alongside trace-carrying live runs.\n */\n private appendResumeSpan(\n record: DelegationRecord,\n detachedSessionRef: string,\n startMs: number,\n error?: string,\n ): void {\n this.appendTrace(record, [\n {\n spanId: generateDelegationSpanId(),\n name: 'loop',\n kind: 'loop',\n startMs,\n endMs: Date.parse(this.now()),\n meta: {\n 'tangle.loop.driver': 'detached-resume',\n 'tangle.loop.detached_session_ref': detachedSessionRef,\n ...(error !== undefined ? { 'tangle.loop.error': error } : {}),\n },\n },\n ])\n }\n\n private persist(record: DelegationRecord): Promise<void> {\n if (this.persistFailure) return Promise.resolve()\n const snapshot = structuredClone(record)\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.upsert(snapshot)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private persistRemoval(taskIds: string[]): Promise<void> | undefined {\n if (this.persistFailure || taskIds.length === 0) return undefined\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.remove(taskIds)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private failPersistence(cause: unknown): void {\n if (this.persistFailure) return\n const error =\n cause instanceof DelegationPersistenceError\n ? cause\n : new DelegationPersistenceError(\n `DelegationTaskQueue: store write failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n this.persistFailure = error\n this.onPersistError(error)\n }\n\n private enforceRetention(): Promise<void> | undefined {\n if (!Number.isFinite(this.maxTerminalRecords)) return undefined\n const terminal: DelegationRecord[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) terminal.push(record)\n }\n const excess = terminal.length - this.maxTerminalRecords\n if (excess <= 0) return undefined\n terminal.sort((a, b) =>\n (a.completedAt ?? a.startedAt).localeCompare(b.completedAt ?? b.startedAt),\n )\n const evicted = terminal.slice(0, excess)\n for (const record of evicted) {\n this.records.delete(record.taskId)\n if (\n record.idempotencyKey &&\n this.byIdempotencyKey.get(record.idempotencyKey) === record.taskId\n ) {\n this.byIdempotencyKey.delete(record.idempotencyKey)\n }\n }\n return this.persistRemoval(evicted.map((record) => record.taskId))\n }\n}\n\nfunction isTerminal(status: DelegationStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled'\n}\n\nfunction currentStatus(record: DelegationRecord): DelegationStatus {\n return record.status\n}\n\nfunction clampLimit(raw: number | undefined): number {\n if (!Number.isFinite(raw)) return 50\n const n = Math.trunc(raw as number)\n if (n <= 0) return 50\n return Math.min(n, 500)\n}\n\nfunction abortableDelay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) {\n resolve()\n return\n }\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nfunction toStatusResult(\n record: DelegationRecord,\n opts?: { includeTrace?: boolean },\n): DelegationStatusResult {\n const out: DelegationStatusResult = {\n taskId: record.taskId,\n profile: record.profile,\n status: record.status,\n startedAt: record.startedAt,\n }\n if (record.progress) out.progress = record.progress\n if (record.result) out.result = record.result\n if (record.error) out.error = record.error\n if (record.costUsd !== undefined) out.costUsd = record.costUsd\n if (record.completedAt) out.completedAt = record.completedAt\n if (record.traceId !== undefined) out.traceId = record.traceId\n if (record.parentSpanId !== undefined) out.parentSpanId = record.parentSpanId\n if (opts?.includeTrace === true && record.trace && record.trace.length > 0) {\n out.trace = record.trace.map((span) => ({ ...span }))\n if (record.traceTruncated) out.traceTruncated = true\n }\n return out\n}\n\nfunction toHistoryEntry(record: DelegationRecord): DelegationHistoryEntry {\n const entry: DelegationHistoryEntry = {\n taskId: record.taskId,\n profile: record.profile,\n args: record.args,\n status: record.status,\n startedAt: record.startedAt,\n hasTrace: record.trace !== undefined && record.trace.length > 0,\n }\n if (record.namespace) entry.namespace = record.namespace\n if (record.completedAt) entry.completedAt = record.completedAt\n if (record.costUsd !== undefined) entry.costUsd = record.costUsd\n if (record.feedback.length > 0) entry.feedback = [...record.feedback]\n if (record.traceId !== undefined) entry.traceId = record.traceId\n return entry\n}\n\nfunction errorToShape(err: unknown): DelegationError {\n if (err instanceof Error) {\n return { message: err.message, kind: err.name || 'Error' }\n }\n return { message: String(err), kind: 'NonError' }\n}\n\nfunction randomTaskId(): string {\n // Caller-stable id: `dlg-${timestamp}-${random}`. The timestamp portion\n // makes lexicographic sort match chronological order in history queries\n // even when the system clock skews under the second.\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `dlg-${t}-${r}`\n}\n\n/**\n * Best-effort stable hash for use as `idempotencyKey`. Not cryptographic;\n * collisions only affect dedupe, never correctness.\n *\n * @stable\n */\nexport function hashIdempotencyInput(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(canonicalize(value))\n } catch {\n str = String(value)\n }\n return fnv1a32Hex(str)\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n const out: Record<string, unknown> = {}\n for (const [k, v] of entries) out[k] = canonicalize(v)\n return out\n}\n\n// Re-exports re-used by the feedback-store + handler glue. Kept local so\n// consumers of the queue don't have to import from `./types` separately.\nexport type {\n DelegateUiAuditArgs,\n DelegateUiAuditResult,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\n} from './types'\n","/**\n *\n * `delegate` MCP tool — the ONE generic delegation verb, the agent-facing front door to\n * `delegate()` / `supervise()`. The agent hands it an INTENT (what it wants done); a default\n * authoring supervisor decomposes the intent and AUTHORS the worker profile it needs — there is no\n * hardcoded coder/researcher profile, so one verb covers code, research, and anything else.\n *\n * `delegate` is SYNCHRONOUS: it awaits the full supervised run and returns the delivered output\n * TOGETHER WITH `spentTotal` — the conserved cost of the whole delegation (`iterations` / `tokens` /\n * `usd` / `ms`), so the caller always learns what the delegation actually spent.\n *\n * The supervisor's substrate (its brain `router`, the worker `backend`, the completion `deliverable`)\n * is INJECTED at server construction — never an agent-supplied arg. The agent supplies only the\n * intent (+ an optional per-call `model` / `runId`).\n *\n * @stable\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { RouterTransportConfig } from '../../runtime/router-http-transport'\nimport type { DeliverableSpec } from '../../runtime/supervise/completion-gate'\nimport { type DelegateOptions, delegate } from '../../runtime/supervise/delegate'\nimport type { ExecutorConfig } from '../../runtime/supervise/runtime'\nimport type { Spend, SupervisedResult } from '../../runtime/supervise/types'\n\n/** MCP tool name for the `delegate` generic-delegation tool. @stable */\nexport const DELEGATE_TOOL_NAME = 'delegate'\n\n/** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATE_DESCRIPTION = [\n 'Delegate an INTENT to a supervisor that AUTHORS and drives whatever worker the intent needs.',\n '',\n 'Use when: you want a task done but do not want to specify HOW. State the outcome — \"fix the',\n 'failing auth test\", \"research competitor pricing with citations\", \"refactor the parser for',\n 'clarity\" — and the supervisor decomposes it, writes a tailored worker profile per sub-task, runs',\n 'the workers over a conserved compute budget, and settles only when a deployable check passes.',\n '',\n 'There is no fixed worker type: this ONE verb replaces separate code / research delegation. The',\n 'supervisor picks the worker shape from your intent.',\n '',\n 'Returns synchronously with the delivered result AND the real cost of the whole delegation',\n '(spentTotal: iterations, input/output tokens, usd, ms) — so you always know what it spent. A run',\n 'that produced no delivered worker returns status \"no-winner\" with the reason; it never fabricates',\n 'a success.',\n].join('\\n')\n\n/** JSON Schema for `delegate` tool arguments (`intent` + optional trace id). @stable */\nexport const DELEGATE_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n intent: {\n type: 'string',\n description: 'What you want accomplished, as an outcome. The supervisor authors the worker.',\n },\n runId: {\n type: 'string',\n description: 'Optional trace-correlation id for this delegation.',\n },\n },\n required: ['intent'],\n additionalProperties: false,\n} as const\n\n/** Parsed `delegate` tool arguments. */\ninterface DelegateArgs {\n intent: string\n runId?: string\n}\n\n/** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @stable */\nfunction validateDelegateArgs(raw: unknown): DelegateArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const unknown = Object.keys(value).filter((key) => key !== 'intent' && key !== 'runId')\n if (unknown.length > 0) {\n throw new TypeError(`delegate: unknown arguments: ${unknown.join(', ')}`)\n }\n const intent = value.intent\n if (typeof intent !== 'string' || intent.trim().length === 0) {\n throw new TypeError('delegate: `intent` must be a non-empty string')\n }\n const args: DelegateArgs = { intent: intent.trim() }\n if (value.runId !== undefined) {\n if (typeof value.runId !== 'string') throw new TypeError('delegate: `runId` must be a string')\n args.runId = value.runId\n }\n return args\n}\n\n/** The synchronous result the `delegate` tool returns to the calling agent: the delivered output (or\n * the no-winner reason) PLUS the conserved spend of the whole delegation. */\nexport type DelegateResult =\n | { status: 'winner'; out: unknown; outRef: string; spentTotal: Spend }\n | { status: 'no-winner'; reason: string; error?: DelegateError; spentTotal: Spend }\n\n/** What killed a delegation, projected for the calling agent: the rejection's name and message.\n * `reason` is a four-word code (`driver-failed`), and a code alone is not diagnosable — the\n * supervisor attaches the rejection to the result precisely so a caller can read it. */\nexport interface DelegateError {\n name: string\n message: string\n}\n\n/** @stable */\nexport interface DelegateHandlerOptions {\n /** The supervisor brain's router substrate (REQUIRED — the default supervisor is router-brained). */\n router: RouterTransportConfig\n /** Exact executable supervisor identity selected by the trusted composition root. */\n supervisorProfile: AgentProfile\n /** WHERE the authored workers run. Required for `supervise()` to spawn anything. */\n backend: ExecutorConfig\n /** The completion oracle the authored workers settle against (settled ⟺ delivered). */\n deliverable?: DeliverableSpec\n /** Restrict the run to this subset of models. */\n allowedModels?: readonly string[]\n}\n\n/** Project a `SupervisedResult` onto the tool's flat `DelegateResult`. Both variants carry the real\n * conserved `spentTotal`, so the agent always learns the cost — even on a no-winner, never a faked\n * output and never a fabricated zero spend. */\nfunction toDelegateResult(result: SupervisedResult<unknown>): DelegateResult {\n if (result.kind === 'no-winner') {\n // `stack` stays behind: an agent reads a cause, not a frame list.\n const rejection = (result as { error?: { name?: unknown; message?: unknown } }).error\n const error: DelegateError | undefined =\n typeof rejection?.name === 'string' && typeof rejection.message === 'string'\n ? { name: rejection.name, message: rejection.message }\n : undefined\n return {\n status: 'no-winner',\n reason: result.reason,\n ...(error ? { error } : {}),\n spentTotal: result.spentTotal,\n }\n }\n return {\n status: 'winner',\n out: result.out,\n outRef: result.outRef,\n spentTotal: result.spentTotal,\n }\n}\n\n/**\n * Build the `delegate` tool handler. Closes over the injected supervisor substrate (`router` /\n * `backend` / `deliverable`); each call routes the agent's intent to `delegate()` and returns the\n * delivered output with its conserved cost.\n */\nexport function createDelegateHandler(\n options: DelegateHandlerOptions,\n): (raw: unknown) => Promise<DelegateResult> {\n return async (raw) => {\n const args = validateDelegateArgs(raw)\n const opts: DelegateOptions = {\n backend: options.backend,\n router: options.router,\n supervisorProfile: options.supervisorProfile,\n ...(options.deliverable ? { deliverable: options.deliverable } : {}),\n ...(options.allowedModels ? { allowedModels: options.allowedModels } : {}),\n ...(args.runId ? { runId: args.runId } : {}),\n }\n const result = await delegate(args.intent, opts)\n return toDelegateResult(result)\n }\n}\n","/**\n *\n * `delegate_feedback` MCP tool — synchronous record of agent / user /\n * downstream-judge feedback on a delegation, artifact, or outcome.\n *\n * The store is append-only. Every rating is its own event; no dedupe.\n * When `refersTo.kind === 'delegation'`, the snapshot is also attached\n * to the matching queue record so `delegation_history` surfaces it\n * inline without a join.\n *\n * @stable\n */\n\nimport type { FeedbackStore } from '../feedback-store'\nimport { eventToSnapshot } from '../feedback-store'\nimport type { DelegationTaskQueue } from '../task-queue'\nimport type {\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n FeedbackRating,\n FeedbackRefersTo,\n} from '../types'\n\n/** MCP tool name for the `delegate_feedback` feedback-recording tool. @stable */\nexport const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback'\n\n/** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATE_FEEDBACK_DESCRIPTION = [\n 'Record feedback on a delegation, artifact, or outcome. Synchronous — the',\n 'event is durably stored when this call returns.',\n '',\n 'Use when: you (the agent), the user, or a downstream judge has formed an',\n 'opinion about a piece of work and want it persisted for calibration,',\n 'pricing, or future routing. Every call is a new event — multiple ratings',\n 'on the same target are expected and never deduped.',\n '',\n '`refersTo.kind`:',\n ' - \"delegation\": ref is a taskId returned by delegate_ui_audit',\n ' - \"artifact\": ref is a URI/path/git-sha — anything you can dereference',\n ' - \"outcome\": ref is a free-form description of a downstream result',\n '',\n '`by`:',\n ' - \"agent\": the agent itself rated the work',\n ' - \"user\": the human user rated it',\n ' - \"downstream-judge\": an automated evaluator emitted the rating',\n '',\n 'When ref names a known taskId, the rating is also attached to the',\n 'delegation record so delegation_history surfaces it inline.',\n].join('\\n')\n\n/** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @stable */\nexport const DELEGATE_FEEDBACK_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n refersTo: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['delegation', 'artifact', 'outcome'] },\n ref: { type: 'string' },\n },\n required: ['kind', 'ref'],\n additionalProperties: false,\n },\n rating: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n label: { type: 'string', enum: ['good', 'bad', 'neutral', 'mixed'] },\n notes: { type: 'string' },\n },\n required: ['score', 'notes'],\n additionalProperties: false,\n },\n by: { type: 'string', enum: ['agent', 'user', 'downstream-judge'] },\n capturedAt: { type: 'string' },\n namespace: { type: 'string' },\n },\n required: ['refersTo', 'rating', 'by'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegateFeedbackArgs(raw: unknown): DelegateFeedbackArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const refersTo = validateRefersTo(value.refersTo)\n const rating = validateRating(value.rating)\n const by = value.by\n if (by !== 'agent' && by !== 'user' && by !== 'downstream-judge') {\n throw new TypeError(\n 'delegate_feedback: `by` must be one of \"agent\" | \"user\" | \"downstream-judge\"',\n )\n }\n const args: DelegateFeedbackArgs = { refersTo, rating, by }\n if (value.capturedAt !== undefined) {\n if (typeof value.capturedAt !== 'string' || Number.isNaN(Date.parse(value.capturedAt))) {\n throw new TypeError('delegate_feedback: `capturedAt` must be an ISO datetime')\n }\n args.capturedAt = value.capturedAt\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateRefersTo(raw: unknown): FeedbackRefersTo {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `refersTo` must be an object')\n }\n const value = raw as Record<string, unknown>\n const kind = value.kind\n if (kind !== 'delegation' && kind !== 'artifact' && kind !== 'outcome') {\n throw new TypeError(\n 'delegate_feedback: `refersTo.kind` must be one of \"delegation\" | \"artifact\" | \"outcome\"',\n )\n }\n const ref = value.ref\n if (typeof ref !== 'string' || ref.trim().length === 0) {\n throw new TypeError('delegate_feedback: `refersTo.ref` must be a non-empty string')\n }\n return { kind, ref: ref.trim() }\n}\n\nfunction validateRating(raw: unknown): FeedbackRating {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `rating` must be an object')\n }\n const value = raw as Record<string, unknown>\n const score = Number(value.score)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new RangeError('delegate_feedback: `rating.score` must be a number in [0, 1]')\n }\n const notes = value.notes\n if (typeof notes !== 'string') {\n throw new TypeError('delegate_feedback: `rating.notes` must be a string')\n }\n const rating: FeedbackRating = { score, notes }\n const label = value.label\n if (label !== undefined) {\n if (label !== 'good' && label !== 'bad' && label !== 'neutral' && label !== 'mixed') {\n throw new TypeError(\n 'delegate_feedback: `rating.label` must be one of \"good\" | \"bad\" | \"neutral\" | \"mixed\"',\n )\n }\n rating.label = label\n }\n return rating\n}\n\n/** @stable */\ninterface DelegateFeedbackHandlerOptions {\n queue: DelegationTaskQueue\n store: FeedbackStore\n generateId?: () => string\n now?: () => string\n}\n\n/** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @stable */\nexport function createDelegateFeedbackHandler(\n options: DelegateFeedbackHandlerOptions,\n): (raw: unknown) => Promise<DelegateFeedbackResult> {\n const generateId = options.generateId ?? randomFeedbackId\n const now = options.now ?? (() => new Date().toISOString())\n return async (raw) => {\n const args = validateDelegateFeedbackArgs(raw)\n const id = generateId()\n const event = {\n id,\n refersTo: args.refersTo,\n rating: args.rating,\n by: args.by,\n capturedAt: args.capturedAt ?? now(),\n namespace: args.namespace,\n }\n await options.store.put(event)\n if (args.refersTo.kind === 'delegation') {\n options.queue.attachFeedback(args.refersTo.ref, eventToSnapshot(event))\n }\n return { recorded: true, id }\n }\n}\n\nfunction randomFeedbackId(): string {\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `fbk-${t}-${r}`\n}\n","/**\n *\n * `delegate_ui_audit` MCP tool — async kickoff for UI audit runs. Validates\n * the input, computes an idempotency key over the canonical fields, hands\n * the task to the queue, and returns a taskId. Identical inputs return\n * the same taskId.\n *\n * The handler does not import the auditor profile directly — consumers\n * inject a `UiAuditorDelegate` via `createMcpServer({ uiAuditorDelegate })`.\n * The delegate is the seam where the consumer chooses the judge (vision\n * model) and the `SandboxClient` (in-process Playwright vs fleet vs\n * remote browser). agent-runtime ships the in-process client under\n * `./profiles` so consumers who want the canonical setup can wire it\n * with a few lines.\n *\n * @experimental\n */\n\nimport path from 'node:path'\nimport { UI_LENSES, type UiLens } from '../../profiles/ui-auditor/substrate'\nimport type { UiAuditorDelegate } from '../delegates'\nimport {\n type DelegateUiAuditArgs,\n type DelegateUiAuditResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\n\n/** MCP tool name for the `delegate_ui_audit` async kickoff tool. @experimental */\nexport const DELEGATE_UI_AUDIT_TOOL_NAME = 'delegate_ui_audit'\n\n/** Human-readable description of the `delegate_ui_audit` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATE_UI_AUDIT_DESCRIPTION = [\n 'Delegate a UI/UX audit to a vision-driven auditor that produces self-contained',\n 'GitHub-issue-ready Markdown findings — one file per finding, with embedded',\n 'screenshot evidence and a suggested fix.',\n '',\n 'Use when: you want a thorough pass over a running web app for consistency,',\n 'hierarchy, layout, ux-flow, duplication, accessibility, responsive, states,',\n 'content, interaction, or perceived-performance issues. The auditor iterates',\n 'lens-by-lens so each pass finds new classes of issues; the workspace registry',\n 'deduplicates across iterations.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'workspace path + indexed findings (typically minutes per audited route).',\n 'Identical inputs return the same taskId — safe to retry.',\n '',\n 'Output layout under workspaceDir:',\n ' registry.json — finding index + capture sidecar',\n ' index.md — human-readable rollup',\n ' issues/NNN--<lens>--<slug>.md — one self-contained GitHub-issue',\n ' screenshots/<route>--<viewport>.png — capture archive',\n '',\n 'Multi-tenant isolation: every finding is scoped to `namespace` when set.',\n \"Never pass another tenant's namespace.\",\n].join('\\n')\n\nconst VIEWPORT_SCHEMA = {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1 },\n height: { type: 'integer', minimum: 1 },\n },\n required: ['width', 'height'],\n additionalProperties: false,\n} as const\n\nconst ROUTE_SCHEMA = {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Stable route name (used in screenshot filenames).' },\n url: { type: 'string', description: 'Fully-qualified URL.' },\n viewports: {\n type: 'array',\n items: VIEWPORT_SCHEMA,\n description: 'Viewports to capture at. Default [{1280, 800}].',\n },\n fullPage: { type: 'boolean' },\n waitFor: { type: 'string', description: 'CSS selector to wait for before capturing.' },\n },\n required: ['name', 'url'],\n additionalProperties: false,\n} as const\n\n/** JSON Schema for `delegate_ui_audit` tool arguments (`workspaceDir`, `routes`, optional config). @experimental */\nexport const DELEGATE_UI_AUDIT_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n workspaceDir: { type: 'string', description: 'Absolute path for the audit workspace.' },\n routes: { type: 'array', items: ROUTE_SCHEMA, minItems: 1 },\n namespace: { type: 'string', description: 'Multi-tenant scope.' },\n config: {\n type: 'object',\n properties: {\n lenses: {\n type: 'array',\n items: { type: 'string', enum: [...UI_LENSES] },\n description: 'Lenses to iterate. Default: every lens except \"other\".',\n },\n maxIterations: { type: 'integer', minimum: 1 },\n maxConcurrency: { type: 'integer', minimum: 1 },\n productContext: { type: 'string' },\n },\n additionalProperties: false,\n },\n },\n required: ['workspaceDir', 'routes'],\n additionalProperties: false,\n} as const\n\nconst PER_LENS_PER_ROUTE_ESTIMATE_MS = 45_000\n\n/** Parse and validate raw MCP tool input into typed `DelegateUiAuditArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegateUiAuditArgs(raw: unknown): DelegateUiAuditArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const workspaceDir = value.workspaceDir\n if (typeof workspaceDir !== 'string' || workspaceDir.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `workspaceDir` must be a non-empty string')\n }\n // Reject relative paths at the boundary. Without this, the writer joins a\n // relative workspaceDir against the process CWD, so the same MCP call\n // produces different file layouts depending on where the server was\n // launched — a silent fail-loud violation for a public API.\n const trimmedWs = workspaceDir.trim()\n if (!path.isAbsolute(trimmedWs)) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must be an absolute path (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n // Reject `..` segments. An absolute path like `/tmp/../../etc` passes\n // `isAbsolute`, then `path.join(workspaceDir, 'issues', …)` normalises it\n // to `/etc/issues/…`, escaping the intended workspace. Check the RAW\n // input split on the platform separator; `path.resolve` already collapses\n // `..` and would silently launder a traversal attempt past us.\n if (trimmedWs.split(path.sep).includes('..')) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must not contain '..' segments (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n const routesRaw = value.routes\n if (!Array.isArray(routesRaw) || routesRaw.length === 0) {\n throw new TypeError('delegate_ui_audit: `routes` must be a non-empty array')\n }\n const routes = routesRaw.map((r, i) => validateRoute(r, i))\n const args: DelegateUiAuditArgs = { workspaceDir: workspaceDir.trim(), routes }\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string' || value.namespace.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `namespace` must be a non-empty string when set')\n }\n args.namespace = value.namespace.trim()\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n return args\n}\n\nfunction validateRoute(raw: unknown, index: number): DelegateUiAuditArgs['routes'][number] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(`delegate_ui_audit: routes[${index}] must be an object`)\n }\n const v = raw as Record<string, unknown>\n if (typeof v.name !== 'string' || v.name.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].name must be a non-empty string`)\n }\n // Defense-in-depth: the slug helpers downstream strip non-alphanumerics, so\n // a route name with `..`, `/`, `\\`, or NUL cannot actually escape the\n // workspace. Rejecting them at the wire boundary keeps the invariant\n // explicit and matches the lens-allowlist style of validation.\n const trimmedName = v.name.trim()\n if (/[./\\\\]/.test(trimmedName) || trimmedName.includes('\\u0000')) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].name must not contain path separators, dots, or NUL (got ${JSON.stringify(v.name)})`,\n )\n }\n if (typeof v.url !== 'string' || v.url.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].url must be a non-empty string`)\n }\n // Parse + restrict to http/https. The in-process auditor client navigates\n // to whatever URL the MCP caller supplies; permitting `file://`, `data:`,\n // `javascript:` would let an attacker controlling the tool input pull\n // local files or run inline scripts.\n let parsedUrl: URL\n try {\n parsedUrl = new URL(v.url)\n } catch {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url is not a parseable URL (got ${JSON.stringify(v.url)})`,\n )\n }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url must use http or https (got ${parsedUrl.protocol})`,\n )\n }\n const out: DelegateUiAuditArgs['routes'][number] = { name: v.name.trim(), url: v.url.trim() }\n if (v.viewports !== undefined) {\n if (!Array.isArray(v.viewports) || v.viewports.length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].viewports must be a non-empty array when set`,\n )\n }\n out.viewports = v.viewports.map((vp, j) => validateViewport(vp, index, j))\n }\n if (v.fullPage !== undefined) {\n if (typeof v.fullPage !== 'boolean') {\n throw new TypeError(`delegate_ui_audit: routes[${index}].fullPage must be a boolean`)\n }\n out.fullPage = v.fullPage\n }\n if (v.waitFor !== undefined) {\n if (typeof v.waitFor !== 'string' || v.waitFor.trim().length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].waitFor must be a non-empty string when set`,\n )\n }\n out.waitFor = v.waitFor.trim()\n }\n return out\n}\n\nfunction validateViewport(\n raw: unknown,\n routeIndex: number,\n viewportIndex: number,\n): { width: number; height: number } {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must be an object`,\n )\n }\n const v = raw as Record<string, unknown>\n const w = Number(v.width)\n const h = Number(v.height)\n if (!Number.isInteger(w) || w <= 0 || !Number.isInteger(h) || h <= 0) {\n throw new RangeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must have positive integer width/height`,\n )\n }\n return { width: w, height: h }\n}\n\nfunction validateConfig(raw: unknown): DelegateUiAuditArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: `config` must be an object')\n }\n const v = raw as Record<string, unknown>\n const out: NonNullable<DelegateUiAuditArgs['config']> = {}\n if (v.lenses !== undefined) {\n if (!Array.isArray(v.lenses) || v.lenses.length === 0) {\n throw new TypeError('delegate_ui_audit: `config.lenses` must be a non-empty array when set')\n }\n const knownSet = new Set<string>(UI_LENSES)\n const lenses: UiLens[] = []\n for (let i = 0; i < v.lenses.length; i += 1) {\n const lens = v.lenses[i]\n if (typeof lens !== 'string' || !knownSet.has(lens)) {\n throw new TypeError(\n `delegate_ui_audit: config.lenses[${i}] must be one of ${UI_LENSES.join('|')}`,\n )\n }\n lenses.push(lens as UiLens)\n }\n out.lenses = lenses\n }\n if (v.maxIterations !== undefined) {\n const n = Number(v.maxIterations)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxIterations` must be a positive integer')\n }\n out.maxIterations = n\n }\n if (v.maxConcurrency !== undefined) {\n const n = Number(v.maxConcurrency)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxConcurrency` must be a positive integer')\n }\n out.maxConcurrency = n\n }\n if (v.productContext !== undefined) {\n if (typeof v.productContext !== 'string') {\n throw new TypeError('delegate_ui_audit: `config.productContext` must be a string')\n }\n out.productContext = v.productContext\n }\n return out\n}\n\n/** @experimental */\ninterface DelegateUiAuditHandlerOptions {\n queue: DelegationTaskQueue\n delegate: UiAuditorDelegate\n estimateDurationMs?: (args: DelegateUiAuditArgs) => number\n}\n\n/** Build the MCP tool handler that validates input, deduplicates via idempotency key, and enqueues a UI audit. @experimental */\nexport function createDelegateUiAuditHandler(\n options: DelegateUiAuditHandlerOptions,\n): (raw: unknown) => Promise<DelegateUiAuditResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateUiAuditArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'ui-auditor',\n workspaceDir: args.workspaceDir,\n routes: args.routes,\n namespace: args.namespace,\n config: args.config,\n })\n const submitted = options.queue.submit<DelegateUiAuditArgs>({\n profile: 'ui-auditor',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: DelegateUiAuditArgs): number {\n const lenses = args.config?.lenses?.length ?? UI_LENSES.length - 1\n const routes = args.routes.length\n return PER_LENS_PER_ROUTE_ESTIMATE_MS * lenses * routes\n}\n","/**\n *\n * MCP delegation tool surface — the typed inputs/outputs the product agent\n * sees over the wire. These types are the contract; the JSON schemas under\n * `tools/*` mirror them for the MCP `tools/list` advertisement.\n *\n * Async semantics: `delegate_ui_audit` returns a `taskId` immediately. The\n * product agent polls `delegation_status` until the task transitions to\n * `completed` | `failed` | `cancelled`. `delegate_feedback` +\n * `delegation_history` are synchronous reads / writes against the local\n * task queue + feedback store.\n *\n * @experimental\n */\n\nimport type { ResearchSource } from '../profiles/researcher'\nimport type { UiFinding, UiLens } from '../profiles/ui-auditor/substrate'\nimport type { DelegationTraceSpan } from './delegation-trace'\nimport type { CoderOutput } from './detached-coder'\n\n/**\n * Every delegation profile a queued record can carry. One owner: the tool schemas and validators\n * that filter on a profile read this list, so a profile added here cannot be one a tool refuses.\n * @experimental\n */\nexport const delegationProfiles = ['coder', 'researcher', 'ui-auditor'] as const\n\n/** @experimental */\nexport type DelegationProfile = (typeof delegationProfiles)[number]\n\n/** @experimental */\nexport type DelegationStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n\n/**\n * Minimal `CoderTask` overrides exposed over the MCP wire. The full\n * `CoderTask` carries fields the kernel synthesizes from `goal` +\n * `repoRoot` — the agent only edits the few that materially gate\n * validator behavior.\n *\n * @experimental\n */\nexport interface DelegateCodeConfig {\n testCmd?: string\n typecheckCmd?: string\n forbiddenPaths?: string[]\n maxDiffLines?: number\n}\n\n/** @experimental */\nexport interface DelegateCodeArgs {\n /** Natural-language description of what the coder must accomplish. */\n goal: string\n /** Absolute path inside the sandbox where the repo lives. */\n repoRoot: string\n /** Optional free-form context the agent surfaces in the prompt prelude. */\n contextHint?: string\n /**\n * When > 1, dispatches `multiHarnessCoderFanout` across the delegate's configured exact profiles\n * and picks the highest-scoring passing patch. Default 1.\n */\n variants?: number\n /** Validator + prompt overrides the agent knows for this repo. */\n config?: DelegateCodeConfig\n /** Multi-tenant scope (customer-id, workspace-id). */\n namespace?: string\n}\n\nexport type { ResearchSource }\n\n/** @experimental */\nexport interface DelegateResearchConfig {\n recencyWindow?: { since?: string; until?: string }\n maxItems?: number\n minConfidence?: number\n}\n\n/** @experimental */\nexport interface DelegateResearchArgs {\n question: string\n namespace: string\n scope?: string\n sources?: ResearchSource[]\n variants?: number\n config?: DelegateResearchConfig\n}\n\n/** @experimental */\nexport interface FeedbackRefersTo {\n kind: 'delegation' | 'artifact' | 'outcome'\n /** For `'delegation'`, this is the taskId. */\n ref: string\n}\n\n/** @experimental */\nexport interface FeedbackRating {\n /** [0, 1]. */\n score: number\n label?: 'good' | 'bad' | 'neutral' | 'mixed'\n notes: string\n}\n\n/** @experimental */\nexport interface DelegateFeedbackArgs {\n refersTo: FeedbackRefersTo\n rating: FeedbackRating\n by: 'agent' | 'user' | 'downstream-judge'\n /** ISO timestamp; defaults to server clock when omitted. */\n capturedAt?: string\n namespace?: string\n}\n\n/** @experimental */\nexport interface DelegateFeedbackResult {\n recorded: true\n id: string\n}\n\n/** @experimental */\nexport interface DelegationStatusArgs {\n taskId: string\n /**\n * Return the delegation's compact loop-trace span tree alongside the\n * status. Default false — status polls stay light; opt in when you need\n * the topology (which iterations ran, where they were placed, what each\n * cost) rather than just the state machine.\n */\n includeTrace?: boolean\n}\n\n/** @experimental */\nexport interface DelegationProgress {\n iteration: number\n phase: string\n}\n\n/** @experimental */\nexport interface DelegationError {\n message: string\n kind: string\n}\n\n/**\n * Polymorphic `result` field: `CoderOutput` when the underlying profile\n * is `'coder'`, a structurally-typed research output when `'researcher'`.\n * The MCP wire carries it as JSON either way.\n *\n * @experimental\n */\nexport type DelegationResultPayload =\n | { profile: 'coder'; output: CoderOutput }\n | { profile: 'researcher'; output: ResearchOutputShape }\n | { profile: 'ui-auditor'; output: UiAuditorDelegationOutput }\n\n/**\n * Wire-shape of a completed UI-audit delegation. The `findings` array\n * contains every finding persisted to the workspace during the run,\n * already enriched with `id` and `createdAt` by the writer. `workspaceDir`\n * is the absolute path to the workspace; `indexFile` is the workspace-\n * relative path to the regenerated index.md.\n *\n * @experimental\n */\nexport interface UiAuditorDelegationOutput {\n workspaceDir: string\n indexFile: string\n findings: UiFinding[]\n /** Total iterations the loop ran for this delegation. */\n iterations: number\n}\n\n/** @experimental */\nexport type UiAuditLensFilter = readonly UiLens[]\n\n/** Optional per-route capture spec the agent surfaces over the wire. */\nexport interface DelegateUiAuditRoute {\n /** Stable route name (used in screenshot filenames + finding metadata). */\n name: string\n /** Fully-qualified URL. */\n url: string\n /** Viewports to capture at. Defaults to `[{ width: 1280, height: 800 }]`. */\n viewports?: readonly { width: number; height: number }[]\n /** Default false. Full-page captures for the broad lenses. */\n fullPage?: boolean\n /** Selector to wait for before capture. */\n waitFor?: string\n}\n\n/** @experimental */\nexport interface DelegateUiAuditConfig {\n /**\n * Lenses to iterate. Default: every lens except `'other'`. Order is\n * preserved — the driver iterates lens-by-lens.\n */\n lenses?: UiAuditLensFilter\n /** Maximum total iterations across all (lens × route) pairs. Default 33 (11 lenses × 3 routes). */\n maxIterations?: number\n /** Maximum concurrent iterations within a single plan() round. Default 2. */\n maxConcurrency?: number\n /** Free-form product context surfaced to the judge. */\n productContext?: string\n}\n\n/** @experimental */\nexport interface DelegateUiAuditArgs {\n /** Workspace root for the audit (absolute path). */\n workspaceDir: string\n /** Routes to audit. Must be non-empty. */\n routes: readonly DelegateUiAuditRoute[]\n /** Multi-tenant scope. */\n namespace?: string\n config?: DelegateUiAuditConfig\n}\n\n/** @experimental */\nexport interface DelegateUiAuditResult {\n taskId: string\n estimatedDurationMs?: number\n}\n\n/**\n * Provider-neutral research output carried over the MCP boundary. The MCP\n * layer accepts this structural shape instead of coupling its wire contract to\n * one research implementation.\n *\n * @experimental\n */\nexport interface ResearchOutputShape {\n items: unknown[]\n citations: unknown[]\n proposedWrites: unknown[]\n gaps?: string[]\n notes?: string\n [key: string]: unknown\n}\n\n/** @experimental */\nexport interface DelegationStatusResult {\n taskId: string\n profile: DelegationProfile\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Compact loop-trace span tree; present only when `includeTrace: true` was passed and spans were recorded. */\n trace?: DelegationTraceSpan[]\n /** Present when oldest trace spans were dropped to honor the trace caps. */\n traceTruncated?: true\n /** Inherited trace identity recorded at submit — join key into the caller's trace. */\n traceId?: string\n /** Caller span that dispatched the delegation, when one was inherited. */\n parentSpanId?: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryArgs {\n namespace?: string\n profile?: DelegationProfile\n /** ISO date — only delegations started at-or-after `since` are returned. */\n since?: string\n /** Default 50. Hard cap 500. */\n limit?: number\n}\n\n/** @experimental */\nexport interface DelegationFeedbackSnapshot {\n id: string\n score: number\n label?: FeedbackRating['label']\n by: DelegateFeedbackArgs['by']\n notes: string\n capturedAt: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryEntry {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs\n status: DelegationStatus\n feedback?: DelegationFeedbackSnapshot[]\n costUsd?: number\n startedAt: string\n completedAt?: string\n /**\n * True when the record carries a journaled loop trace. History stays\n * light by design — fetch the spans via\n * `delegation_status { taskId, includeTrace: true }`.\n */\n hasTrace: boolean\n /** Inherited trace identity recorded at submit — join key into the caller's trace. */\n traceId?: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryResult {\n delegations: DelegationHistoryEntry[]\n}\n\n/**\n * Re-export `CoderTask` so callers wiring custom delegates don't have to\n * import from `./profiles` themselves.\n *\n * @experimental\n */\nexport type { CoderOutput }\n","/**\n *\n * `delegation_history` MCP tool — synchronous read of past delegations.\n * The agent uses this for self-introspection — \"have I delegated this\n * kind of task before? did it work?\" — and calibration.\n *\n * @stable\n */\n\nimport type {\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationTaskQueue,\n} from '../task-queue'\nimport { delegationProfiles } from '../types'\n\n/** MCP tool name for the `delegation_history` read-past-delegations tool. @stable */\nexport const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history'\n\n/** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATION_HISTORY_DESCRIPTION = [\n 'Read past delegations newest-first. Each entry carries the original',\n 'arguments, current status, cost, and any feedback attached via',\n 'delegate_feedback.',\n '',\n 'Use when: you want to introspect prior decisions — \"have I asked this',\n 'question before?',\n 'did the last patch land?',\n \"what's the historical\",\n 'success rate of coder delegations on this repo?\". Feed the results back',\n 'into your own routing and calibration.',\n '',\n 'Each entry carries `hasTrace` — when true, the full loop-trace span tree',\n 'is retrievable via delegation_status { taskId, includeTrace: true }.',\n '',\n `Filters: \\`namespace\\` (multi-tenant scope), \\`profile\\` (${delegationProfiles\n .map((profile) => `\"${profile}\"`)\n .join(' | ')}),`,\n '`since` (ISO date — only delegations started at-or-after). `limit` defaults',\n 'to 50, capped at 500.',\n].join('\\n')\n\n/** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @stable */\nexport const DELEGATION_HISTORY_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n namespace: { type: 'string' },\n profile: { type: 'string', enum: delegationProfiles },\n since: { type: 'string', description: 'ISO datetime — earliest startedAt to include.' },\n limit: { type: 'integer', minimum: 1, maximum: 500 },\n },\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryArgs {\n if (raw === undefined || raw === null) return {}\n if (typeof raw !== 'object') {\n throw new TypeError('delegation_history: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: DelegationHistoryArgs = {}\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string') {\n throw new TypeError('delegation_history: `namespace` must be a string')\n }\n out.namespace = value.namespace\n }\n if (value.profile !== undefined) {\n if (!delegationProfiles.includes(value.profile as DelegationProfile)) {\n throw new TypeError(\n `delegation_history: \\`profile\\` must be one of ${delegationProfiles.join(', ')}`,\n )\n }\n out.profile = value.profile as DelegationProfile\n }\n if (value.since !== undefined) {\n if (typeof value.since !== 'string' || Number.isNaN(Date.parse(value.since))) {\n throw new TypeError('delegation_history: `since` must be an ISO datetime')\n }\n out.since = value.since\n }\n if (value.limit !== undefined) {\n const n = Number(value.limit)\n if (!Number.isFinite(n) || n < 1 || n > 500) {\n throw new RangeError('delegation_history: `limit` must be an integer in [1, 500]')\n }\n out.limit = Math.trunc(n)\n }\n return out\n}\n\n/** @stable */\ninterface DelegationHistoryHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @stable */\nexport function createDelegationHistoryHandler(\n options: DelegationHistoryHandlerOptions,\n): (raw: unknown) => Promise<DelegationHistoryResult> {\n return async (raw) => {\n const args = validateDelegationHistoryArgs(raw)\n return { delegations: options.queue.history(args) }\n }\n}\n","/**\n *\n * `delegation_status` MCP tool — synchronous poll. Returns the current\n * state machine + optional progress + final result (when terminal).\n *\n * @stable\n */\n\nimport { NotFoundError } from '../../errors'\nimport type {\n DelegationStatusArgs,\n DelegationStatusResult,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** MCP tool name for the `delegation_status` synchronous-poll tool. @stable */\nexport const DELEGATION_STATUS_TOOL_NAME = 'delegation_status'\n\n/** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATION_STATUS_DESCRIPTION = [\n 'Poll the status of an async delegation. Returns the current state',\n '(pending | running | completed | failed | cancelled), optional progress,',\n 'and the final result when status === \"completed\".',\n '',\n 'Use when: you previously kicked off an async delegation (delegate_ui_audit)',\n \"and need to know whether the work is done. The agent's right rhythm is to\",\n 'call this every minute or two while waiting; do not busy-poll.',\n '',\n 'For a completed delegate_ui_audit run, `result.output` is the array of UI',\n 'findings — one self-contained Markdown finding per issue, each with an',\n 'embedded screenshot and a suggested fix.',\n '',\n 'Pass includeTrace: true to also receive the journaled loop-trace span',\n 'tree (loop → round → iteration, with placement/cost/verdict metadata).',\n 'Default false — keep routine polls light.',\n '',\n 'Throws NotFoundError when taskId is unknown — never silently returns',\n '`pending` for a typo.',\n].join('\\n')\n\n/** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @stable */\nexport const DELEGATION_STATUS_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n taskId: { type: 'string', description: 'Returned by delegate_ui_audit.' },\n includeTrace: {\n type: 'boolean',\n description:\n 'Also return the journaled loop-trace span tree for this delegation. Default false.',\n },\n },\n required: ['taskId'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegation_status: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const taskId = value.taskId\n if (typeof taskId !== 'string' || taskId.trim().length === 0) {\n throw new TypeError('delegation_status: `taskId` must be a non-empty string')\n }\n const out: DelegationStatusArgs = { taskId: taskId.trim() }\n if (value.includeTrace !== undefined) {\n if (typeof value.includeTrace !== 'boolean') {\n throw new TypeError('delegation_status: `includeTrace` must be a boolean')\n }\n out.includeTrace = value.includeTrace\n }\n return out\n}\n\n/** @stable */\ninterface DelegationStatusHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. @stable */\nexport function createDelegationStatusHandler(\n options: DelegationStatusHandlerOptions,\n): (raw: unknown) => Promise<DelegationStatusResult> {\n return async (raw) => {\n const args = validateDelegationStatusArgs(raw)\n const status = options.queue.status(\n args.taskId,\n args.includeTrace !== undefined ? { includeTrace: args.includeTrace } : undefined,\n )\n if (!status) {\n throw new NotFoundError(`delegation_status: unknown taskId \"${args.taskId}\"`)\n }\n return status\n }\n}\n","/**\n *\n * Stdio JSON-RPC MCP server exposing the delegation tools to sandbox\n * coding-harness agents (claude-code, codex, opencode, ...): the generic\n * `delegate` verb plus the queue-bound `delegate_feedback`,\n * `delegation_status`, and `delegation_history`. `delegate_ui_audit` is served\n * when a `uiAuditorDelegate` is wired.\n *\n * The server is transport-bound but topology-free: tool execution is\n * delegated to handler functions composed from a queue, a feedback\n * store, and the wired run delegates. Consumers wire those at\n * construction time. The `agent-runtime-mcp` bin serves the generic\n * `delegate` verb over a real sandbox client when `MCP_ENABLE_DELEGATE=1`.\n *\n * Wire protocol: line-delimited JSON-RPC 2.0 over stdio. Each line is\n * one request; each response is one line. `tools/list` and `tools/call`\n * mirror the MCP 2024-11-05 spec. The production server does not depend on\n * `@modelcontextprotocol/sdk`; integration tests validate this wire with the official client.\n *\n * @experimental\n */\n\nimport { Readable, Writable } from 'node:stream'\nimport { ValidationError } from '../errors'\nimport type { UiAuditorDelegate } from './delegates'\nimport { type FeedbackStore, InMemoryFeedbackStore } from './feedback-store'\nimport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\nimport { DelegationTaskQueue } from './task-queue'\nimport { createStdioToolServer } from './tool-server'\nimport {\n createDelegateHandler,\n DELEGATE_DESCRIPTION,\n DELEGATE_INPUT_SCHEMA,\n DELEGATE_TOOL_NAME,\n type DelegateHandlerOptions,\n} from './tools/delegate'\nimport {\n createDelegateFeedbackHandler,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n createDelegateUiAuditHandler,\n DELEGATE_UI_AUDIT_DESCRIPTION,\n DELEGATE_UI_AUDIT_INPUT_SCHEMA,\n DELEGATE_UI_AUDIT_TOOL_NAME,\n} from './tools/delegate-ui-audit'\nimport {\n createDelegationHistoryHandler,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n createDelegationStatusHandler,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\nimport type { TraceContext } from './trace-propagation'\n\nexport type { JsonRpcResponse, McpToolDescriptor } from './protocol'\n\n/** @experimental */\nexport interface McpServerOptions {\n /**\n * Required to enable `delegate` — the ONE generic delegation verb. Inject the supervisor\n * substrate: its brain `router`, the worker `backend`, and the completion `deliverable`. The\n * supervisor AUTHORS its own worker from the agent's intent, so there is no worker profile to\n * wire here.\n */\n delegateSupervisor?: DelegateHandlerOptions\n /**\n * Required to enable delegate_ui_audit. Wire one that executes an exact\n * agent profile through Runtime and returns the provider-neutral UI audit result.\n */\n uiAuditorDelegate?: UiAuditorDelegate\n /** Override the default in-memory feedback store. */\n feedbackStore?: FeedbackStore\n /** Override the default in-memory task queue. */\n queue?: DelegationTaskQueue\n /**\n * Extra tools to serve alongside the delegation tools, for example\n * `createCoordinationTools(...).tools`. Registered after the built-ins; a\n * duplicate name throws so delegation tools cannot be shadowed silently.\n */\n extraTools?: McpToolDescriptor[]\n /**\n * Inherited trace identity (`readTraceContextFromEnv()`) stamped on every\n * record the DEFAULT queue creates. Ignored when `queue` is supplied —\n * pass `traceContext` to that queue's constructor instead.\n */\n traceContext?: TraceContext\n /** Server display name surfaced via `initialize`. Default `'agent-runtime-mcp'`. */\n serverName?: string\n /** Server version surfaced via `initialize`. Default = the package version baked at build time. */\n serverVersion?: string\n}\n\n/** @experimental */\nexport interface McpServer {\n /** Tools currently registered (depend on which delegates were wired). */\n readonly tools: ReadonlyMap<string, McpToolDescriptor>\n /** The underlying queue — exposed so tests can introspect it. */\n readonly queue: DelegationTaskQueue\n /** The feedback store — exposed for the same reason. */\n readonly feedbackStore: FeedbackStore\n /** Handle a single parsed JSON-RPC message. Returns the response object (or `null` for notifications). */\n handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null>\n /** Drive the server on a stdio-shaped transport until `stop()` is called. */\n serve(transport?: McpTransport): Promise<void>\n /** Stop a `serve` call. Subsequent requests are rejected. */\n stop(): void\n}\n\nconst DEFAULT_SERVER_NAME = 'agent-runtime-mcp'\nconst DEFAULT_SERVER_VERSION = '0.22.0'\n\n/**\n * Stdio JSON-RPC MCP server exposing the delegation tools (`delegate`, `delegate_feedback`, `delegation_status`, `delegation_history`, optional `delegate_ui_audit`) to sandbox coding-harness agents.\n *\n * @experimental\n */\nexport function createMcpServer(options: McpServerOptions = {}): McpServer {\n const queue =\n options.queue ??\n new DelegationTaskQueue(\n options.traceContext !== undefined ? { traceContext: options.traceContext } : {},\n )\n const feedbackStore = options.feedbackStore ?? new InMemoryFeedbackStore()\n const serverName = options.serverName ?? DEFAULT_SERVER_NAME\n const serverVersion = options.serverVersion ?? DEFAULT_SERVER_VERSION\n\n const tools = new Map<string, McpToolDescriptor>()\n\n if (options.delegateSupervisor) {\n tools.set(DELEGATE_TOOL_NAME, {\n name: DELEGATE_TOOL_NAME,\n description: DELEGATE_DESCRIPTION,\n inputSchema: DELEGATE_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateHandler(options.delegateSupervisor),\n })\n }\n if (options.uiAuditorDelegate) {\n tools.set(DELEGATE_UI_AUDIT_TOOL_NAME, {\n name: DELEGATE_UI_AUDIT_TOOL_NAME,\n description: DELEGATE_UI_AUDIT_DESCRIPTION,\n inputSchema: DELEGATE_UI_AUDIT_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateUiAuditHandler({ queue, delegate: options.uiAuditorDelegate }),\n })\n }\n tools.set(DELEGATE_FEEDBACK_TOOL_NAME, {\n name: DELEGATE_FEEDBACK_TOOL_NAME,\n description: DELEGATE_FEEDBACK_DESCRIPTION,\n inputSchema: DELEGATE_FEEDBACK_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateFeedbackHandler({ queue, store: feedbackStore }),\n })\n tools.set(DELEGATION_STATUS_TOOL_NAME, {\n name: DELEGATION_STATUS_TOOL_NAME,\n description: DELEGATION_STATUS_DESCRIPTION,\n inputSchema: DELEGATION_STATUS_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationStatusHandler({ queue }),\n })\n tools.set(DELEGATION_HISTORY_TOOL_NAME, {\n name: DELEGATION_HISTORY_TOOL_NAME,\n description: DELEGATION_HISTORY_DESCRIPTION,\n inputSchema: DELEGATION_HISTORY_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationHistoryHandler({ queue }),\n })\n for (const tool of options.extraTools ?? []) {\n if (tools.has(tool.name)) {\n throw new ValidationError(\n `createMcpServer: extra tool \"${tool.name}\" shadows a built-in tool`,\n )\n }\n tools.set(tool.name, tool)\n }\n\n const stdio = createStdioToolServer({\n serverName,\n serverVersion,\n tools: [...tools.values()],\n })\n\n return {\n tools: stdio.tools,\n queue,\n feedbackStore,\n handle: stdio.handle,\n serve: stdio.serve,\n stop: stdio.stop,\n }\n}\n\n/**\n * In-process pair of `Readable` + `Writable` streams suitable for driving\n * `server.serve(...)` from a test. Returns the agent-side stream (the\n * client writes to it) and the server-side stream (the test reads from it).\n *\n * @experimental\n */\nexport function createInProcessTransport(): {\n transport: McpTransport\n clientWrite(line: string): void\n clientClose(): void\n readServer(): Promise<JsonRpcResponse[]>\n} {\n const responses: JsonRpcResponse[] = []\n const input = new Readable({ read() {} })\n const output = new Writable({\n write(chunk, _enc, cb) {\n const text = chunk.toString('utf8')\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n responses.push(JSON.parse(trimmed) as JsonRpcResponse)\n } catch {\n // Non-JSON output should never appear; drop it silently in the\n // test transport rather than crashing.\n }\n }\n cb()\n },\n })\n return {\n transport: { input, output },\n clientWrite(line: string) {\n input.push(`${line}\\n`)\n },\n clientClose() {\n input.push(null)\n },\n async readServer() {\n // Yield to the event loop a few times so async handlers drain.\n for (let i = 0; i < 5; i += 1) await new Promise((r) => setImmediate(r))\n return [...responses]\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server-BP7d8yGG.js","names":[],"sources":["../src/mcp/delegation-trace.ts","../src/mcp/delegation-store.ts","../src/mcp/feedback-store.ts","../src/mcp/task-queue.ts","../src/mcp/tools/delegate.ts","../src/mcp/tools/delegate-feedback.ts","../src/mcp/tools/delegate-ui-audit.ts","../src/mcp/types.ts","../src/mcp/tools/delegation-history.ts","../src/mcp/tools/delegation-status.ts","../src/mcp/server.ts"],"sourcesContent":["/**\n *\n * Compact loop-trace tee for the delegation journal.\n *\n * The OTEL exporter ({@link createPropagatingTraceEmitter}) is a no-op\n * without `OTEL_EXPORTER_OTLP_ENDPOINT`, which leaves delegated work streams\n * dark in practice. This module derives the same loop → round → branch span\n * tree (via the shared {@link buildLoopSpanNodes} builder) into a small,\n * JSON-safe shape persisted directly on the `DelegationRecord` — observable\n * through `delegation_status` with no collector infrastructure. Both sinks\n * coexist: the OTEL export path is unchanged.\n *\n * Payload discipline: a record's trace is hard-capped (spans + serialized\n * bytes). Past the cap the OLDEST spans are dropped and the record carries a\n * `traceTruncated: true` marker — truncation is never silent.\n *\n * @experimental\n */\n\nimport { buildLoopSpanNodes } from '../otel-export'\nimport type { LoopTraceEmitter, LoopTraceEvent } from '../runtime/types'\n\n/**\n * One span of a delegation's compact trace. Flat (parent linkage by id), all\n * values JSON-safe scalars — `FileDelegationStore` round-trips records\n * through `JSON.stringify`. `meta` carries the span's attributes (GenAI\n * semconv keys + `tangle.loop.*` extensions) exactly as the OTEL sink emits\n * them, so a consumer can re-export journal traces losslessly.\n *\n * @experimental\n */\nexport interface DelegationTraceSpan {\n spanId: string\n /** Absent on the tree root. */\n parentSpanId?: string\n /** `'loop'` | `'loop.round'` | `'loop.iteration'` (or a sink-specific name). */\n name: string\n /** Topology level: loop root, plan round, or iteration branch. */\n kind: 'loop' | 'round' | 'branch'\n startMs: number\n endMs: number\n meta?: Record<string, string | number | boolean>\n}\n\n/** Default cap on spans retained per delegation record. @experimental */\nconst DELEGATION_TRACE_MAX_SPANS = 512\n\n/** Default cap on the serialized trace payload per record, in bytes. @experimental */\nconst DELEGATION_TRACE_MAX_BYTES = 256 * 1024\n\n/** @experimental */\ninterface DelegationTraceCaps {\n /** Default {@link DELEGATION_TRACE_MAX_SPANS}. */\n maxSpans?: number\n /** Default {@link DELEGATION_TRACE_MAX_BYTES}. Approximate — measured as the\n * sum of per-span `JSON.stringify` lengths. */\n maxBytes?: number\n}\n\n/** @experimental */\ninterface CappedDelegationTrace {\n trace: DelegationTraceSpan[]\n /** True when oldest spans were dropped to honor the caps. */\n truncated: boolean\n}\n\n/**\n * Derive the compact span tree for ONE loop run from its buffered\n * `LoopTraceEvent` stream. Same reconstruction as the OTEL exporter\n * ({@link buildLoopSpanNodes}); tolerates partial streams.\n *\n * @experimental\n */\nexport function buildDelegationTraceSpans(\n events: ReadonlyArray<LoopTraceEvent>,\n): DelegationTraceSpan[] {\n return buildLoopSpanNodes(events).map((node) => ({\n spanId: node.spanId,\n ...(node.parentSpanId !== undefined ? { parentSpanId: node.parentSpanId } : {}),\n name: node.name,\n kind: node.kind,\n startMs: node.startMs,\n endMs: node.endMs,\n ...(Object.keys(node.attrs).length > 0 ? { meta: node.attrs } : {}),\n }))\n}\n\n/**\n * Enforce the trace caps over an ordered (oldest-first) span list. Drops the\n * OLDEST spans first and reports `truncated: true` when anything was dropped;\n * the newest span always survives, so a non-empty input never caps to empty.\n * Dropping a parent may orphan surviving children's `parentSpanId` references\n * — acceptable for the flat journal shape; consumers treat unresolved parents\n * as roots.\n *\n * @experimental\n */\nexport function capDelegationTrace(\n spans: ReadonlyArray<DelegationTraceSpan>,\n caps?: DelegationTraceCaps,\n): CappedDelegationTrace {\n const maxSpans = caps?.maxSpans ?? DELEGATION_TRACE_MAX_SPANS\n const maxBytes = caps?.maxBytes ?? DELEGATION_TRACE_MAX_BYTES\n let start = Math.max(0, spans.length - maxSpans)\n const sizes = spans.map((span) => JSON.stringify(span).length + 1)\n let total = 0\n for (let i = start; i < sizes.length; i += 1) total += sizes[i]!\n while (start < spans.length - 1 && total > maxBytes) {\n total -= sizes[start]!\n start += 1\n }\n return { trace: spans.slice(start), truncated: start > 0 }\n}\n\n/**\n * Per-delegation trace collector. Buffers `LoopTraceEvent`s per runId\n * (mirroring the OTEL emitter's buffering) and hands the derived compact\n * spans to `onSpans` when a run reaches `loop.ended`. `settle()` drains runs\n * that never ended — a hard-aborted loop still leaves its partial tree in the\n * journal, unlike the OTEL path which drops it.\n *\n * @experimental\n */\ninterface DelegationTraceCollector {\n emitter: LoopTraceEmitter\n /** Flush buffered events of runs that never reached `loop.ended`. */\n settle(): void\n}\n\n/** Build a `DelegationTraceCollector` that buffers loop-trace events and converts them to spans on settle. @experimental */\nexport function createDelegationTraceCollector(\n onSpans: (spans: DelegationTraceSpan[]) => void,\n): DelegationTraceCollector {\n const buffers = new Map<string, LoopTraceEvent[]>()\n const flush = (events: LoopTraceEvent[]): void => {\n const spans = buildDelegationTraceSpans(events)\n if (spans.length > 0) onSpans(spans)\n }\n return {\n emitter: {\n emit(event: LoopTraceEvent): void {\n const buf = buffers.get(event.runId)\n if (buf) buf.push(event)\n else buffers.set(event.runId, [event])\n if (event.kind === 'loop.ended') {\n const events = buffers.get(event.runId) ?? [event]\n buffers.delete(event.runId)\n flush(events)\n }\n },\n },\n settle(): void {\n for (const events of buffers.values()) flush(events)\n buffers.clear()\n },\n }\n}\n\n/**\n * 16-hex-char span id for journal spans synthesized outside the shared loop\n * builder (e.g. the queue's detached-resume segment).\n *\n * @experimental\n */\nexport function generateDelegationSpanId(): string {\n const bytes = new Uint8Array(8)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 8; i += 1) bytes[i] = Math.floor(Math.random() * 256)\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n/**\n * Fan one `LoopTraceEvent` stream into several emitters — e.g. the\n * process-wide OTEL exporter AND the per-delegation journal collector.\n * `undefined` entries are skipped; returns `undefined` when nothing is left\n * so callers keep the kernel's \"no emitter, no events\" fast path.\n *\n * @experimental\n */\nexport function composeLoopTraceEmitters(\n ...emitters: ReadonlyArray<LoopTraceEmitter | undefined>\n): LoopTraceEmitter | undefined {\n const live = emitters.filter((e): e is LoopTraceEmitter => e !== undefined)\n if (live.length === 0) return undefined\n if (live.length === 1) return live[0]\n return {\n emit(event: LoopTraceEvent): void | Promise<void> {\n const pending: Promise<void>[] = []\n for (const emitter of live) {\n const result = emitter.emit(event)\n if (result) pending.push(result)\n }\n if (pending.length > 0) return Promise.all(pending).then(() => undefined)\n },\n }\n}\n","/**\n *\n * Persistence port for the MCP delegation queue.\n *\n * `DelegationTaskQueue` keeps its working set in memory (status/history\n * reads stay synchronous) and journals every record mutation through a\n * `DelegationStore`. `DelegationTaskQueue.restore({ store })` is the load\n * path: it reads the full record set once at construction and rehydrates\n * the queue from it. After that the store only sees writes.\n *\n * Records MUST be JSON-safe — `FileDelegationStore` round-trips them\n * through `JSON.stringify`/`JSON.parse`, so a `Date`, `Map`, or function\n * smuggled into `args`/`result` would corrupt the journal.\n *\n * @stable\n */\n\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { AgentEvalError } from '../errors'\nimport { errorMessage } from '../runtime/util'\nimport type { DelegationRecord } from './task-queue'\n\n/** @stable */\nexport interface DelegationStore {\n /**\n * Read every persisted record. Called once, by\n * `DelegationTaskQueue.restore`, before any write. A missing backing\n * file is an empty store; an unparseable one throws\n * `DelegationStateCorruptError`.\n */\n loadAll(): Promise<DelegationRecord[]>\n /** Insert or replace the record keyed by `record.taskId`. */\n upsert(record: DelegationRecord): Promise<void>\n /**\n * Resolve an idempotency key to the taskId that claimed it, if any.\n * The queue serves submit-time dedupe from its rehydrated in-memory\n * index; this read exists for consumers that share a store across\n * processes without holding the full record set.\n */\n lookupIdempotencyKey(key: string): Promise<string | undefined>\n /** Delete the named records — the retention-cap eviction path. */\n remove(taskIds: readonly string[]): Promise<void>\n}\n\n/**\n * The persisted delegation state exists but cannot be parsed into\n * records. Fail loud: silently starting empty over a corrupt journal\n * would erase delegation history and re-run idempotent work. Opt into\n * recovery explicitly via `FileDelegationStoreOptions.recoverCorrupt`\n * (the bin maps `AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1` onto it),\n * which archives the corrupt file and starts fresh.\n *\n * @stable\n */\nexport class DelegationStateCorruptError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n\n/**\n * A delegation-store read or write failed (filesystem error, store\n * called before `loadAll`, ...). Once the queue observes one, it stops\n * accepting new submissions — accepting work it cannot journal would\n * silently demote durable mode to in-memory mode.\n *\n * @stable\n */\nexport class DelegationPersistenceError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('config', message, options)\n }\n}\n\n/** In-memory `DelegationStore` — suitable for single-process use and tests. @stable */\nexport class InMemoryDelegationStore implements DelegationStore {\n private readonly records = new Map<string, DelegationRecord>()\n\n async loadAll(): Promise<DelegationRecord[]> {\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.records.set(record.taskId, cloneRecord(record))\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n for (const taskId of taskIds) this.records.delete(taskId)\n }\n}\n\n/** @stable */\nexport interface FileDelegationStoreOptions {\n /** Absolute path of the JSON state file. Parent directories are created on first write. */\n filePath: string\n /**\n * When the state file exists but cannot be parsed, archive it to\n * `<filePath>.corrupt-<timestamp>` and start empty instead of\n * throwing `DelegationStateCorruptError`. Default false.\n */\n recoverCorrupt?: boolean\n}\n\ninterface PersistedDelegationState {\n version: 1\n records: DelegationRecord[]\n}\n\nconst STATE_FORMAT_VERSION = 1\n\n/**\n * JSON-file persistence for the delegation queue. Each write serializes\n * the full record set and lands it atomically (write to a sibling tmp\n * file, then `rename`), so readers never observe a torn file — a crash\n * mid-write leaves the previous snapshot intact. Writes are serialized\n * internally; concurrent `upsert`/`remove` calls cannot interleave.\n *\n * Built for the MCP server's scale (one stdio process, hundreds of\n * records): full-snapshot writes keep the format trivially inspectable\n * and corruption-detectable without a database dependency.\n *\n * @stable\n */\nexport class FileDelegationStore implements DelegationStore {\n private readonly filePath: string\n private readonly recoverCorrupt: boolean\n private readonly records = new Map<string, DelegationRecord>()\n private loaded = false\n private writeTail: Promise<void> = Promise.resolve()\n private tmpSeq = 0\n\n constructor(options: FileDelegationStoreOptions) {\n this.filePath = options.filePath\n this.recoverCorrupt = options.recoverCorrupt ?? false\n }\n\n async loadAll(): Promise<DelegationRecord[]> {\n let raw: string\n try {\n raw = await readFile(this.filePath, 'utf8')\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n this.loaded = true\n return []\n }\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to read ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n let state: PersistedDelegationState\n try {\n state = parsePersistedState(raw)\n } catch (err) {\n if (!this.recoverCorrupt) {\n throw new DelegationStateCorruptError(\n `FileDelegationStore: state file ${this.filePath} is corrupt (${errorMessage(err)}). ` +\n 'Repair or archive the file, or opt into automatic recovery ' +\n '(recoverCorrupt / AGENT_RUNTIME_DELEGATION_STATE_RECOVER=1) to archive it and start empty.',\n { cause: err },\n )\n }\n const archivePath = `${this.filePath}.corrupt-${Date.now()}`\n await rename(this.filePath, archivePath)\n this.loaded = true\n return []\n }\n this.records.clear()\n for (const record of state.records) this.records.set(record.taskId, record)\n this.loaded = true\n return [...this.records.values()].map(cloneRecord)\n }\n\n async upsert(record: DelegationRecord): Promise<void> {\n this.assertLoaded('upsert')\n this.records.set(record.taskId, cloneRecord(record))\n await this.enqueueWrite()\n }\n\n async lookupIdempotencyKey(key: string): Promise<string | undefined> {\n this.assertLoaded('lookupIdempotencyKey')\n for (const record of this.records.values()) {\n if (record.idempotencyKey === key) return record.taskId\n }\n return undefined\n }\n\n async remove(taskIds: readonly string[]): Promise<void> {\n this.assertLoaded('remove')\n let changed = false\n for (const taskId of taskIds) {\n if (this.records.delete(taskId)) changed = true\n }\n if (changed) await this.enqueueWrite()\n }\n\n private assertLoaded(op: string): void {\n if (this.loaded) return\n // Writing before load would snapshot only the new records and clobber\n // whatever the file already holds.\n throw new DelegationPersistenceError(\n `FileDelegationStore: ${op} called before loadAll() — the on-disk state has not been read yet`,\n )\n }\n\n private enqueueWrite(): Promise<void> {\n const write = this.writeTail.then(() => this.writeSnapshot())\n this.writeTail = write.catch(() => {})\n return write\n }\n\n private async writeSnapshot(): Promise<void> {\n const state: PersistedDelegationState = {\n version: STATE_FORMAT_VERSION,\n records: [...this.records.values()],\n }\n const payload = `${JSON.stringify(state)}\\n`\n this.tmpSeq += 1\n const tmpPath = `${this.filePath}.tmp-${process.pid}-${this.tmpSeq}`\n try {\n await mkdir(dirname(this.filePath), { recursive: true })\n await writeFile(tmpPath, payload, 'utf8')\n await rename(tmpPath, this.filePath)\n } catch (err) {\n throw new DelegationPersistenceError(\n `FileDelegationStore: failed to write ${this.filePath}: ${errorMessage(err)}`,\n { cause: err },\n )\n }\n }\n}\n\nfunction parsePersistedState(raw: string): PersistedDelegationState {\n const parsed: unknown = JSON.parse(raw)\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error('top-level value is not an object')\n }\n const state = parsed as Record<string, unknown>\n if (state.version !== STATE_FORMAT_VERSION) {\n throw new Error(`unsupported state version ${JSON.stringify(state.version)}`)\n }\n if (!Array.isArray(state.records)) {\n throw new Error('`records` is not an array')\n }\n for (const record of state.records) {\n if (record === null || typeof record !== 'object') {\n throw new Error('a record entry is not an object')\n }\n const candidate = record as Record<string, unknown>\n if (typeof candidate.taskId !== 'string' || typeof candidate.status !== 'string') {\n throw new Error('a record entry is missing `taskId`/`status`')\n }\n }\n return { version: STATE_FORMAT_VERSION, records: state.records as DelegationRecord[] }\n}\n\nfunction cloneRecord(record: DelegationRecord): DelegationRecord {\n return structuredClone(record)\n}\n","/**\n *\n * Feedback persistence surface for the MCP layer.\n *\n * Feedback storage is product policy, so the MCP layer depends on this narrow\n * interface instead of choosing a knowledge store. The default implementation\n * is in-memory; consumers wire their own durable adapter via\n * `createMcpServer({ feedbackStore })`.\n *\n * Feedback events are append-only: every rating is a new event with a\n * fresh id, even when the same delegation is rated multiple times. The\n * caller decides how to roll up scores downstream.\n *\n * @stable\n */\n\nimport type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types'\n\n/** @stable */\nexport interface FeedbackEvent {\n id: string\n refersTo: DelegateFeedbackArgs['refersTo']\n rating: DelegateFeedbackArgs['rating']\n by: DelegateFeedbackArgs['by']\n capturedAt: string\n namespace?: string\n}\n\n/** @stable */\nexport interface FeedbackStore {\n /** Append a new event. Never dedupes — every rating is its own event. */\n put(event: FeedbackEvent): Promise<void>\n /**\n * List events filtered by `namespace`. When `namespace` is omitted, list\n * across all namespaces. Returns events in insertion order.\n */\n list(filter?: { namespace?: string; refersToRef?: string }): Promise<FeedbackEvent[]>\n}\n\n/** In-memory `FeedbackStore` — suitable for single-process use and tests. @stable */\nexport class InMemoryFeedbackStore implements FeedbackStore {\n private readonly events: FeedbackEvent[] = []\n\n async put(event: FeedbackEvent): Promise<void> {\n this.events.push({ ...event })\n }\n\n async list(filter: { namespace?: string; refersToRef?: string } = {}): Promise<FeedbackEvent[]> {\n let out = this.events\n if (filter.namespace !== undefined) {\n out = out.filter((event) => event.namespace === filter.namespace)\n }\n if (filter.refersToRef !== undefined) {\n out = out.filter((event) => event.refersTo.ref === filter.refersToRef)\n }\n return out.map((event) => ({ ...event }))\n }\n}\n\n/**\n * Project a `FeedbackEvent` down to the snapshot shape carried on\n * `delegation_history` entries.\n *\n * @stable\n */\nexport function eventToSnapshot(event: FeedbackEvent): DelegationFeedbackSnapshot {\n const snap: DelegationFeedbackSnapshot = {\n id: event.id,\n score: event.rating.score,\n by: event.by,\n notes: event.rating.notes,\n capturedAt: event.capturedAt,\n }\n if (event.rating.label) snap.label = event.rating.label\n return snap\n}\n","/**\n *\n * State machine for async MCP delegations:\n *\n * pending → running → completed | failed\n * ↘ cancelled (from any non-terminal state via cancel())\n *\n * Each `submit` returns a `taskId` immediately and kicks the work off in the\n * background. The work function receives an `AbortSignal` the queue fires\n * when `cancel(taskId)` is called. The queue does NOT supervise runtime\n * timeouts — the underlying `runAgentRounds` driver / sandbox imposes those.\n *\n * Idempotency: callers may supply an `idempotencyKey` (hash of the input).\n * A duplicate `submit` with a known key returns the existing task instead of\n * starting a new one. Mutated input → different key → different task.\n *\n * Durability: the working set lives in memory (reads stay synchronous) and\n * every record mutation is journaled through a `DelegationStore`. The default\n * `InMemoryDelegationStore` keeps today's semantics — a process restart drops\n * all state. Construct via `DelegationTaskQueue.restore({ store })` with a\n * `FileDelegationStore` to reload prior records on startup: terminal records\n * stay queryable, in-flight records either re-attach through the\n * `resumeDelegate` seam (when they carry a `detachedSessionRef`) or fail\n * loud with a driver-restart error so `delegation_status` tells the truth.\n *\n * @stable\n */\n\nimport { ValidationError } from '../errors'\nimport type { LoopTraceEmitter } from '../runtime/types'\nimport { fnv1a32Hex } from '../runtime/util'\nimport {\n DelegationPersistenceError,\n type DelegationStore,\n InMemoryDelegationStore,\n} from './delegation-store'\nimport {\n capDelegationTrace,\n createDelegationTraceCollector,\n type DelegationTraceSpan,\n generateDelegationSpanId,\n} from './delegation-trace'\nimport type { TraceContext } from './trace-propagation'\nimport type {\n DelegateCodeArgs,\n DelegateResearchArgs,\n DelegateUiAuditArgs,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusResult,\n} from './types'\n\n/** Arguments accepted by the durable delegation queue. @stable */\nexport type DelegationArgs = DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs\n\n/**\n * Must be JSON-safe end to end (`args`, `result`, `error`, `feedback`) —\n * persistent stores round-trip records through `JSON.stringify`.\n *\n * @stable\n */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegationArgs\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Sha-prefix hash of the canonical input — used for idempotency lookup. */\n idempotencyKey?: string\n /**\n * Caller-generated deterministic id of a detached run (e.g. the sandbox\n * session id a single-tick driver resumes by). Presence is what makes a\n * restored in-flight record resumable via `resumeDelegate`; without it a\n * restart settles the record as failed.\n */\n detachedSessionRef?: string\n /** Feedback events keyed by this delegation's taskId. */\n feedback: DelegationFeedbackSnapshot[]\n /**\n * Compact loop-trace span tree teed from the delegation's run, oldest\n * spans first. Appended when a delegated loop reaches `loop.ended` and\n * settled (partial buffers included) at the terminal transition. Capped\n * via `capDelegationTrace` — see `traceTruncated`.\n */\n trace?: DelegationTraceSpan[]\n /** Present when oldest trace spans were dropped to honor the trace caps. */\n traceTruncated?: true\n /**\n * Inherited trace identity (the queue's `traceContext` at submit time —\n * typically `readTraceContextFromEnv()`), distinct from the span payload:\n * a journal consumer joins records into the parent trace by these ids\n * without parsing spans. Restored records keep their persisted identity.\n */\n traceId?: string\n /** Caller span that dispatched the delegation, when one was inherited. */\n parentSpanId?: string\n}\n\n/** @stable */\nexport interface SubmitInput<Args extends DelegationArgs> {\n profile: DelegationProfile\n args: Args\n namespace?: string\n idempotencyKey?: string\n /**\n * Records the detached-run resume key on the new record. The submitted\n * `run` function still executes in-process exactly as without it — the\n * ref only matters after a restart, when `DelegationTaskQueue.restore`\n * hands it to the `resumeDelegate` seam instead of failing the record.\n */\n detachedSessionRef?: string\n /**\n * Runs the underlying delegation. The queue passes a fresh `AbortSignal`\n * and a `report` channel for incremental progress updates. The function\n * MUST resolve with the typed `DelegationResultPayload['output']`; the\n * queue wraps it with the profile tag.\n */\n run: (ctx: DelegationRunContext) => Promise<DelegationResultPayload['output']>\n}\n\n/** @stable Context handed to a `SubmitInput.run` function. */\nexport interface DelegationRunContext {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n /** The `detachedSessionRef` recorded at submit, when one was supplied. */\n detachedSessionRef?: string\n /**\n * Replace the record's detached-run resume key — the detached dispatch path\n * calls this once the sandbox id is known so the persisted ref names a\n * resolvable box. Ignored after the record settles (a cancel racing the\n * rebind is legitimate; the ref no longer matters then). Throws on an empty\n * ref — erasing the resume key would silently make the record unresumable.\n */\n updateDetachedSessionRef(ref: string): void\n /**\n * Per-delegation loop-trace sink, always provided by the queue. Events\n * emitted here are journaled onto the record as a compact span tree\n * (`record.trace`) when each loop run ends and at the delegation's\n * terminal transition. Delegates forward it into their `runAgentRounds` ctx,\n * composed with any process-wide OTEL emitter\n * (`composeLoopTraceEmitters`). Optional in the type so consumer-built\n * contexts stay source-compatible.\n */\n traceEmitter?: LoopTraceEmitter\n}\n\n/** @stable */\nexport interface SubmitOutput {\n taskId: string\n /** True when a prior matching `idempotencyKey` returned an existing record. */\n reused: boolean\n}\n\n/**\n * One observation of a detached run, mapped 1:1 from a single-tick driver\n * (e.g. the sandbox SDK's `driveTurn`, which reports\n * completed | running | failed per pass). `running` schedules another tick\n * after `intervalMs`; `completed` / `failed` settle the record.\n *\n * @stable\n */\nexport type DelegationResumeTick =\n | { state: 'running' }\n | { state: 'completed'; output: DelegationResultPayload['output']; costUsd?: number }\n | { state: 'failed'; error: DelegationError }\n\n/** @stable */\nexport interface DelegationResumeContext {\n /** Fired by `cancel(taskId)`; the driver should stop the remote run when it can. */\n signal: AbortSignal\n report(progress: DelegationProgress): void\n}\n\n/**\n * Re-attaches restored in-flight records to their detached runs. The queue\n * calls `tick` repeatedly — it never awaits a whole run — so the driver can\n * be a thin wrapper over a one-pass primitive: resolve the run named by\n * `detachedSessionRef`, advance/poll it once, report where it stands. A\n * thrown error settles the record as failed; `failed` ticks are treated as\n * terminal and are not retried.\n *\n * @stable\n */\nexport interface DelegationResumeDriver {\n tick(\n task: { record: DelegationRecord; detachedSessionRef: string },\n ctx: DelegationResumeContext,\n ): Promise<DelegationResumeTick>\n /** Delay between `running` ticks, in milliseconds. Default 5000. */\n intervalMs?: number\n}\n\n/** @stable */\nexport interface DelegationTaskQueueOptions {\n /** ID generator override; default `randomTaskId`. */\n generateId?: () => string\n /** Clock override; default `() => new Date().toISOString()`. */\n now?: () => string\n /**\n * Journal for record mutations and the `restore()` load source. Default\n * `InMemoryDelegationStore` — observably identical to an unjournaled\n * queue. Pass a `FileDelegationStore` through\n * `DelegationTaskQueue.restore` for state that survives a restart;\n * constructing with `new` never loads prior state.\n */\n store?: DelegationStore\n /** Resume seam for restored in-flight records that carry a `detachedSessionRef`. */\n resumeDelegate?: DelegationResumeDriver\n /**\n * Maximum number of terminal (completed | failed | cancelled) records\n * retained; the oldest (by `completedAt`) are evicted from memory and\n * store once the cap is exceeded. Default unbounded.\n */\n maxTerminalRecords?: number\n /**\n * Observes the first store failure. After it fires, the queue refuses\n * new submissions and `flush()` rejects with the same error. Default:\n * rethrow on a microtask — an unhandled crash — because silently\n * degrading durable mode to memory-only would lie to the caller.\n */\n onPersistError?: (error: DelegationPersistenceError) => void\n /**\n * Inherited trace identity stamped on every submitted record\n * (`traceId` / `parentSpanId`). The bin passes\n * `readTraceContextFromEnv()` so journal consumers can join delegation\n * records into the caller's trace. Restored records keep the identity\n * they were persisted with.\n */\n traceContext?: TraceContext\n}\n\n/** In-process queue for async delegation tasks — submit, cancel, poll status, and read history. @stable */\nexport class DelegationTaskQueue {\n private readonly records = new Map<string, DelegationRecord>()\n private readonly controllers = new Map<string, AbortController>()\n private readonly byIdempotencyKey = new Map<string, string>()\n private readonly generateId: () => string\n private readonly now: () => string\n private readonly store: DelegationStore\n private readonly resumeDelegate?: DelegationResumeDriver\n private readonly maxTerminalRecords: number\n private readonly onPersistError: (error: DelegationPersistenceError) => void\n private readonly traceContext: TraceContext | undefined\n private persistTail: Promise<void> = Promise.resolve()\n private persistFailure: DelegationPersistenceError | undefined\n\n constructor(options: DelegationTaskQueueOptions = {}) {\n this.generateId = options.generateId ?? randomTaskId\n this.now = options.now ?? (() => new Date().toISOString())\n this.store = options.store ?? new InMemoryDelegationStore()\n this.resumeDelegate = options.resumeDelegate\n if (options.maxTerminalRecords !== undefined) {\n if (!Number.isInteger(options.maxTerminalRecords) || options.maxTerminalRecords < 1) {\n throw new ValidationError(\n `DelegationTaskQueue: maxTerminalRecords must be a positive integer, got ${String(options.maxTerminalRecords)}`,\n )\n }\n }\n this.maxTerminalRecords = options.maxTerminalRecords ?? Number.POSITIVE_INFINITY\n this.traceContext = options.traceContext\n this.onPersistError =\n options.onPersistError ??\n ((error) => {\n queueMicrotask(() => {\n throw error\n })\n })\n }\n\n /**\n * Construct a queue from previously-persisted state. Loads every record\n * from `options.store`, rebuilds the idempotency index (so a re-submitted\n * identical task returns the prior taskId and its terminal state), then:\n *\n * - terminal records stay queryable via `status()` / `history()`\n * - in-flight records with a `detachedSessionRef` re-attach through\n * `options.resumeDelegate` and report `running`\n * - other in-flight records settle as failed — their driver died with\n * the previous process and the result is unrecoverable\n *\n * The retention cap applies to the loaded set as well.\n */\n static async restore(options: DelegationTaskQueueOptions = {}): Promise<DelegationTaskQueue> {\n const queue = new DelegationTaskQueue(options)\n const loaded = await queue.store.loadAll()\n await queue.rehydrate(loaded)\n return queue\n }\n\n /**\n * Kick off a delegation in the background. Returns immediately. The\n * `taskId` is queryable via `status` once this method returns. Throws\n * the recorded `DelegationPersistenceError` once the store has failed —\n * the queue does not accept work it cannot journal.\n */\n submit<Args extends DelegationArgs>(input: SubmitInput<Args>): SubmitOutput {\n if (this.persistFailure) throw this.persistFailure\n if (input.idempotencyKey) {\n const existing = this.byIdempotencyKey.get(input.idempotencyKey)\n if (existing && this.records.has(existing)) {\n return { taskId: existing, reused: true }\n }\n }\n const taskId = this.generateId()\n const controller = new AbortController()\n const record: DelegationRecord = {\n taskId,\n profile: input.profile,\n namespace: input.namespace,\n args: input.args,\n status: 'pending',\n startedAt: this.now(),\n feedback: [],\n idempotencyKey: input.idempotencyKey,\n detachedSessionRef: input.detachedSessionRef,\n ...(this.traceContext !== undefined\n ? {\n traceId: this.traceContext.traceId,\n ...(this.traceContext.parentSpanId !== undefined\n ? { parentSpanId: this.traceContext.parentSpanId }\n : {}),\n }\n : {}),\n }\n this.records.set(taskId, record)\n this.controllers.set(taskId, controller)\n if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId)\n this.persist(record)\n\n // Fire-and-forget the run function. Errors flow into the record so the\n // status poll surfaces them; the promise itself is intentionally\n // unobserved by the queue.\n queueMicrotask(() => {\n this.execute(taskId, input, controller)\n })\n\n return { taskId, reused: false }\n }\n\n /**\n * Snapshot the current state of a delegation. Returns `undefined` for\n * unknown ids so callers can distinguish missing from terminal.\n * `includeTrace` attaches the journaled loop-trace span tree — off by\n * default so status polls stay light.\n */\n status(taskId: string, opts?: { includeTrace?: boolean }): DelegationStatusResult | undefined {\n const record = this.records.get(taskId)\n if (!record) return undefined\n return toStatusResult(record, opts)\n }\n\n /**\n * Abort an in-flight delegation. Returns `false` if the task is unknown\n * or already terminal. The underlying `run` function MUST honor the\n * abort signal for the cancel to take effect; the queue marks the\n * record `cancelled` regardless so a misbehaving runner cannot pin the\n * UI on `running` forever.\n */\n cancel(taskId: string): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n if (isTerminal(record.status)) return false\n const controller = this.controllers.get(taskId)\n controller?.abort()\n record.status = 'cancelled'\n record.completedAt = this.now()\n record.error = { message: 'cancelled by caller', kind: 'CancelledError' }\n this.persist(record)\n this.enforceRetention()\n return true\n }\n\n /**\n * Append a feedback event to the matching delegation. Returns `false`\n * when `ref` does not name a known taskId — the caller should still\n * record the feedback through a different surface (artifact/outcome\n * kinds are not queue-bound).\n */\n attachFeedback(taskId: string, snapshot: DelegationFeedbackSnapshot): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n record.feedback.push(snapshot)\n this.persist(record)\n return true\n }\n\n /**\n * Query the recorded delegations. Returns entries newest-first (by\n * `startedAt`), truncated to `limit`.\n */\n history(args: DelegationHistoryArgs = {}): DelegationHistoryEntry[] {\n const limit = clampLimit(args.limit)\n const since = args.since ? Date.parse(args.since) : Number.NEGATIVE_INFINITY\n const out: DelegationHistoryEntry[] = []\n for (const record of this.records.values()) {\n if (args.namespace && record.namespace !== args.namespace) continue\n if (args.profile && record.profile !== args.profile) continue\n if (Number.isFinite(since) && Date.parse(record.startedAt) < since) continue\n out.push(toHistoryEntry(record))\n }\n out.sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n return out.slice(0, limit)\n }\n\n /**\n * Await every journal write issued so far. Rejects with the recorded\n * `DelegationPersistenceError` when any of them failed. Call before\n * handing the store's backing file to another process.\n */\n async flush(): Promise<void> {\n // Drain to quiescence: a write that completes while we await the tail can\n // chain another (the resume loop persisting a settle, a late `report`,\n // retention removals). Awaiting a single snapshot of `persistTail` would\n // miss those follow-on writes, letting a `store.upsert` land after the\n // caller has torn the backing dir down. Re-await until the tail stops\n // advancing.\n let tail: typeof this.persistTail | undefined\n while (this.persistTail !== tail) {\n tail = this.persistTail\n await tail\n }\n if (this.persistFailure) throw this.persistFailure\n }\n\n /** Test-only — number of in-flight (non-terminal) records. */\n inflightCount(): number {\n let n = 0\n for (const record of this.records.values()) {\n if (!isTerminal(record.status)) n += 1\n }\n return n\n }\n\n private async execute<Args extends DelegationArgs>(\n taskId: string,\n input: SubmitInput<Args>,\n controller: AbortController,\n ): Promise<void> {\n const record = this.records.get(taskId)\n if (!record) return\n record.status = 'running'\n this.persist(record)\n // Journal tee: each finished loop run inside the delegation appends its\n // compact span tree to the record immediately (a long delegation's trace\n // is durable before the terminal transition); `settle()` below drains\n // partial buffers from runs that never reached `loop.ended`.\n const traceCollector = createDelegationTraceCollector((spans) => {\n if (isTerminal(currentStatus(record))) return\n this.appendTrace(record, spans)\n this.persist(record)\n })\n try {\n const output = await input.run({\n signal: controller.signal,\n report: (progress) => {\n if (record.status === 'running') {\n record.progress = progress\n this.persist(record)\n }\n },\n traceEmitter: traceCollector.emitter,\n ...(record.detachedSessionRef !== undefined\n ? { detachedSessionRef: record.detachedSessionRef }\n : {}),\n updateDetachedSessionRef: (ref) => {\n if (typeof ref !== 'string' || ref.length === 0) {\n throw new ValidationError(\n 'DelegationTaskQueue: updateDetachedSessionRef requires a non-empty ref',\n )\n }\n if (isTerminal(currentStatus(record))) return\n record.detachedSessionRef = ref\n this.persist(record)\n },\n })\n traceCollector.settle()\n // `cancel()` may have flipped the status to `cancelled` while the\n // run promise was pending. Read the field through a widening\n // helper so the narrowed `'running'` type from the assignment\n // above does not exclude that case at compile time.\n if (currentStatus(record) === 'cancelled') return\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = { profile: input.profile, output } as DelegationResultPayload\n this.persist(record)\n this.enforceRetention()\n } catch (err) {\n traceCollector.settle()\n if (currentStatus(record) === 'cancelled') return\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(taskId)\n }\n }\n\n private appendTrace(record: DelegationRecord, spans: DelegationTraceSpan[]): void {\n if (spans.length === 0) return\n const { trace, truncated } = capDelegationTrace([...(record.trace ?? []), ...spans])\n record.trace = trace\n if (truncated) record.traceTruncated = true\n }\n\n private async rehydrate(loaded: DelegationRecord[]): Promise<void> {\n const records = [...loaded].sort((a, b) => a.startedAt.localeCompare(b.startedAt))\n for (const record of records) {\n this.records.set(record.taskId, record)\n if (record.idempotencyKey) this.byIdempotencyKey.set(record.idempotencyKey, record.taskId)\n }\n const restoreWrites: Promise<void>[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) continue\n if (record.detachedSessionRef && this.resumeDelegate) {\n record.status = 'running'\n restoreWrites.push(this.persist(record))\n this.startResume(record, record.detachedSessionRef, this.resumeDelegate)\n continue\n }\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = {\n message: record.detachedSessionRef\n ? `delegation driver restarted while the task was in flight; detached session \"${record.detachedSessionRef}\" needs a resumeDelegate to be resumed`\n : 'delegation driver restarted while the task was in flight; the run was not detached and cannot be resumed',\n kind: 'DriverRestartError',\n }\n restoreWrites.push(this.persist(record))\n }\n const retentionWrite = this.enforceRetention()\n if (retentionWrite) restoreWrites.push(retentionWrite)\n await Promise.all(restoreWrites)\n if (this.persistFailure) throw this.persistFailure\n }\n\n private startResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n ): void {\n const controller = new AbortController()\n this.controllers.set(record.taskId, controller)\n void this.driveResume(record, detachedSessionRef, driver, controller)\n }\n\n private async driveResume(\n record: DelegationRecord,\n detachedSessionRef: string,\n driver: DelegationResumeDriver,\n controller: AbortController,\n ): Promise<void> {\n const intervalMs = driver.intervalMs ?? 5000\n const resumeStartMs = Date.parse(this.now())\n const ctx: DelegationResumeContext = {\n signal: controller.signal,\n report: (progress) => {\n if (currentStatus(record) !== 'running') return\n record.progress = progress\n this.persist(record)\n },\n }\n try {\n while (!controller.signal.aborted && currentStatus(record) === 'running') {\n const tick = await driver.tick({ record: structuredClone(record), detachedSessionRef }, ctx)\n if (currentStatus(record) === 'cancelled') return\n if (tick.state === 'completed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs)\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = {\n profile: record.profile,\n output: tick.output,\n } as DelegationResultPayload\n if (tick.costUsd !== undefined) record.costUsd = tick.costUsd\n this.persist(record)\n this.enforceRetention()\n return\n }\n if (tick.state === 'failed') {\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, tick.error.message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = tick.error\n this.persist(record)\n this.enforceRetention()\n return\n }\n await abortableDelay(intervalMs, controller.signal)\n }\n } catch (err) {\n if (currentStatus(record) === 'cancelled') return\n this.appendResumeSpan(record, detachedSessionRef, resumeStartMs, errorToShape(err).message)\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n this.persist(record)\n this.enforceRetention()\n } finally {\n this.controllers.delete(record.taskId)\n }\n }\n\n /**\n * Journal the resumed segment of a detached run as one compact span. The\n * resume driver re-attaches after a process restart, so the original\n * process's loop events are gone — this span records the post-restart\n * observation window (re-attach → terminal tick) under the\n * `'detached-resume'` driver tag, keeping restored delegations observable\n * in the journal alongside trace-carrying live runs.\n */\n private appendResumeSpan(\n record: DelegationRecord,\n detachedSessionRef: string,\n startMs: number,\n error?: string,\n ): void {\n this.appendTrace(record, [\n {\n spanId: generateDelegationSpanId(),\n name: 'loop',\n kind: 'loop',\n startMs,\n endMs: Date.parse(this.now()),\n meta: {\n 'tangle.loop.driver': 'detached-resume',\n 'tangle.loop.detached_session_ref': detachedSessionRef,\n ...(error !== undefined ? { 'tangle.loop.error': error } : {}),\n },\n },\n ])\n }\n\n private persist(record: DelegationRecord): Promise<void> {\n if (this.persistFailure) return Promise.resolve()\n const snapshot = structuredClone(record)\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.upsert(snapshot)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private persistRemoval(taskIds: string[]): Promise<void> | undefined {\n if (this.persistFailure || taskIds.length === 0) return undefined\n this.persistTail = this.persistTail.then(async () => {\n if (this.persistFailure) return\n try {\n await this.store.remove(taskIds)\n } catch (err) {\n this.failPersistence(err)\n }\n })\n return this.persistTail\n }\n\n private failPersistence(cause: unknown): void {\n if (this.persistFailure) return\n const error =\n cause instanceof DelegationPersistenceError\n ? cause\n : new DelegationPersistenceError(\n `DelegationTaskQueue: store write failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n this.persistFailure = error\n this.onPersistError(error)\n }\n\n private enforceRetention(): Promise<void> | undefined {\n if (!Number.isFinite(this.maxTerminalRecords)) return undefined\n const terminal: DelegationRecord[] = []\n for (const record of this.records.values()) {\n if (isTerminal(record.status)) terminal.push(record)\n }\n const excess = terminal.length - this.maxTerminalRecords\n if (excess <= 0) return undefined\n terminal.sort((a, b) =>\n (a.completedAt ?? a.startedAt).localeCompare(b.completedAt ?? b.startedAt),\n )\n const evicted = terminal.slice(0, excess)\n for (const record of evicted) {\n this.records.delete(record.taskId)\n if (\n record.idempotencyKey &&\n this.byIdempotencyKey.get(record.idempotencyKey) === record.taskId\n ) {\n this.byIdempotencyKey.delete(record.idempotencyKey)\n }\n }\n return this.persistRemoval(evicted.map((record) => record.taskId))\n }\n}\n\nfunction isTerminal(status: DelegationStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled'\n}\n\nfunction currentStatus(record: DelegationRecord): DelegationStatus {\n return record.status\n}\n\nfunction clampLimit(raw: number | undefined): number {\n if (!Number.isFinite(raw)) return 50\n const n = Math.trunc(raw as number)\n if (n <= 0) return 50\n return Math.min(n, 500)\n}\n\nfunction abortableDelay(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal.aborted) {\n resolve()\n return\n }\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nfunction toStatusResult(\n record: DelegationRecord,\n opts?: { includeTrace?: boolean },\n): DelegationStatusResult {\n const out: DelegationStatusResult = {\n taskId: record.taskId,\n profile: record.profile,\n status: record.status,\n startedAt: record.startedAt,\n }\n if (record.progress) out.progress = record.progress\n if (record.result) out.result = record.result\n if (record.error) out.error = record.error\n if (record.costUsd !== undefined) out.costUsd = record.costUsd\n if (record.completedAt) out.completedAt = record.completedAt\n if (record.traceId !== undefined) out.traceId = record.traceId\n if (record.parentSpanId !== undefined) out.parentSpanId = record.parentSpanId\n if (opts?.includeTrace === true && record.trace && record.trace.length > 0) {\n out.trace = record.trace.map((span) => ({ ...span }))\n if (record.traceTruncated) out.traceTruncated = true\n }\n return out\n}\n\nfunction toHistoryEntry(record: DelegationRecord): DelegationHistoryEntry {\n const entry: DelegationHistoryEntry = {\n taskId: record.taskId,\n profile: record.profile,\n args: record.args,\n status: record.status,\n startedAt: record.startedAt,\n hasTrace: record.trace !== undefined && record.trace.length > 0,\n }\n if (record.namespace) entry.namespace = record.namespace\n if (record.completedAt) entry.completedAt = record.completedAt\n if (record.costUsd !== undefined) entry.costUsd = record.costUsd\n if (record.feedback.length > 0) entry.feedback = [...record.feedback]\n if (record.traceId !== undefined) entry.traceId = record.traceId\n return entry\n}\n\nfunction errorToShape(err: unknown): DelegationError {\n if (err instanceof Error) {\n return { message: err.message, kind: err.name || 'Error' }\n }\n return { message: String(err), kind: 'NonError' }\n}\n\nfunction randomTaskId(): string {\n // Caller-stable id: `dlg-${timestamp}-${random}`. The timestamp portion\n // makes lexicographic sort match chronological order in history queries\n // even when the system clock skews under the second.\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `dlg-${t}-${r}`\n}\n\n/**\n * Best-effort stable hash for use as `idempotencyKey`. Not cryptographic;\n * collisions only affect dedupe, never correctness.\n *\n * @stable\n */\nexport function hashIdempotencyInput(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(canonicalize(value))\n } catch {\n str = String(value)\n }\n return fnv1a32Hex(str)\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n const out: Record<string, unknown> = {}\n for (const [k, v] of entries) out[k] = canonicalize(v)\n return out\n}\n\n// Re-exports re-used by the feedback-store + handler glue. Kept local so\n// consumers of the queue don't have to import from `./types` separately.\nexport type {\n DelegateUiAuditArgs,\n DelegateUiAuditResult,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\n} from './types'\n","/**\n *\n * `delegate` MCP tool — the ONE generic delegation verb, the agent-facing front door to\n * `delegate()` / `supervise()`. The agent hands it an INTENT (what it wants done); a default\n * authoring supervisor decomposes the intent and AUTHORS the worker profile it needs — there is no\n * hardcoded coder/researcher profile, so one verb covers code, research, and anything else.\n *\n * `delegate` is SYNCHRONOUS: it awaits the full supervised run and returns the delivered output\n * TOGETHER WITH `spentTotal` — the conserved cost of the whole delegation (`iterations` / `tokens` /\n * `usd` / `ms`), so the caller always learns what the delegation actually spent.\n *\n * The supervisor's substrate (its brain `router`, the worker `backend`, the completion `deliverable`)\n * is INJECTED at server construction — never an agent-supplied arg. The agent supplies only the\n * intent (+ an optional per-call `model` / `runId`).\n *\n * @stable\n */\n\nimport type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { RouterTransportConfig } from '../../runtime/router-http-transport'\nimport type { DeliverableSpec } from '../../runtime/supervise/completion-gate'\nimport { type DelegateOptions, delegate } from '../../runtime/supervise/delegate'\nimport type { ExecutorConfig } from '../../runtime/supervise/runtime'\nimport type { Spend, SupervisedResult } from '../../runtime/supervise/types'\n\n/** MCP tool name for the `delegate` generic-delegation tool. @stable */\nexport const DELEGATE_TOOL_NAME = 'delegate'\n\n/** Human-readable description of the `delegate` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATE_DESCRIPTION = [\n 'Delegate an INTENT to a supervisor that AUTHORS and drives whatever worker the intent needs.',\n '',\n 'Use when: you want a task done but do not want to specify HOW. State the outcome — \"fix the',\n 'failing auth test\", \"research competitor pricing with citations\", \"refactor the parser for',\n 'clarity\" — and the supervisor decomposes it, writes a tailored worker profile per sub-task, runs',\n 'the workers over a conserved compute budget, and settles only when a deployable check passes.',\n '',\n 'There is no fixed worker type: this ONE verb replaces separate code / research delegation. The',\n 'supervisor picks the worker shape from your intent.',\n '',\n 'Returns synchronously with the delivered result AND the real cost of the whole delegation',\n '(spentTotal: iterations, input/output tokens, usd, ms) — so you always know what it spent. A run',\n 'that produced no delivered worker returns status \"no-winner\" with the reason; it never fabricates',\n 'a success.',\n].join('\\n')\n\n/** JSON Schema for `delegate` tool arguments (`intent` + optional trace id). @stable */\nexport const DELEGATE_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n intent: {\n type: 'string',\n description: 'What you want accomplished, as an outcome. The supervisor authors the worker.',\n },\n runId: {\n type: 'string',\n description: 'Optional trace-correlation id for this delegation.',\n },\n },\n required: ['intent'],\n additionalProperties: false,\n} as const\n\n/** Parsed `delegate` tool arguments. */\ninterface DelegateArgs {\n intent: string\n runId?: string\n}\n\n/** Parse and validate raw MCP tool input into typed `DelegateArgs`; throws `TypeError` on bad input. @stable */\nfunction validateDelegateArgs(raw: unknown): DelegateArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const unknown = Object.keys(value).filter((key) => key !== 'intent' && key !== 'runId')\n if (unknown.length > 0) {\n throw new TypeError(`delegate: unknown arguments: ${unknown.join(', ')}`)\n }\n const intent = value.intent\n if (typeof intent !== 'string' || intent.trim().length === 0) {\n throw new TypeError('delegate: `intent` must be a non-empty string')\n }\n const args: DelegateArgs = { intent: intent.trim() }\n if (value.runId !== undefined) {\n if (typeof value.runId !== 'string') throw new TypeError('delegate: `runId` must be a string')\n args.runId = value.runId\n }\n return args\n}\n\n/** The synchronous result the `delegate` tool returns to the calling agent: the delivered output (or\n * the no-winner reason) PLUS the conserved spend of the whole delegation. */\nexport type DelegateResult =\n | { status: 'winner'; out: unknown; outRef: string; spentTotal: Spend }\n | { status: 'no-winner'; reason: string; error?: DelegateError; spentTotal: Spend }\n\n/** What killed a delegation, projected for the calling agent: the rejection's name and message.\n * `reason` is a four-word code (`driver-failed`), and a code alone is not diagnosable — the\n * supervisor attaches the rejection to the result precisely so a caller can read it. */\nexport interface DelegateError {\n name: string\n message: string\n}\n\n/** @stable */\nexport interface DelegateHandlerOptions {\n /** The supervisor brain's router substrate (REQUIRED — the default supervisor is router-brained). */\n router: RouterTransportConfig\n /** Exact executable supervisor identity selected by the trusted composition root. */\n supervisorProfile: AgentProfile\n /** WHERE the authored workers run. Required for `supervise()` to spawn anything. */\n backend: ExecutorConfig\n /** The completion oracle the authored workers settle against (settled ⟺ delivered). */\n deliverable?: DeliverableSpec\n /** Restrict the run to this subset of models. */\n allowedModels?: readonly string[]\n}\n\n/** Project a `SupervisedResult` onto the tool's flat `DelegateResult`. Both variants carry the real\n * conserved `spentTotal`, so the agent always learns the cost — even on a no-winner, never a faked\n * output and never a fabricated zero spend. */\nfunction toDelegateResult(result: SupervisedResult<unknown>): DelegateResult {\n if (result.kind === 'no-winner') {\n // `stack` stays behind: an agent reads a cause, not a frame list.\n const rejection = (result as { error?: { name?: unknown; message?: unknown } }).error\n const error: DelegateError | undefined =\n typeof rejection?.name === 'string' && typeof rejection.message === 'string'\n ? { name: rejection.name, message: rejection.message }\n : undefined\n return {\n status: 'no-winner',\n reason: result.reason,\n ...(error ? { error } : {}),\n spentTotal: result.spentTotal,\n }\n }\n return {\n status: 'winner',\n out: result.out,\n outRef: result.outRef,\n spentTotal: result.spentTotal,\n }\n}\n\n/**\n * Build the `delegate` tool handler. Closes over the injected supervisor substrate (`router` /\n * `backend` / `deliverable`); each call routes the agent's intent to `delegate()` and returns the\n * delivered output with its conserved cost.\n */\nexport function createDelegateHandler(\n options: DelegateHandlerOptions,\n): (raw: unknown) => Promise<DelegateResult> {\n return async (raw) => {\n const args = validateDelegateArgs(raw)\n const opts: DelegateOptions = {\n backend: options.backend,\n router: options.router,\n supervisorProfile: options.supervisorProfile,\n ...(options.deliverable ? { deliverable: options.deliverable } : {}),\n ...(options.allowedModels ? { allowedModels: options.allowedModels } : {}),\n ...(args.runId ? { runId: args.runId } : {}),\n }\n const result = await delegate(args.intent, opts)\n return toDelegateResult(result)\n }\n}\n","/**\n *\n * `delegate_feedback` MCP tool — synchronous record of agent / user /\n * downstream-judge feedback on a delegation, artifact, or outcome.\n *\n * The store is append-only. Every rating is its own event; no dedupe.\n * When `refersTo.kind === 'delegation'`, the snapshot is also attached\n * to the matching queue record so `delegation_history` surfaces it\n * inline without a join.\n *\n * @stable\n */\n\nimport type { FeedbackStore } from '../feedback-store'\nimport { eventToSnapshot } from '../feedback-store'\nimport type { DelegationTaskQueue } from '../task-queue'\nimport type {\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n FeedbackRating,\n FeedbackRefersTo,\n} from '../types'\n\n/** MCP tool name for the `delegate_feedback` feedback-recording tool. @stable */\nexport const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback'\n\n/** Human-readable description of the `delegate_feedback` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATE_FEEDBACK_DESCRIPTION = [\n 'Record feedback on a delegation, artifact, or outcome. Synchronous — the',\n 'event is durably stored when this call returns.',\n '',\n 'Use when: you (the agent), the user, or a downstream judge has formed an',\n 'opinion about a piece of work and want it persisted for calibration,',\n 'pricing, or future routing. Every call is a new event — multiple ratings',\n 'on the same target are expected and never deduped.',\n '',\n '`refersTo.kind`:',\n ' - \"delegation\": ref is a taskId returned by delegate_ui_audit',\n ' - \"artifact\": ref is a URI/path/git-sha — anything you can dereference',\n ' - \"outcome\": ref is a free-form description of a downstream result',\n '',\n '`by`:',\n ' - \"agent\": the agent itself rated the work',\n ' - \"user\": the human user rated it',\n ' - \"downstream-judge\": an automated evaluator emitted the rating',\n '',\n 'When ref names a known taskId, the rating is also attached to the',\n 'delegation record so delegation_history surfaces it inline.',\n].join('\\n')\n\n/** JSON Schema for `delegate_feedback` tool arguments (`refersTo`, `rating`, `by`, optional fields). @stable */\nexport const DELEGATE_FEEDBACK_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n refersTo: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['delegation', 'artifact', 'outcome'] },\n ref: { type: 'string' },\n },\n required: ['kind', 'ref'],\n additionalProperties: false,\n },\n rating: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n label: { type: 'string', enum: ['good', 'bad', 'neutral', 'mixed'] },\n notes: { type: 'string' },\n },\n required: ['score', 'notes'],\n additionalProperties: false,\n },\n by: { type: 'string', enum: ['agent', 'user', 'downstream-judge'] },\n capturedAt: { type: 'string' },\n namespace: { type: 'string' },\n },\n required: ['refersTo', 'rating', 'by'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegateFeedbackArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegateFeedbackArgs(raw: unknown): DelegateFeedbackArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const refersTo = validateRefersTo(value.refersTo)\n const rating = validateRating(value.rating)\n const by = value.by\n if (by !== 'agent' && by !== 'user' && by !== 'downstream-judge') {\n throw new TypeError(\n 'delegate_feedback: `by` must be one of \"agent\" | \"user\" | \"downstream-judge\"',\n )\n }\n const args: DelegateFeedbackArgs = { refersTo, rating, by }\n if (value.capturedAt !== undefined) {\n if (typeof value.capturedAt !== 'string' || Number.isNaN(Date.parse(value.capturedAt))) {\n throw new TypeError('delegate_feedback: `capturedAt` must be an ISO datetime')\n }\n args.capturedAt = value.capturedAt\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateRefersTo(raw: unknown): FeedbackRefersTo {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `refersTo` must be an object')\n }\n const value = raw as Record<string, unknown>\n const kind = value.kind\n if (kind !== 'delegation' && kind !== 'artifact' && kind !== 'outcome') {\n throw new TypeError(\n 'delegate_feedback: `refersTo.kind` must be one of \"delegation\" | \"artifact\" | \"outcome\"',\n )\n }\n const ref = value.ref\n if (typeof ref !== 'string' || ref.trim().length === 0) {\n throw new TypeError('delegate_feedback: `refersTo.ref` must be a non-empty string')\n }\n return { kind, ref: ref.trim() }\n}\n\nfunction validateRating(raw: unknown): FeedbackRating {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `rating` must be an object')\n }\n const value = raw as Record<string, unknown>\n const score = Number(value.score)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new RangeError('delegate_feedback: `rating.score` must be a number in [0, 1]')\n }\n const notes = value.notes\n if (typeof notes !== 'string') {\n throw new TypeError('delegate_feedback: `rating.notes` must be a string')\n }\n const rating: FeedbackRating = { score, notes }\n const label = value.label\n if (label !== undefined) {\n if (label !== 'good' && label !== 'bad' && label !== 'neutral' && label !== 'mixed') {\n throw new TypeError(\n 'delegate_feedback: `rating.label` must be one of \"good\" | \"bad\" | \"neutral\" | \"mixed\"',\n )\n }\n rating.label = label\n }\n return rating\n}\n\n/** @stable */\ninterface DelegateFeedbackHandlerOptions {\n queue: DelegationTaskQueue\n store: FeedbackStore\n generateId?: () => string\n now?: () => string\n}\n\n/** Build the MCP tool handler that persists feedback events and attaches them to delegation records. @stable */\nexport function createDelegateFeedbackHandler(\n options: DelegateFeedbackHandlerOptions,\n): (raw: unknown) => Promise<DelegateFeedbackResult> {\n const generateId = options.generateId ?? randomFeedbackId\n const now = options.now ?? (() => new Date().toISOString())\n return async (raw) => {\n const args = validateDelegateFeedbackArgs(raw)\n const id = generateId()\n const event = {\n id,\n refersTo: args.refersTo,\n rating: args.rating,\n by: args.by,\n capturedAt: args.capturedAt ?? now(),\n namespace: args.namespace,\n }\n await options.store.put(event)\n if (args.refersTo.kind === 'delegation') {\n options.queue.attachFeedback(args.refersTo.ref, eventToSnapshot(event))\n }\n return { recorded: true, id }\n }\n}\n\nfunction randomFeedbackId(): string {\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `fbk-${t}-${r}`\n}\n","/**\n *\n * `delegate_ui_audit` MCP tool — async kickoff for UI audit runs. Validates\n * the input, computes an idempotency key over the canonical fields, hands\n * the task to the queue, and returns a taskId. Identical inputs return\n * the same taskId.\n *\n * The handler does not import the auditor profile directly — consumers\n * inject a `UiAuditorDelegate` via `createMcpServer({ uiAuditorDelegate })`.\n * The delegate is the seam where the consumer chooses the judge (vision\n * model) and the `SandboxClient` (in-process Playwright vs fleet vs\n * remote browser). agent-runtime ships the in-process client under\n * `./profiles` so consumers who want the canonical setup can wire it\n * with a few lines.\n *\n * @experimental\n */\n\nimport path from 'node:path'\nimport { UI_LENSES, type UiLens } from '../../profiles/ui-auditor/substrate'\nimport type { UiAuditorDelegate } from '../delegates'\nimport {\n type DelegateUiAuditArgs,\n type DelegateUiAuditResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\n\n/** MCP tool name for the `delegate_ui_audit` async kickoff tool. @experimental */\nexport const DELEGATE_UI_AUDIT_TOOL_NAME = 'delegate_ui_audit'\n\n/** Human-readable description of the `delegate_ui_audit` MCP tool, injected into the tool manifest. @experimental */\nexport const DELEGATE_UI_AUDIT_DESCRIPTION = [\n 'Delegate a UI/UX audit to a vision-driven auditor that produces self-contained',\n 'GitHub-issue-ready Markdown findings — one file per finding, with embedded',\n 'screenshot evidence and a suggested fix.',\n '',\n 'Use when: you want a thorough pass over a running web app for consistency,',\n 'hierarchy, layout, ux-flow, duplication, accessibility, responsive, states,',\n 'content, interaction, or perceived-performance issues. The auditor iterates',\n 'lens-by-lens so each pass finds new classes of issues; the workspace registry',\n 'deduplicates across iterations.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'workspace path + indexed findings (typically minutes per audited route).',\n 'Identical inputs return the same taskId — safe to retry.',\n '',\n 'Output layout under workspaceDir:',\n ' registry.json — finding index + capture sidecar',\n ' index.md — human-readable rollup',\n ' issues/NNN--<lens>--<slug>.md — one self-contained GitHub-issue',\n ' screenshots/<route>--<viewport>.png — capture archive',\n '',\n 'Multi-tenant isolation: every finding is scoped to `namespace` when set.',\n \"Never pass another tenant's namespace.\",\n].join('\\n')\n\nconst VIEWPORT_SCHEMA = {\n type: 'object',\n properties: {\n width: { type: 'integer', minimum: 1 },\n height: { type: 'integer', minimum: 1 },\n },\n required: ['width', 'height'],\n additionalProperties: false,\n} as const\n\nconst ROUTE_SCHEMA = {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Stable route name (used in screenshot filenames).' },\n url: { type: 'string', description: 'Fully-qualified URL.' },\n viewports: {\n type: 'array',\n items: VIEWPORT_SCHEMA,\n description: 'Viewports to capture at. Default [{1280, 800}].',\n },\n fullPage: { type: 'boolean' },\n waitFor: { type: 'string', description: 'CSS selector to wait for before capturing.' },\n },\n required: ['name', 'url'],\n additionalProperties: false,\n} as const\n\n/** JSON Schema for `delegate_ui_audit` tool arguments (`workspaceDir`, `routes`, optional config). @experimental */\nexport const DELEGATE_UI_AUDIT_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n workspaceDir: { type: 'string', description: 'Absolute path for the audit workspace.' },\n routes: { type: 'array', items: ROUTE_SCHEMA, minItems: 1 },\n namespace: { type: 'string', description: 'Multi-tenant scope.' },\n config: {\n type: 'object',\n properties: {\n lenses: {\n type: 'array',\n items: { type: 'string', enum: [...UI_LENSES] },\n description: 'Lenses to iterate. Default: every lens except \"other\".',\n },\n maxIterations: { type: 'integer', minimum: 1 },\n maxConcurrency: { type: 'integer', minimum: 1 },\n productContext: { type: 'string' },\n },\n additionalProperties: false,\n },\n },\n required: ['workspaceDir', 'routes'],\n additionalProperties: false,\n} as const\n\nconst PER_LENS_PER_ROUTE_ESTIMATE_MS = 45_000\n\n/** Parse and validate raw MCP tool input into typed `DelegateUiAuditArgs`; throws `TypeError` on bad input. @experimental */\nexport function validateDelegateUiAuditArgs(raw: unknown): DelegateUiAuditArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const workspaceDir = value.workspaceDir\n if (typeof workspaceDir !== 'string' || workspaceDir.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `workspaceDir` must be a non-empty string')\n }\n // Reject relative paths at the boundary. Without this, the writer joins a\n // relative workspaceDir against the process CWD, so the same MCP call\n // produces different file layouts depending on where the server was\n // launched — a silent fail-loud violation for a public API.\n const trimmedWs = workspaceDir.trim()\n if (!path.isAbsolute(trimmedWs)) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must be an absolute path (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n // Reject `..` segments. An absolute path like `/tmp/../../etc` passes\n // `isAbsolute`, then `path.join(workspaceDir, 'issues', …)` normalises it\n // to `/etc/issues/…`, escaping the intended workspace. Check the RAW\n // input split on the platform separator; `path.resolve` already collapses\n // `..` and would silently launder a traversal attempt past us.\n if (trimmedWs.split(path.sep).includes('..')) {\n throw new TypeError(\n `delegate_ui_audit: \\`workspaceDir\\` must not contain '..' segments (got ${JSON.stringify(workspaceDir)})`,\n )\n }\n const routesRaw = value.routes\n if (!Array.isArray(routesRaw) || routesRaw.length === 0) {\n throw new TypeError('delegate_ui_audit: `routes` must be a non-empty array')\n }\n const routes = routesRaw.map((r, i) => validateRoute(r, i))\n const args: DelegateUiAuditArgs = { workspaceDir: workspaceDir.trim(), routes }\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string' || value.namespace.trim().length === 0) {\n throw new TypeError('delegate_ui_audit: `namespace` must be a non-empty string when set')\n }\n args.namespace = value.namespace.trim()\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n return args\n}\n\nfunction validateRoute(raw: unknown, index: number): DelegateUiAuditArgs['routes'][number] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(`delegate_ui_audit: routes[${index}] must be an object`)\n }\n const v = raw as Record<string, unknown>\n if (typeof v.name !== 'string' || v.name.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].name must be a non-empty string`)\n }\n // Defense-in-depth: the slug helpers downstream strip non-alphanumerics, so\n // a route name with `..`, `/`, `\\`, or NUL cannot actually escape the\n // workspace. Rejecting them at the wire boundary keeps the invariant\n // explicit and matches the lens-allowlist style of validation.\n const trimmedName = v.name.trim()\n if (/[./\\\\]/.test(trimmedName) || trimmedName.includes('\\u0000')) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].name must not contain path separators, dots, or NUL (got ${JSON.stringify(v.name)})`,\n )\n }\n if (typeof v.url !== 'string' || v.url.trim().length === 0) {\n throw new TypeError(`delegate_ui_audit: routes[${index}].url must be a non-empty string`)\n }\n // Parse + restrict to http/https. The in-process auditor client navigates\n // to whatever URL the MCP caller supplies; permitting `file://`, `data:`,\n // `javascript:` would let an attacker controlling the tool input pull\n // local files or run inline scripts.\n let parsedUrl: URL\n try {\n parsedUrl = new URL(v.url)\n } catch {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url is not a parseable URL (got ${JSON.stringify(v.url)})`,\n )\n }\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].url must use http or https (got ${parsedUrl.protocol})`,\n )\n }\n const out: DelegateUiAuditArgs['routes'][number] = { name: v.name.trim(), url: v.url.trim() }\n if (v.viewports !== undefined) {\n if (!Array.isArray(v.viewports) || v.viewports.length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].viewports must be a non-empty array when set`,\n )\n }\n out.viewports = v.viewports.map((vp, j) => validateViewport(vp, index, j))\n }\n if (v.fullPage !== undefined) {\n if (typeof v.fullPage !== 'boolean') {\n throw new TypeError(`delegate_ui_audit: routes[${index}].fullPage must be a boolean`)\n }\n out.fullPage = v.fullPage\n }\n if (v.waitFor !== undefined) {\n if (typeof v.waitFor !== 'string' || v.waitFor.trim().length === 0) {\n throw new TypeError(\n `delegate_ui_audit: routes[${index}].waitFor must be a non-empty string when set`,\n )\n }\n out.waitFor = v.waitFor.trim()\n }\n return out\n}\n\nfunction validateViewport(\n raw: unknown,\n routeIndex: number,\n viewportIndex: number,\n): { width: number; height: number } {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must be an object`,\n )\n }\n const v = raw as Record<string, unknown>\n const w = Number(v.width)\n const h = Number(v.height)\n if (!Number.isInteger(w) || w <= 0 || !Number.isInteger(h) || h <= 0) {\n throw new RangeError(\n `delegate_ui_audit: routes[${routeIndex}].viewports[${viewportIndex}] must have positive integer width/height`,\n )\n }\n return { width: w, height: h }\n}\n\nfunction validateConfig(raw: unknown): DelegateUiAuditArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_ui_audit: `config` must be an object')\n }\n const v = raw as Record<string, unknown>\n const out: NonNullable<DelegateUiAuditArgs['config']> = {}\n if (v.lenses !== undefined) {\n if (!Array.isArray(v.lenses) || v.lenses.length === 0) {\n throw new TypeError('delegate_ui_audit: `config.lenses` must be a non-empty array when set')\n }\n const knownSet = new Set<string>(UI_LENSES)\n const lenses: UiLens[] = []\n for (let i = 0; i < v.lenses.length; i += 1) {\n const lens = v.lenses[i]\n if (typeof lens !== 'string' || !knownSet.has(lens)) {\n throw new TypeError(\n `delegate_ui_audit: config.lenses[${i}] must be one of ${UI_LENSES.join('|')}`,\n )\n }\n lenses.push(lens as UiLens)\n }\n out.lenses = lenses\n }\n if (v.maxIterations !== undefined) {\n const n = Number(v.maxIterations)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxIterations` must be a positive integer')\n }\n out.maxIterations = n\n }\n if (v.maxConcurrency !== undefined) {\n const n = Number(v.maxConcurrency)\n if (!Number.isInteger(n) || n < 1) {\n throw new RangeError('delegate_ui_audit: `config.maxConcurrency` must be a positive integer')\n }\n out.maxConcurrency = n\n }\n if (v.productContext !== undefined) {\n if (typeof v.productContext !== 'string') {\n throw new TypeError('delegate_ui_audit: `config.productContext` must be a string')\n }\n out.productContext = v.productContext\n }\n return out\n}\n\n/** @experimental */\ninterface DelegateUiAuditHandlerOptions {\n queue: DelegationTaskQueue\n delegate: UiAuditorDelegate\n estimateDurationMs?: (args: DelegateUiAuditArgs) => number\n}\n\n/** Build the MCP tool handler that validates input, deduplicates via idempotency key, and enqueues a UI audit. @experimental */\nexport function createDelegateUiAuditHandler(\n options: DelegateUiAuditHandlerOptions,\n): (raw: unknown) => Promise<DelegateUiAuditResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateUiAuditArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'ui-auditor',\n workspaceDir: args.workspaceDir,\n routes: args.routes,\n namespace: args.namespace,\n config: args.config,\n })\n const submitted = options.queue.submit<DelegateUiAuditArgs>({\n profile: 'ui-auditor',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: DelegateUiAuditArgs): number {\n const lenses = args.config?.lenses?.length ?? UI_LENSES.length - 1\n const routes = args.routes.length\n return PER_LENS_PER_ROUTE_ESTIMATE_MS * lenses * routes\n}\n","/**\n *\n * MCP delegation tool surface — the typed inputs/outputs the product agent\n * sees over the wire. These types are the contract; the JSON schemas under\n * `tools/*` mirror them for the MCP `tools/list` advertisement.\n *\n * Async semantics: `delegate_ui_audit` returns a `taskId` immediately. The\n * product agent polls `delegation_status` until the task transitions to\n * `completed` | `failed` | `cancelled`. `delegate_feedback` +\n * `delegation_history` are synchronous reads / writes against the local\n * task queue + feedback store.\n *\n * @experimental\n */\n\nimport type { ResearchSource } from '../profiles/researcher'\nimport type { UiFinding, UiLens } from '../profiles/ui-auditor/substrate'\nimport type { DelegationTraceSpan } from './delegation-trace'\nimport type { CoderOutput } from './detached-coder'\n\n/**\n * Every delegation profile a queued record can carry. One owner: the tool schemas and validators\n * that filter on a profile read this list, so a profile added here cannot be one a tool refuses.\n * @experimental\n */\nexport const delegationProfiles = ['coder', 'researcher', 'ui-auditor'] as const\n\n/** @experimental */\nexport type DelegationProfile = (typeof delegationProfiles)[number]\n\n/** @experimental */\nexport type DelegationStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n\n/**\n * Minimal `CoderTask` overrides exposed over the MCP wire. The full\n * `CoderTask` carries fields the kernel synthesizes from `goal` +\n * `repoRoot` — the agent only edits the few that materially gate\n * validator behavior.\n *\n * @experimental\n */\nexport interface DelegateCodeConfig {\n testCmd?: string\n typecheckCmd?: string\n forbiddenPaths?: string[]\n maxDiffLines?: number\n}\n\n/** @experimental */\nexport interface DelegateCodeArgs {\n /** Natural-language description of what the coder must accomplish. */\n goal: string\n /** Absolute path inside the sandbox where the repo lives. */\n repoRoot: string\n /** Optional free-form context the agent surfaces in the prompt prelude. */\n contextHint?: string\n /**\n * When > 1, dispatches `multiHarnessCoderFanout` across the delegate's configured exact profiles\n * and picks the highest-scoring passing patch. Default 1.\n */\n variants?: number\n /** Validator + prompt overrides the agent knows for this repo. */\n config?: DelegateCodeConfig\n /** Multi-tenant scope (customer-id, workspace-id). */\n namespace?: string\n}\n\nexport type { ResearchSource }\n\n/** @experimental */\nexport interface DelegateResearchConfig {\n recencyWindow?: { since?: string; until?: string }\n maxItems?: number\n minConfidence?: number\n}\n\n/** @experimental */\nexport interface DelegateResearchArgs {\n question: string\n namespace: string\n scope?: string\n sources?: ResearchSource[]\n variants?: number\n config?: DelegateResearchConfig\n}\n\n/** @experimental */\nexport interface FeedbackRefersTo {\n kind: 'delegation' | 'artifact' | 'outcome'\n /** For `'delegation'`, this is the taskId. */\n ref: string\n}\n\n/** @experimental */\nexport interface FeedbackRating {\n /** [0, 1]. */\n score: number\n label?: 'good' | 'bad' | 'neutral' | 'mixed'\n notes: string\n}\n\n/** @experimental */\nexport interface DelegateFeedbackArgs {\n refersTo: FeedbackRefersTo\n rating: FeedbackRating\n by: 'agent' | 'user' | 'downstream-judge'\n /** ISO timestamp; defaults to server clock when omitted. */\n capturedAt?: string\n namespace?: string\n}\n\n/** @experimental */\nexport interface DelegateFeedbackResult {\n recorded: true\n id: string\n}\n\n/** @experimental */\nexport interface DelegationStatusArgs {\n taskId: string\n /**\n * Return the delegation's compact loop-trace span tree alongside the\n * status. Default false — status polls stay light; opt in when you need\n * the topology (which iterations ran, where they were placed, what each\n * cost) rather than just the state machine.\n */\n includeTrace?: boolean\n}\n\n/** @experimental */\nexport interface DelegationProgress {\n iteration: number\n phase: string\n}\n\n/** @experimental */\nexport interface DelegationError {\n message: string\n kind: string\n}\n\n/**\n * Polymorphic `result` field: `CoderOutput` when the underlying profile\n * is `'coder'`, a structurally-typed research output when `'researcher'`.\n * The MCP wire carries it as JSON either way.\n *\n * @experimental\n */\nexport type DelegationResultPayload =\n | { profile: 'coder'; output: CoderOutput }\n | { profile: 'researcher'; output: ResearchOutputShape }\n | { profile: 'ui-auditor'; output: UiAuditorDelegationOutput }\n\n/**\n * Wire-shape of a completed UI-audit delegation. The `findings` array\n * contains every finding persisted to the workspace during the run,\n * already enriched with `id` and `createdAt` by the writer. `workspaceDir`\n * is the absolute path to the workspace; `indexFile` is the workspace-\n * relative path to the regenerated index.md.\n *\n * @experimental\n */\nexport interface UiAuditorDelegationOutput {\n workspaceDir: string\n indexFile: string\n findings: UiFinding[]\n /** Total iterations the loop ran for this delegation. */\n iterations: number\n}\n\n/** @experimental */\nexport type UiAuditLensFilter = readonly UiLens[]\n\n/** Optional per-route capture spec the agent surfaces over the wire. */\nexport interface DelegateUiAuditRoute {\n /** Stable route name (used in screenshot filenames + finding metadata). */\n name: string\n /** Fully-qualified URL. */\n url: string\n /** Viewports to capture at. Defaults to `[{ width: 1280, height: 800 }]`. */\n viewports?: readonly { width: number; height: number }[]\n /** Default false. Full-page captures for the broad lenses. */\n fullPage?: boolean\n /** Selector to wait for before capture. */\n waitFor?: string\n}\n\n/** @experimental */\nexport interface DelegateUiAuditConfig {\n /**\n * Lenses to iterate. Default: every lens except `'other'`. Order is\n * preserved — the driver iterates lens-by-lens.\n */\n lenses?: UiAuditLensFilter\n /** Maximum total iterations across all (lens × route) pairs. Default 33 (11 lenses × 3 routes). */\n maxIterations?: number\n /** Maximum concurrent iterations within a single plan() round. Default 2. */\n maxConcurrency?: number\n /** Free-form product context surfaced to the judge. */\n productContext?: string\n}\n\n/** @experimental */\nexport interface DelegateUiAuditArgs {\n /** Workspace root for the audit (absolute path). */\n workspaceDir: string\n /** Routes to audit. Must be non-empty. */\n routes: readonly DelegateUiAuditRoute[]\n /** Multi-tenant scope. */\n namespace?: string\n config?: DelegateUiAuditConfig\n}\n\n/** @experimental */\nexport interface DelegateUiAuditResult {\n taskId: string\n estimatedDurationMs?: number\n}\n\n/**\n * Provider-neutral research output carried over the MCP boundary. The MCP\n * layer accepts this structural shape instead of coupling its wire contract to\n * one research implementation.\n *\n * @experimental\n */\nexport interface ResearchOutputShape {\n items: unknown[]\n citations: unknown[]\n proposedWrites: unknown[]\n gaps?: string[]\n notes?: string\n [key: string]: unknown\n}\n\n/** @experimental */\nexport interface DelegationStatusResult {\n taskId: string\n profile: DelegationProfile\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Compact loop-trace span tree; present only when `includeTrace: true` was passed and spans were recorded. */\n trace?: DelegationTraceSpan[]\n /** Present when oldest trace spans were dropped to honor the trace caps. */\n traceTruncated?: true\n /** Inherited trace identity recorded at submit — join key into the caller's trace. */\n traceId?: string\n /** Caller span that dispatched the delegation, when one was inherited. */\n parentSpanId?: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryArgs {\n namespace?: string\n profile?: DelegationProfile\n /** ISO date — only delegations started at-or-after `since` are returned. */\n since?: string\n /** Default 50. Hard cap 500. */\n limit?: number\n}\n\n/** @experimental */\nexport interface DelegationFeedbackSnapshot {\n id: string\n score: number\n label?: FeedbackRating['label']\n by: DelegateFeedbackArgs['by']\n notes: string\n capturedAt: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryEntry {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegateCodeArgs | DelegateResearchArgs | DelegateUiAuditArgs\n status: DelegationStatus\n feedback?: DelegationFeedbackSnapshot[]\n costUsd?: number\n startedAt: string\n completedAt?: string\n /**\n * True when the record carries a journaled loop trace. History stays\n * light by design — fetch the spans via\n * `delegation_status { taskId, includeTrace: true }`.\n */\n hasTrace: boolean\n /** Inherited trace identity recorded at submit — join key into the caller's trace. */\n traceId?: string\n}\n\n/** @experimental */\nexport interface DelegationHistoryResult {\n delegations: DelegationHistoryEntry[]\n}\n\n/**\n * Re-export `CoderTask` so callers wiring custom delegates don't have to\n * import from `./profiles` themselves.\n *\n * @experimental\n */\nexport type { CoderOutput }\n","/**\n *\n * `delegation_history` MCP tool — synchronous read of past delegations.\n * The agent uses this for self-introspection — \"have I delegated this\n * kind of task before? did it work?\" — and calibration.\n *\n * @stable\n */\n\nimport type {\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationTaskQueue,\n} from '../task-queue'\nimport { delegationProfiles } from '../types'\n\n/** MCP tool name for the `delegation_history` read-past-delegations tool. @stable */\nexport const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history'\n\n/** Human-readable description of the `delegation_history` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATION_HISTORY_DESCRIPTION = [\n 'Read past delegations newest-first. Each entry carries the original',\n 'arguments, current status, cost, and any feedback attached via',\n 'delegate_feedback.',\n '',\n 'Use when: you want to introspect prior decisions — \"have I asked this',\n 'question before?',\n 'did the last patch land?',\n \"what's the historical\",\n 'success rate of coder delegations on this repo?\". Feed the results back',\n 'into your own routing and calibration.',\n '',\n 'Each entry carries `hasTrace` — when true, the full loop-trace span tree',\n 'is retrievable via delegation_status { taskId, includeTrace: true }.',\n '',\n `Filters: \\`namespace\\` (multi-tenant scope), \\`profile\\` (${delegationProfiles\n .map((profile) => `\"${profile}\"`)\n .join(' | ')}),`,\n '`since` (ISO date — only delegations started at-or-after). `limit` defaults',\n 'to 50, capped at 500.',\n].join('\\n')\n\n/** JSON Schema for `delegation_history` tool arguments (optional `namespace`, `profile`, `since`, `limit`). @stable */\nexport const DELEGATION_HISTORY_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n namespace: { type: 'string' },\n profile: { type: 'string', enum: delegationProfiles },\n since: { type: 'string', description: 'ISO datetime — earliest startedAt to include.' },\n limit: { type: 'integer', minimum: 1, maximum: 500 },\n },\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationHistoryArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryArgs {\n if (raw === undefined || raw === null) return {}\n if (typeof raw !== 'object') {\n throw new TypeError('delegation_history: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: DelegationHistoryArgs = {}\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string') {\n throw new TypeError('delegation_history: `namespace` must be a string')\n }\n out.namespace = value.namespace\n }\n if (value.profile !== undefined) {\n if (!delegationProfiles.includes(value.profile as DelegationProfile)) {\n throw new TypeError(\n `delegation_history: \\`profile\\` must be one of ${delegationProfiles.join(', ')}`,\n )\n }\n out.profile = value.profile as DelegationProfile\n }\n if (value.since !== undefined) {\n if (typeof value.since !== 'string' || Number.isNaN(Date.parse(value.since))) {\n throw new TypeError('delegation_history: `since` must be an ISO datetime')\n }\n out.since = value.since\n }\n if (value.limit !== undefined) {\n const n = Number(value.limit)\n if (!Number.isFinite(n) || n < 1 || n > 500) {\n throw new RangeError('delegation_history: `limit` must be an integer in [1, 500]')\n }\n out.limit = Math.trunc(n)\n }\n return out\n}\n\n/** @stable */\ninterface DelegationHistoryHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that reads filtered past delegations from a `DelegationTaskQueue`. @stable */\nexport function createDelegationHistoryHandler(\n options: DelegationHistoryHandlerOptions,\n): (raw: unknown) => Promise<DelegationHistoryResult> {\n return async (raw) => {\n const args = validateDelegationHistoryArgs(raw)\n return { delegations: options.queue.history(args) }\n }\n}\n","/**\n *\n * `delegation_status` MCP tool — synchronous poll. Returns the current\n * state machine + optional progress + final result (when terminal).\n *\n * @stable\n */\n\nimport { NotFoundError } from '../../errors'\nimport type {\n DelegationStatusArgs,\n DelegationStatusResult,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** MCP tool name for the `delegation_status` synchronous-poll tool. @stable */\nexport const DELEGATION_STATUS_TOOL_NAME = 'delegation_status'\n\n/** Human-readable description of the `delegation_status` MCP tool, injected into the tool manifest. @stable */\nexport const DELEGATION_STATUS_DESCRIPTION = [\n 'Poll the status of an async delegation. Returns the current state',\n '(pending | running | completed | failed | cancelled), optional progress,',\n 'and the final result when status === \"completed\".',\n '',\n 'Use when: you previously kicked off an async delegation (delegate_ui_audit)',\n \"and need to know whether the work is done. The agent's right rhythm is to\",\n 'call this every minute or two while waiting; do not busy-poll.',\n '',\n 'For a completed delegate_ui_audit run, `result.output` is the array of UI',\n 'findings — one self-contained Markdown finding per issue, each with an',\n 'embedded screenshot and a suggested fix.',\n '',\n 'Pass includeTrace: true to also receive the journaled loop-trace span',\n 'tree (loop → round → iteration, with placement/cost/verdict metadata).',\n 'Default false — keep routine polls light.',\n '',\n 'Throws NotFoundError when taskId is unknown — never silently returns',\n '`pending` for a typo.',\n].join('\\n')\n\n/** JSON Schema for `delegation_status` tool arguments (`taskId` + optional `includeTrace`). @stable */\nexport const DELEGATION_STATUS_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n taskId: { type: 'string', description: 'Returned by delegate_ui_audit.' },\n includeTrace: {\n type: 'boolean',\n description:\n 'Also return the journaled loop-trace span tree for this delegation. Default false.',\n },\n },\n required: ['taskId'],\n additionalProperties: false,\n} as const\n\n/** Parse and validate raw MCP tool input into typed `DelegationStatusArgs`; throws `TypeError` on bad input. @stable */\nexport function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegation_status: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const taskId = value.taskId\n if (typeof taskId !== 'string' || taskId.trim().length === 0) {\n throw new TypeError('delegation_status: `taskId` must be a non-empty string')\n }\n const out: DelegationStatusArgs = { taskId: taskId.trim() }\n if (value.includeTrace !== undefined) {\n if (typeof value.includeTrace !== 'boolean') {\n throw new TypeError('delegation_status: `includeTrace` must be a boolean')\n }\n out.includeTrace = value.includeTrace\n }\n return out\n}\n\n/** @stable */\ninterface DelegationStatusHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** Build the MCP tool handler that polls a `DelegationTaskQueue` for task status. @stable */\nexport function createDelegationStatusHandler(\n options: DelegationStatusHandlerOptions,\n): (raw: unknown) => Promise<DelegationStatusResult> {\n return async (raw) => {\n const args = validateDelegationStatusArgs(raw)\n const status = options.queue.status(\n args.taskId,\n args.includeTrace !== undefined ? { includeTrace: args.includeTrace } : undefined,\n )\n if (!status) {\n throw new NotFoundError(`delegation_status: unknown taskId \"${args.taskId}\"`)\n }\n return status\n }\n}\n","/**\n *\n * Stdio JSON-RPC MCP server exposing the delegation tools to sandbox\n * coding-harness agents (claude-code, codex, opencode, ...): the generic\n * `delegate` verb plus the queue-bound `delegate_feedback`,\n * `delegation_status`, and `delegation_history`. `delegate_ui_audit` is served\n * when a `uiAuditorDelegate` is wired.\n *\n * The server is transport-bound but topology-free: tool execution is\n * delegated to handler functions composed from a queue, a feedback\n * store, and the wired run delegates. Consumers wire those at\n * construction time. The `agent-runtime-mcp` bin serves the generic\n * `delegate` verb over a real sandbox client when `MCP_ENABLE_DELEGATE=1`.\n *\n * Wire protocol: line-delimited JSON-RPC 2.0 over stdio. Each line is\n * one request; each response is one line. `tools/list` and `tools/call`\n * mirror the MCP 2024-11-05 spec. The production server does not depend on\n * `@modelcontextprotocol/sdk`; integration tests validate this wire with the official client.\n *\n * @experimental\n */\n\nimport { Readable, Writable } from 'node:stream'\nimport { ValidationError } from '../errors'\nimport type { UiAuditorDelegate } from './delegates'\nimport { type FeedbackStore, InMemoryFeedbackStore } from './feedback-store'\nimport type { JsonRpcMessage, JsonRpcResponse, McpToolDescriptor, McpTransport } from './protocol'\nimport { DelegationTaskQueue } from './task-queue'\nimport { createStdioToolServer } from './tool-server'\nimport {\n createDelegateHandler,\n DELEGATE_DESCRIPTION,\n DELEGATE_INPUT_SCHEMA,\n DELEGATE_TOOL_NAME,\n type DelegateHandlerOptions,\n} from './tools/delegate'\nimport {\n createDelegateFeedbackHandler,\n DELEGATE_FEEDBACK_DESCRIPTION,\n DELEGATE_FEEDBACK_INPUT_SCHEMA,\n DELEGATE_FEEDBACK_TOOL_NAME,\n} from './tools/delegate-feedback'\nimport {\n createDelegateUiAuditHandler,\n DELEGATE_UI_AUDIT_DESCRIPTION,\n DELEGATE_UI_AUDIT_INPUT_SCHEMA,\n DELEGATE_UI_AUDIT_TOOL_NAME,\n} from './tools/delegate-ui-audit'\nimport {\n createDelegationHistoryHandler,\n DELEGATION_HISTORY_DESCRIPTION,\n DELEGATION_HISTORY_INPUT_SCHEMA,\n DELEGATION_HISTORY_TOOL_NAME,\n} from './tools/delegation-history'\nimport {\n createDelegationStatusHandler,\n DELEGATION_STATUS_DESCRIPTION,\n DELEGATION_STATUS_INPUT_SCHEMA,\n DELEGATION_STATUS_TOOL_NAME,\n} from './tools/delegation-status'\nimport type { TraceContext } from './trace-propagation'\n\nexport type { JsonRpcResponse, McpToolDescriptor } from './protocol'\n\n/** @experimental */\nexport interface McpServerOptions {\n /**\n * Required to enable `delegate` — the ONE generic delegation verb. Inject the supervisor\n * substrate: its brain `router`, the worker `backend`, and the completion `deliverable`. The\n * supervisor AUTHORS its own worker from the agent's intent, so there is no worker profile to\n * wire here.\n */\n delegateSupervisor?: DelegateHandlerOptions\n /**\n * Required to enable delegate_ui_audit. Wire one that executes an exact\n * agent profile through Runtime and returns the provider-neutral UI audit result.\n */\n uiAuditorDelegate?: UiAuditorDelegate\n /** Override the default in-memory feedback store. */\n feedbackStore?: FeedbackStore\n /** Override the default in-memory task queue. */\n queue?: DelegationTaskQueue\n /**\n * Extra tools to serve alongside the delegation tools, for example\n * `createCoordinationTools(...).tools`. Registered after the built-ins; a\n * duplicate name throws so delegation tools cannot be shadowed silently.\n */\n extraTools?: McpToolDescriptor[]\n /**\n * Inherited trace identity (`readTraceContextFromEnv()`) stamped on every\n * record the DEFAULT queue creates. Ignored when `queue` is supplied —\n * pass `traceContext` to that queue's constructor instead.\n */\n traceContext?: TraceContext\n /** Server display name surfaced via `initialize`. Default `'agent-runtime-mcp'`. */\n serverName?: string\n /** Server version surfaced via `initialize`. Default = the package version baked at build time. */\n serverVersion?: string\n}\n\n/** @experimental */\nexport interface McpServer {\n /** Tools currently registered (depend on which delegates were wired). */\n readonly tools: ReadonlyMap<string, McpToolDescriptor>\n /** The underlying queue — exposed so tests can introspect it. */\n readonly queue: DelegationTaskQueue\n /** The feedback store — exposed for the same reason. */\n readonly feedbackStore: FeedbackStore\n /** Handle a single parsed JSON-RPC message. Returns the response object (or `null` for notifications). */\n handle(message: JsonRpcMessage): Promise<JsonRpcResponse | null>\n /** Drive the server on a stdio-shaped transport until `stop()` is called. */\n serve(transport?: McpTransport): Promise<void>\n /** Stop a `serve` call. Subsequent requests are rejected. */\n stop(): void\n}\n\nconst DEFAULT_SERVER_NAME = 'agent-runtime-mcp'\nconst DEFAULT_SERVER_VERSION = '0.22.0'\n\n/**\n * Stdio JSON-RPC MCP server exposing the delegation tools (`delegate`, `delegate_feedback`, `delegation_status`, `delegation_history`, optional `delegate_ui_audit`) to sandbox coding-harness agents.\n *\n * @experimental\n */\nexport function createMcpServer(options: McpServerOptions = {}): McpServer {\n const queue =\n options.queue ??\n new DelegationTaskQueue(\n options.traceContext !== undefined ? { traceContext: options.traceContext } : {},\n )\n const feedbackStore = options.feedbackStore ?? new InMemoryFeedbackStore()\n const serverName = options.serverName ?? DEFAULT_SERVER_NAME\n const serverVersion = options.serverVersion ?? DEFAULT_SERVER_VERSION\n\n const tools = new Map<string, McpToolDescriptor>()\n\n if (options.delegateSupervisor) {\n tools.set(DELEGATE_TOOL_NAME, {\n name: DELEGATE_TOOL_NAME,\n description: DELEGATE_DESCRIPTION,\n inputSchema: DELEGATE_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateHandler(options.delegateSupervisor),\n })\n }\n if (options.uiAuditorDelegate) {\n tools.set(DELEGATE_UI_AUDIT_TOOL_NAME, {\n name: DELEGATE_UI_AUDIT_TOOL_NAME,\n description: DELEGATE_UI_AUDIT_DESCRIPTION,\n inputSchema: DELEGATE_UI_AUDIT_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateUiAuditHandler({ queue, delegate: options.uiAuditorDelegate }),\n })\n }\n tools.set(DELEGATE_FEEDBACK_TOOL_NAME, {\n name: DELEGATE_FEEDBACK_TOOL_NAME,\n description: DELEGATE_FEEDBACK_DESCRIPTION,\n inputSchema: DELEGATE_FEEDBACK_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegateFeedbackHandler({ queue, store: feedbackStore }),\n })\n tools.set(DELEGATION_STATUS_TOOL_NAME, {\n name: DELEGATION_STATUS_TOOL_NAME,\n description: DELEGATION_STATUS_DESCRIPTION,\n inputSchema: DELEGATION_STATUS_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationStatusHandler({ queue }),\n })\n tools.set(DELEGATION_HISTORY_TOOL_NAME, {\n name: DELEGATION_HISTORY_TOOL_NAME,\n description: DELEGATION_HISTORY_DESCRIPTION,\n inputSchema: DELEGATION_HISTORY_INPUT_SCHEMA as unknown as Record<string, unknown>,\n handler: createDelegationHistoryHandler({ queue }),\n })\n for (const tool of options.extraTools ?? []) {\n if (tools.has(tool.name)) {\n throw new ValidationError(\n `createMcpServer: extra tool \"${tool.name}\" shadows a built-in tool`,\n )\n }\n tools.set(tool.name, tool)\n }\n\n const stdio = createStdioToolServer({\n serverName,\n serverVersion,\n tools: [...tools.values()],\n })\n\n return {\n tools: stdio.tools,\n queue,\n feedbackStore,\n handle: stdio.handle,\n serve: stdio.serve,\n stop: stdio.stop,\n }\n}\n\n/**\n * In-process pair of `Readable` + `Writable` streams suitable for driving\n * `server.serve(...)` from a test. Returns the agent-side stream (the\n * client writes to it) and the server-side stream (the test reads from it).\n *\n * @experimental\n */\nexport function createInProcessTransport(): {\n transport: McpTransport\n clientWrite(line: string): void\n clientClose(): void\n readServer(): Promise<JsonRpcResponse[]>\n} {\n const responses: JsonRpcResponse[] = []\n const input = new Readable({ read() {} })\n const output = new Writable({\n write(chunk, _enc, cb) {\n const text = chunk.toString('utf8')\n for (const line of text.split('\\n')) {\n const trimmed = line.trim()\n if (!trimmed) continue\n try {\n responses.push(JSON.parse(trimmed) as JsonRpcResponse)\n } catch {\n // Non-JSON output should never appear; drop it silently in the\n // test transport rather than crashing.\n }\n }\n cb()\n },\n })\n return {\n transport: { input, output },\n clientWrite(line: string) {\n input.push(`${line}\\n`)\n },\n clientClose() {\n input.push(null)\n },\n async readServer() {\n // Yield to the event loop a few times so async handlers drain.\n for (let i = 0; i < 5; i += 1) await new Promise((r) => setImmediate(r))\n return [...responses]\n },\n }\n}\n"],"mappings":"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"}
|