@tangle-network/agent-runtime 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -16
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +5 -3
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/analyst-loop.js +2 -2
- package/dist/{chunk-K5M3SHEU.js → chunk-2BDXWZUC.js} +5 -34
- package/dist/chunk-2BDXWZUC.js.map +1 -0
- package/dist/chunk-A73RADPB.js +281 -0
- package/dist/chunk-A73RADPB.js.map +1 -0
- package/dist/chunk-FRBWCJLP.js +396 -0
- package/dist/chunk-FRBWCJLP.js.map +1 -0
- package/dist/chunk-GRAGM4MC.js +72 -0
- package/dist/chunk-GRAGM4MC.js.map +1 -0
- package/dist/{chunk-K6WP7PYW.js → chunk-JTH2FPCK.js} +3231 -424
- package/dist/chunk-JTH2FPCK.js.map +1 -0
- package/dist/{chunk-P4QNEXFC.js → chunk-KJH62YEK.js} +2 -2
- package/dist/{chunk-HNUXAZIJ.js → chunk-P5OKDSLB.js} +2 -2
- package/dist/{chunk-GSUO5QS6.js → chunk-VLF5RHEQ.js} +2 -5
- package/dist/{chunk-GSUO5QS6.js.map → chunk-VLF5RHEQ.js.map} +1 -1
- package/dist/{chunk-JFIYKDXF.js → chunk-XRYEZPR6.js} +2 -1
- package/dist/chunk-XRYEZPR6.js.map +1 -0
- package/dist/{coder-LKm3Mczw.d.ts → coder-CEkUFv8h.d.ts} +1 -1
- package/dist/{types-CNDJCL_0.d.ts → coordination-BMzskrUR.d.ts} +268 -2
- package/dist/{kb-gate-CKfykcYQ.d.ts → delegates-BPLIl8EC.d.ts} +491 -566
- package/dist/index.d.ts +7 -7
- package/dist/index.js +23 -80
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +2 -2
- package/dist/kb-gate-CuzMYGYM.d.ts +76 -0
- package/dist/{loop-runner-bin-D4Ir7b00.d.ts → loop-runner-bin-BGpVVyXp.d.ts} +6 -27
- package/dist/loop-runner-bin.d.ts +5 -5
- package/dist/loop-runner-bin.js +6 -5
- package/dist/loops.d.ts +8 -6
- package/dist/loops.js +32 -8
- package/dist/mcp/bin.js +94 -30
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +9 -272
- package/dist/mcp/index.js +45 -365
- package/dist/mcp/index.js.map +1 -1
- package/dist/{openai-tools-CKfR3EMh.d.ts → openai-tools-CoeLQ7Uo.d.ts} +1 -1
- package/dist/profiles.d.ts +2 -2
- package/dist/profiles.js +4 -4
- package/dist/{router-client-B0Qi1NiN.d.ts → router-client-30Y_pca8.d.ts} +1 -1
- package/dist/{run-loop-DgVhucoR.d.ts → run-loop-DluzfJ2h.d.ts} +1 -1
- package/dist/runtime.d.ts +424 -23
- package/dist/runtime.js +32 -8
- package/dist/topology.d.ts +54 -1
- package/dist/topology.js +222 -0
- package/dist/topology.js.map +1 -1
- package/dist/{types-CklkW4Eh.d.ts → types-C8rNlxfV.d.ts} +4 -4
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +4 -2
- package/dist/workflow.js.map +1 -1
- package/package.json +5 -5
- package/skills/agent-runtime-adoption/SKILL.md +54 -46
- package/skills/build-with-agent-runtime/SKILL.md +12 -8
- package/skills/loop-writer/SKILL.md +9 -1
- package/skills/supervise/SKILL.md +24 -0
- package/dist/chunk-5M2WDWBI.js +0 -908
- package/dist/chunk-5M2WDWBI.js.map +0 -1
- package/dist/chunk-AYRQZRDV.js +0 -623
- package/dist/chunk-AYRQZRDV.js.map +0 -1
- package/dist/chunk-FO4DCM7R.js +0 -1356
- package/dist/chunk-FO4DCM7R.js.map +0 -1
- package/dist/chunk-JFIYKDXF.js.map +0 -1
- package/dist/chunk-K5M3SHEU.js.map +0 -1
- package/dist/chunk-K6WP7PYW.js.map +0 -1
- package/dist/driver-B2RKkVJW.d.ts +0 -221
- /package/dist/{chunk-P4QNEXFC.js.map → chunk-KJH62YEK.js.map} +0 -0
- /package/dist/{chunk-HNUXAZIJ.js.map → chunk-P5OKDSLB.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/delegation-store.ts","../src/mcp/task-queue.ts","../src/mcp/tools/delegate-code.ts","../src/mcp/feedback-store.ts","../src/mcp/tools/delegate-feedback.ts","../src/mcp/tools/delegate-research.ts","../src/mcp/tools/delegation-history.ts","../src/mcp/tools/delegation-status.ts"],"sourcesContent":["/**\n * @experimental\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\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { AgentEvalError } from '../errors'\nimport type { DelegationRecord } from './task-queue'\n\n/** @experimental */\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 * @experimental\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 * @experimental\n */\nexport class DelegationPersistenceError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('config', message, options)\n }\n}\n\n/** @experimental */\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/** @experimental */\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 * @experimental\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\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n","/**\n * @experimental\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 `runLoop` 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\nimport { ValidationError } from '../errors'\nimport type { LoopTraceEmitter } from '../runtime/types'\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\ntype AnyDelegateArgs = 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 * @experimental\n */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: AnyDelegateArgs\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/** @experimental */\nexport interface SubmitInput<Args extends AnyDelegateArgs> {\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/** @experimental 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 `runLoop` 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/** @experimental */\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 * @experimental\n */\nexport type DelegationResumeTick =\n | { state: 'running' }\n | { state: 'completed'; output: DelegationResultPayload['output']; costUsd?: number }\n | { state: 'failed'; error: DelegationError }\n\n/** @experimental */\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 * @experimental\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/** @experimental */\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/** @experimental */\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 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 AnyDelegateArgs>(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 await this.persistTail\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 AnyDelegateArgs>(\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 rehydrate(loaded: DelegationRecord[]): 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 for (const record of this.records.values()) {\n if (isTerminal(record.status)) continue\n if (record.detachedSessionRef && this.resumeDelegate) {\n record.status = 'running'\n 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 this.persist(record)\n }\n this.enforceRetention()\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): void {\n if (this.persistFailure) return\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 }\n\n private persistRemoval(taskIds: string[]): void {\n if (this.persistFailure || taskIds.length === 0) return\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 }\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(): void {\n if (!Number.isFinite(this.maxTerminalRecords)) return\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\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 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 * @experimental\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 // FNV-1a 32-bit\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\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 DelegateCodeArgs,\n DelegateCodeResult,\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n DelegateResearchArgs,\n DelegateResearchResult,\n DelegateUiAuditArgs,\n DelegateUiAuditConfig,\n DelegateUiAuditResult,\n DelegateUiAuditRoute,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\n UiAuditorDelegationOutput,\n} from './types'\n","/**\n * @experimental\n *\n * `delegate_code` MCP tool — async kickoff. The handler validates the\n * input, computes an idempotency key over the canonical fields, hands\n * the task to the queue, and returns `{ taskId, estimatedDurationMs }`.\n */\n\nimport type { CoderDelegate } from '../delegates'\nimport { formatDetachedSessionRef } from '../detached-turn'\nimport {\n type DelegateCodeArgs,\n type DelegateCodeResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATE_CODE_TOOL_NAME = 'delegate_code'\n\n/** @experimental */\nexport const DELEGATE_CODE_DESCRIPTION = [\n 'Delegate a coding task to specialist coder agents that produce a validated patch.',\n '',\n 'Use when: you need code written, fixed, refactored, or extended to satisfy a',\n 'user goal that touches a real repository. The coder runs in an isolated',\n 'sandbox, opens a fresh branch, keeps the diff minimal, runs the supplied',\n 'test + typecheck commands, and emits a unified-diff patch.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'patch + validator verdict (typically minutes-to-hours, longer for large',\n 'changes). Identical inputs return the same taskId — safe to retry.',\n '',\n 'When variants > 1, multiple coder harnesses (claude-code, codex, opencode)',\n 'attempt the task in parallel and the highest-scoring patch wins (smallest',\n 'passing diff). Use variants for high-stakes changes; single variant for',\n 'routine ones.',\n '',\n 'Capability scope: the coder cannot modify paths outside repoRoot and cannot',\n 'touch paths in config.forbiddenPaths. The validator hard-fails on a',\n 'forbidden-path violation, diff above config.maxDiffLines, test failure, or',\n 'typecheck failure — none of those make it past the gate.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATE_CODE_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n goal: {\n type: 'string',\n description: 'Natural-language description of what the coder must accomplish.',\n },\n repoRoot: {\n type: 'string',\n description: 'Absolute path inside the sandbox where the repo lives.',\n },\n contextHint: {\n type: 'string',\n description: 'Optional free-form context the coder sees in the prompt prelude.',\n },\n variants: {\n type: 'integer',\n minimum: 1,\n maximum: 8,\n description: 'Number of parallel coder harnesses. Default 1.',\n },\n config: {\n type: 'object',\n properties: {\n testCmd: { type: 'string' },\n typecheckCmd: { type: 'string' },\n forbiddenPaths: { type: 'array', items: { type: 'string' } },\n maxDiffLines: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n namespace: {\n type: 'string',\n description: 'Multi-tenant scope (customer-id, workspace-id).',\n },\n },\n required: ['goal', 'repoRoot'],\n additionalProperties: false,\n} as const\n\nconst SINGLE_VARIANT_ESTIMATE_MS = 6 * 60 * 1000 // 6 minutes — single coder\nconst FANOUT_PER_VARIANT_ESTIMATE_MS = 8 * 60 * 1000 // 8 minutes — fanout\n\n/** @experimental */\nexport function validateDelegateCodeArgs(raw: unknown): DelegateCodeArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_code: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const goal = value.goal\n if (typeof goal !== 'string' || goal.trim().length === 0) {\n throw new TypeError('delegate_code: `goal` must be a non-empty string')\n }\n const repoRoot = value.repoRoot\n if (typeof repoRoot !== 'string' || repoRoot.trim().length === 0) {\n throw new TypeError('delegate_code: `repoRoot` must be a non-empty string')\n }\n const args: DelegateCodeArgs = { goal: goal.trim(), repoRoot: repoRoot.trim() }\n if (typeof value.contextHint === 'string') args.contextHint = value.contextHint\n if (value.variants !== undefined) {\n const variants = Number(value.variants)\n if (!Number.isFinite(variants) || variants < 1 || variants > 8) {\n throw new RangeError('delegate_code: `variants` must be an integer in [1, 8]')\n }\n args.variants = Math.trunc(variants)\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateConfig(raw: unknown): DelegateCodeArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_code: `config` must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: NonNullable<DelegateCodeArgs['config']> = {}\n if (value.testCmd !== undefined) {\n if (typeof value.testCmd !== 'string') {\n throw new TypeError('delegate_code: `config.testCmd` must be a string')\n }\n out.testCmd = value.testCmd\n }\n if (value.typecheckCmd !== undefined) {\n if (typeof value.typecheckCmd !== 'string') {\n throw new TypeError('delegate_code: `config.typecheckCmd` must be a string')\n }\n out.typecheckCmd = value.typecheckCmd\n }\n if (value.forbiddenPaths !== undefined) {\n if (!Array.isArray(value.forbiddenPaths)) {\n throw new TypeError('delegate_code: `config.forbiddenPaths` must be a string array')\n }\n out.forbiddenPaths = value.forbiddenPaths.map((entry, i) => {\n if (typeof entry !== 'string') {\n throw new TypeError(`delegate_code: forbiddenPaths[${i}] must be a string`)\n }\n return entry\n })\n }\n if (value.maxDiffLines !== undefined) {\n const n = Number(value.maxDiffLines)\n if (!Number.isFinite(n) || n < 1) {\n throw new RangeError('delegate_code: `config.maxDiffLines` must be a positive integer')\n }\n out.maxDiffLines = Math.trunc(n)\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegateCodeHandlerOptions {\n queue: DelegationTaskQueue\n delegate: CoderDelegate\n /** Override the duration hint. */\n estimateDurationMs?: (args: DelegateCodeArgs) => number\n /**\n * Record a deterministic detached-session resume key on single-variant\n * submissions (derived from the idempotency key, so retried identical\n * inputs name the same logical turn). Enable only when the wired delegate\n * dispatches via sandbox sessions — `createDefaultCoderDelegate` routes\n * onto its `driveTurn` tick path when the ref is present. Fanout\n * (`variants > 1`) never records a ref: one resume key cannot express N\n * sessions + winner selection.\n */\n detachedDispatch?: boolean\n}\n\n/** @experimental */\nexport function createDelegateCodeHandler(\n options: DelegateCodeHandlerOptions,\n): (raw: unknown) => Promise<DelegateCodeResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateCodeArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'coder',\n goal: args.goal,\n repoRoot: args.repoRoot,\n contextHint: args.contextHint,\n variants: args.variants ?? 1,\n config: args.config,\n namespace: args.namespace,\n })\n const detached = options.detachedDispatch === true && (args.variants ?? 1) <= 1\n const submitted = options.queue.submit<DelegateCodeArgs>({\n profile: 'coder',\n args,\n namespace: args.namespace,\n idempotencyKey,\n ...(detached\n ? {\n detachedSessionRef: formatDetachedSessionRef({\n sessionId: `dlg-turn-coder-${idempotencyKey}`,\n }),\n }\n : {}),\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: DelegateCodeArgs): number {\n const variants = Math.max(1, args.variants ?? 1)\n if (variants === 1) return SINGLE_VARIANT_ESTIMATE_MS\n return FANOUT_PER_VARIANT_ESTIMATE_MS\n}\n","/**\n * @experimental\n *\n * Feedback persistence surface for the MCP layer.\n *\n * The substrate cannot import `@tangle-network/agent-knowledge` (it would\n * induce a dependency cycle), so the store is an abstract interface. The\n * default implementation is in-memory; consumers wire their own adapter\n * (a real KbStore-backed sink, an HTTP relay to gtm-agent's knowledge\n * service, etc.) via `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\nimport type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types'\n\n/** @experimental */\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/** @experimental */\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/** @experimental */\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 * @experimental\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 * @experimental\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\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/** @experimental */\nexport const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback'\n\n/** @experimental */\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_code/delegate_research',\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/** @experimental */\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/** @experimental */\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/** @experimental */\nexport interface DelegateFeedbackHandlerOptions {\n queue: DelegationTaskQueue\n store: FeedbackStore\n generateId?: () => string\n now?: () => string\n}\n\n/** @experimental */\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 * @experimental\n *\n * `delegate_research` MCP tool — async kickoff for source-grounded\n * research tasks. Same async semantics as `delegate_code`: returns a\n * taskId immediately, idempotent on canonical inputs.\n *\n * The handler does not import a researcher profile directly — consumers\n * inject a `ResearcherDelegate` via `createMcpServer({ researcherDelegate })`.\n * The substrate cannot depend on `@tangle-network/agent-knowledge`\n * without inducing a dependency cycle.\n */\n\nimport type { ResearcherDelegate } from '../delegates'\nimport { formatDetachedSessionRef } from '../detached-turn'\nimport {\n type DelegateResearchArgs,\n type DelegateResearchResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\nimport type { ResearchSource } from '../types'\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_TOOL_NAME = 'delegate_research'\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_DESCRIPTION = [\n 'Delegate a research question to specialist researcher agents that produce',\n 'source-grounded, evidence-bearing knowledge items.',\n '',\n 'Use when: you need to answer a factual question with external evidence —',\n 'audience research, competitive intelligence, recency-bound web searches,',\n 'corpus / docs lookups. The researcher emits items[] with provenance, a',\n 'citations[] index, and proposedWrites[] you decide whether to persist.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'items + verdict. Identical inputs return the same taskId — safe to retry.',\n '',\n 'When variants > 1, multiple researcher harnesses run in parallel and the',\n 'highest-scoring valid output wins (citation density × source diversity ×',\n 'recency match × gap coverage). Use variants when answers might disagree.',\n '',\n 'Multi-tenant isolation: every item carries `namespace`. The validator',\n 'hard-fails when any item is scoped outside `namespace`. Never pass another',\n \"tenant's namespace.\",\n].join('\\n')\n\nconst VALID_SOURCES: readonly ResearchSource[] = ['web', 'corpus', 'twitter', 'github', 'docs']\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The research question to answer.',\n },\n namespace: {\n type: 'string',\n description: 'Multi-tenant scope (customer-id, workspace-id). REQUIRED.',\n },\n scope: { type: 'string', description: 'Bound, e.g. \"audience for cpg-founder ICP\".' },\n sources: {\n type: 'array',\n items: { type: 'string', enum: [...VALID_SOURCES] },\n },\n variants: { type: 'integer', minimum: 1, maximum: 8 },\n config: {\n type: 'object',\n properties: {\n recencyWindow: {\n type: 'object',\n properties: {\n since: { type: 'string', description: 'ISO datetime' },\n until: { type: 'string', description: 'ISO datetime' },\n },\n additionalProperties: false,\n },\n maxItems: { type: 'integer', minimum: 1 },\n minConfidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n additionalProperties: false,\n },\n },\n required: ['question', 'namespace'],\n additionalProperties: false,\n} as const\n\nconst SINGLE_VARIANT_ESTIMATE_MS = 4 * 60 * 1000\nconst FANOUT_PER_VARIANT_ESTIMATE_MS = 6 * 60 * 1000\n\n/** @experimental */\nexport function validateDelegateResearchArgs(raw: unknown): DelegateResearchArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_research: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const question = value.question\n if (typeof question !== 'string' || question.trim().length === 0) {\n throw new TypeError('delegate_research: `question` must be a non-empty string')\n }\n const namespace = value.namespace\n if (typeof namespace !== 'string' || namespace.trim().length === 0) {\n throw new TypeError('delegate_research: `namespace` is required')\n }\n const args: DelegateResearchArgs = { question: question.trim(), namespace: namespace.trim() }\n if (typeof value.scope === 'string') args.scope = value.scope\n if (value.sources !== undefined) {\n if (!Array.isArray(value.sources)) {\n throw new TypeError('delegate_research: `sources` must be a string array')\n }\n const sources: ResearchSource[] = value.sources.map((src, i) => {\n if (typeof src !== 'string' || !VALID_SOURCES.includes(src as ResearchSource)) {\n throw new TypeError(\n `delegate_research: sources[${i}] must be one of ${VALID_SOURCES.join('|')}`,\n )\n }\n return src as ResearchSource\n })\n args.sources = sources\n }\n if (value.variants !== undefined) {\n const variants = Number(value.variants)\n if (!Number.isFinite(variants) || variants < 1 || variants > 8) {\n throw new RangeError('delegate_research: `variants` must be an integer in [1, 8]')\n }\n args.variants = Math.trunc(variants)\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n return args\n}\n\nfunction validateConfig(raw: unknown): DelegateResearchArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_research: `config` must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: NonNullable<DelegateResearchArgs['config']> = {}\n if (value.recencyWindow !== undefined) {\n if (value.recencyWindow === null || typeof value.recencyWindow !== 'object') {\n throw new TypeError('delegate_research: `config.recencyWindow` must be an object')\n }\n const window = value.recencyWindow as Record<string, unknown>\n const windowOut: NonNullable<NonNullable<DelegateResearchArgs['config']>['recencyWindow']> = {}\n if (window.since !== undefined) {\n if (typeof window.since !== 'string' || Number.isNaN(Date.parse(window.since))) {\n throw new TypeError('delegate_research: `recencyWindow.since` must be an ISO datetime')\n }\n windowOut.since = window.since\n }\n if (window.until !== undefined) {\n if (typeof window.until !== 'string' || Number.isNaN(Date.parse(window.until))) {\n throw new TypeError('delegate_research: `recencyWindow.until` must be an ISO datetime')\n }\n windowOut.until = window.until\n }\n out.recencyWindow = windowOut\n }\n if (value.maxItems !== undefined) {\n const n = Number(value.maxItems)\n if (!Number.isFinite(n) || n < 1) {\n throw new RangeError('delegate_research: `config.maxItems` must be a positive integer')\n }\n out.maxItems = Math.trunc(n)\n }\n if (value.minConfidence !== undefined) {\n const n = Number(value.minConfidence)\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n throw new RangeError('delegate_research: `config.minConfidence` must be in [0, 1]')\n }\n out.minConfidence = n\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegateResearchHandlerOptions {\n queue: DelegationTaskQueue\n delegate: ResearcherDelegate\n estimateDurationMs?: (args: DelegateResearchArgs) => number\n /**\n * Record a deterministic detached-session resume key on single-variant\n * submissions. Same contract as `DelegateCodeHandlerOptions.detachedDispatch`.\n */\n detachedDispatch?: boolean\n}\n\n/** @experimental */\nexport function createDelegateResearchHandler(\n options: DelegateResearchHandlerOptions,\n): (raw: unknown) => Promise<DelegateResearchResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateResearchArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'researcher',\n question: args.question,\n namespace: args.namespace,\n scope: args.scope,\n sources: args.sources,\n variants: args.variants ?? 1,\n config: args.config,\n })\n const detached = options.detachedDispatch === true && (args.variants ?? 1) <= 1\n const submitted = options.queue.submit<DelegateResearchArgs>({\n profile: 'researcher',\n args,\n namespace: args.namespace,\n idempotencyKey,\n ...(detached\n ? {\n detachedSessionRef: formatDetachedSessionRef({\n sessionId: `dlg-turn-research-${idempotencyKey}`,\n }),\n }\n : {}),\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: DelegateResearchArgs): number {\n const variants = Math.max(1, args.variants ?? 1)\n if (variants === 1) return SINGLE_VARIANT_ESTIMATE_MS\n return FANOUT_PER_VARIANT_ESTIMATE_MS\n}\n","/**\n * @experimental\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\nimport type {\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history'\n\n/** @experimental */\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` (\"coder\" | \"researcher\"),',\n '`since` (ISO date — only delegations started at-or-after). `limit` defaults',\n 'to 50, capped at 500.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATION_HISTORY_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n namespace: { type: 'string' },\n profile: { type: 'string', enum: ['coder', 'researcher'] },\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/** @experimental */\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 (value.profile !== 'coder' && value.profile !== 'researcher') {\n throw new TypeError('delegation_history: `profile` must be \"coder\" or \"researcher\"')\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/** @experimental */\nexport interface DelegationHistoryHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** @experimental */\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 * @experimental\n *\n * `delegation_status` MCP tool — synchronous poll. Returns the current\n * state machine + optional progress + final result (when terminal).\n */\n\nimport { NotFoundError } from '../../errors'\nimport type {\n DelegationStatusArgs,\n DelegationStatusResult,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATION_STATUS_TOOL_NAME = 'delegation_status'\n\n/** @experimental */\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 called delegate_code or delegate_research and',\n \"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 coder task, `result.output` is a CoderOutput with branch,',\n 'patch, test/typecheck results, and diff stats. For a completed research',\n 'task, `result.output` is the items + citations + proposedWrites bundle.',\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/** @experimental */\nexport const DELEGATION_STATUS_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n taskId: { type: 'string', description: 'Returned by delegate_code / delegate_research.' },\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/** @experimental */\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/** @experimental */\nexport interface DelegationStatusHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** @experimental */\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"],"mappings":"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","names":["SINGLE_VARIANT_ESTIMATE_MS","FANOUT_PER_VARIANT_ESTIMATE_MS","validateConfig","defaultEstimate"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/delegation-profile.ts"],"sourcesContent":["/**\n * Production-profile composition for the agent-runtime delegation MCP.\n *\n * A product agent's sandbox loads the delegation tools (`delegate_code`,\n * `delegate_research`, `delegate_feedback`, `delegation_status`,\n * `delegation_history`) by mounting the `agent-runtime-mcp` stdio server as\n * an MCP entry in its `AgentProfile`. This module is the single composer for\n * that wiring, so every consumer — the fleet agents and agent-builder's\n * generated agents — shares one implementation instead of copying it.\n *\n * The load-bearing invariant: the delegation MCP entry is only ever emitted\n * when a sandbox API key is present. Without the key the kernel's\n * coder/researcher delegate cannot construct an authenticated sandbox client,\n * so we omit the entry rather than ship an MCP child that fails to\n * authenticate on startup. No static profile entry, ever.\n */\n\nimport type {\n AgentProfile,\n AgentProfileFileMount,\n AgentProfileMcpServer,\n AgentSubagentProfile,\n} from '@tangle-network/sandbox'\n\n/** One hook command entry. The SDK declares `AgentProfile.hooks` as\n * `Record<string, AgentProfileHookCommand[]>` but does not re-export the element\n * type from the package entry, so derive it from `AgentProfile` by indexed\n * access — the single source of truth, no drift from the SDK shape. */\ntype AgentProfileHookCommand = NonNullable<AgentProfile['hooks']>[string][number]\n\n/** MCP server key under which the agent-runtime delegation tools mount. */\nexport const DELEGATION_MCP_SERVER_KEY = 'agent-runtime-delegation'\n\n/**\n * Env vars forwarded into the delegation MCP child so its delegated\n * build/research loops export topology spans to the configured OTLP /\n * Tangle Intelligence sink. Each is forwarded only when present, so the\n * child is a no-op exporter until `OTEL_EXPORTER_OTLP_ENDPOINT` is set in the\n * parent env — never a hardcoded endpoint.\n */\nconst OTEL_FORWARD_KEYS = [\n 'OTEL_EXPORTER_OTLP_ENDPOINT',\n 'OTEL_EXPORTER_OTLP_HEADERS',\n 'TRACE_ID',\n 'PARENT_SPAN_ID',\n] as const\n\nconst DEFAULT_SANDBOX_BASE_URL = 'https://sandbox.tangle.tools'\n\nexport interface BuildDelegationMcpServerOptions {\n /** Sandbox API key forwarded as `TANGLE_API_KEY` to the MCP child. The\n * agent-runtime MCP bin reads `TANGLE_API_KEY` and passes it straight to\n * `new Sandbox({ apiKey })`. Defaults to `env.TANGLE_API_KEY`. */\n sandboxApiKey?: string\n /** Sandbox base URL forwarded as `SANDBOX_BASE_URL`. Defaults to\n * `env.SANDBOX_BASE_URL`, then `env.SANDBOX_API_URL`, then the public\n * sandbox endpoint. */\n sandboxBaseUrl?: string\n /** Environment source for key + OTEL resolution. Defaults to `process.env`;\n * injectable for tests and non-process callers. */\n env?: Record<string, string | undefined>\n}\n\n/**\n * Build the delegation MCP entry the sandbox-side agent loads on startup.\n * Returns `undefined` when no sandbox API key is resolvable — callers merge\n * the result into a profile's `mcp` map only when defined.\n */\nexport function buildDelegationMcpServer(\n options: BuildDelegationMcpServerOptions = {},\n): Record<string, AgentProfileMcpServer> | undefined {\n const env = options.env ?? process.env\n const sandboxApiKey = options.sandboxApiKey ?? env.TANGLE_API_KEY\n if (!sandboxApiKey) return undefined\n const baseUrl =\n options.sandboxBaseUrl ??\n env.SANDBOX_BASE_URL ??\n env.SANDBOX_API_URL ??\n DEFAULT_SANDBOX_BASE_URL\n\n const otelEnv: Record<string, string> = {}\n for (const key of OTEL_FORWARD_KEYS) {\n const value = env[key]\n if (value) otelEnv[key] = value\n }\n\n return {\n [DELEGATION_MCP_SERVER_KEY]: {\n transport: 'stdio',\n command: 'npx',\n args: ['-y', '@tangle-network/agent-runtime', 'mcp'],\n env: {\n TANGLE_API_KEY: sandboxApiKey,\n SANDBOX_BASE_URL: baseUrl,\n ...otelEnv,\n },\n enabled: true,\n metadata: {\n surface: 'delegation:dispatch',\n tools: [\n 'delegate_code',\n 'delegate_research',\n 'delegate_feedback',\n 'delegation_status',\n 'delegation_history',\n ],\n },\n },\n }\n}\n\nexport interface ComposeProductionAgentProfileOptions {\n /** Sandbox API key forwarded to the delegation MCP child. Defaults to\n * `env.TANGLE_API_KEY`. When unset, the delegation MCP entry is omitted. */\n sandboxApiKey?: string\n /** Sandbox base URL forwarded as `SANDBOX_BASE_URL` to the MCP child. */\n sandboxBaseUrl?: string\n /** Replace the base profile's system prompt. Used by per-turn calls that\n * swap in workspace-augmented prompts (board summary, learned style). */\n systemPrompt?: string\n /** Extra file mounts layered after the base profile's `resources.files`. */\n extraFiles?: AgentProfileFileMount[]\n /** Override the profile `name`. Defaults to the base profile's name. */\n name?: string\n /** Environment source for key + OTEL resolution. Defaults to `process.env`. */\n env?: Record<string, string | undefined>\n /** Box built-in tool ON/OFF flags merged over the base profile's `tools`\n * (overlay wins per key). The sandbox-seam mapping of a certified surface's\n * tool grants — `AgentProfile.tools` is `Record<string, boolean>` box flags,\n * so it carries grants, not arbitrary tool defs. */\n tools?: Record<string, boolean>\n /** Per-event hook commands merged over the base profile's `hooks`. An event\n * present in both has the extra commands appended after the base ones. */\n hooks?: Record<string, AgentProfileHookCommand[]>\n /** Subagent definitions merged over the base profile's `subagents` (overlay\n * wins per key). */\n subagents?: Record<string, AgentSubagentProfile>\n /** Resolved certified MCP connections injected into `AgentProfile.mcp` — the\n * sandbox-seam delivery of a `ResolvedSurface.mcpConnections`. Merged after\n * the base map and before the delegation entry, so a base/delegation key is\n * never silently shadowed by an injected one. */\n mcpConnections?: Record<string, AgentProfileMcpServer>\n}\n\n/**\n * Compose the production `AgentProfile`: the canonical base profile with the\n * delegation MCP merged into `mcp`. Used by every call site that boots a\n * sandbox or runs a chat turn through the sandbox path, and by eval wiring so\n * the scorecard profile hash reflects the actual production profile.\n *\n * Merge rules:\n * - `mcp`: base map preserved; `options.mcpConnections` (resolved certified\n * servers) merged over it; the delegation entry is appended last under\n * {@link DELEGATION_MCP_SERVER_KEY}, and omitted entirely when no sandbox\n * API key resolves.\n * - `tools`: base box-flags map preserved; `options.tools` overlaid per key.\n * - `hooks`: per event, base commands preserved; `options.hooks[event]`\n * appended after the base ones.\n * - `subagents`: base map preserved; `options.subagents` overlaid per key.\n * - `prompt.systemPrompt`: replaced when `options.systemPrompt` is set.\n * - `resources.files`: `options.extraFiles` concatenated after base files.\n * - `name`: replaced when `options.name` is set.\n */\nexport function composeProductionAgentProfile(\n baseProfile: AgentProfile,\n options: ComposeProductionAgentProfileOptions = {},\n): AgentProfile {\n const delegationMcp = buildDelegationMcpServer({\n sandboxApiKey: options.sandboxApiKey,\n sandboxBaseUrl: options.sandboxBaseUrl,\n env: options.env,\n })\n\n const baseMcp = baseProfile.mcp ?? {}\n const withInjected: Record<string, AgentProfileMcpServer> = options.mcpConnections\n ? { ...baseMcp, ...options.mcpConnections }\n : { ...baseMcp }\n const mergedMcp: Record<string, AgentProfileMcpServer> = delegationMcp\n ? { ...withInjected, ...delegationMcp }\n : withInjected\n\n const baseFiles = baseProfile.resources?.files ?? []\n const mergedFiles: AgentProfileFileMount[] = options.extraFiles?.length\n ? [...baseFiles, ...options.extraFiles]\n : [...baseFiles]\n\n const prompt = options.systemPrompt\n ? { ...baseProfile.prompt, systemPrompt: options.systemPrompt }\n : baseProfile.prompt\n\n const mergedTools = options.tools\n ? { ...(baseProfile.tools ?? {}), ...options.tools }\n : baseProfile.tools\n\n const mergedHooks = mergeHooks(baseProfile.hooks, options.hooks)\n\n const mergedSubagents = options.subagents\n ? { ...(baseProfile.subagents ?? {}), ...options.subagents }\n : baseProfile.subagents\n\n return {\n ...baseProfile,\n name: options.name ?? baseProfile.name,\n prompt,\n ...(mergedTools ? { tools: mergedTools } : {}),\n ...(mergedHooks ? { hooks: mergedHooks } : {}),\n ...(mergedSubagents ? { subagents: mergedSubagents } : {}),\n mcp: mergedMcp,\n resources: {\n ...baseProfile.resources,\n files: mergedFiles,\n },\n }\n}\n\n/** Merge per-event hook command lists: base commands first, overlay commands\n * appended after. Returns the base map unchanged when no overlay is given. */\nfunction mergeHooks(\n base: Record<string, AgentProfileHookCommand[]> | undefined,\n overlay: Record<string, AgentProfileHookCommand[]> | undefined,\n): Record<string, AgentProfileHookCommand[]> | undefined {\n if (!overlay) return base\n const merged: Record<string, AgentProfileHookCommand[]> = { ...(base ?? {}) }\n for (const [event, commands] of Object.entries(overlay)) {\n merged[event] = [...(merged[event] ?? []), ...commands]\n }\n return merged\n}\n"],"mappings":";AA+BO,IAAM,4BAA4B;AASzC,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,2BAA2B;AAqB1B,SAAS,yBACd,UAA2C,CAAC,GACO;AACnD,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,gBAAgB,QAAQ,iBAAiB,IAAI;AACnD,MAAI,CAAC,cAAe,QAAO;AAC3B,QAAM,UACJ,QAAQ,kBACR,IAAI,oBACJ,IAAI,mBACJ;AAEF,QAAM,UAAkC,CAAC;AACzC,aAAW,OAAO,mBAAmB;AACnC,UAAM,QAAQ,IAAI,GAAG;AACrB,QAAI,MAAO,SAAQ,GAAG,IAAI;AAAA,EAC5B;AAEA,SAAO;AAAA,IACL,CAAC,yBAAyB,GAAG;AAAA,MAC3B,WAAW;AAAA,MACX,SAAS;AAAA,MACT,MAAM,CAAC,MAAM,iCAAiC,KAAK;AAAA,MACnD,KAAK;AAAA,QACH,gBAAgB;AAAA,QAChB,kBAAkB;AAAA,QAClB,GAAG;AAAA,MACL;AAAA,MACA,SAAS;AAAA,MACT,UAAU;AAAA,QACR,SAAS;AAAA,QACT,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAsDO,SAAS,8BACd,aACA,UAAgD,CAAC,GACnC;AACd,QAAM,gBAAgB,yBAAyB;AAAA,IAC7C,eAAe,QAAQ;AAAA,IACvB,gBAAgB,QAAQ;AAAA,IACxB,KAAK,QAAQ;AAAA,EACf,CAAC;AAED,QAAM,UAAU,YAAY,OAAO,CAAC;AACpC,QAAM,eAAsD,QAAQ,iBAChE,EAAE,GAAG,SAAS,GAAG,QAAQ,eAAe,IACxC,EAAE,GAAG,QAAQ;AACjB,QAAM,YAAmD,gBACrD,EAAE,GAAG,cAAc,GAAG,cAAc,IACpC;AAEJ,QAAM,YAAY,YAAY,WAAW,SAAS,CAAC;AACnD,QAAM,cAAuC,QAAQ,YAAY,SAC7D,CAAC,GAAG,WAAW,GAAG,QAAQ,UAAU,IACpC,CAAC,GAAG,SAAS;AAEjB,QAAM,SAAS,QAAQ,eACnB,EAAE,GAAG,YAAY,QAAQ,cAAc,QAAQ,aAAa,IAC5D,YAAY;AAEhB,QAAM,cAAc,QAAQ,QACxB,EAAE,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ,MAAM,IACjD,YAAY;AAEhB,QAAM,cAAc,WAAW,YAAY,OAAO,QAAQ,KAAK;AAE/D,QAAM,kBAAkB,QAAQ,YAC5B,EAAE,GAAI,YAAY,aAAa,CAAC,GAAI,GAAG,QAAQ,UAAU,IACzD,YAAY;AAEhB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,QAAQ,QAAQ,YAAY;AAAA,IAClC;AAAA,IACA,GAAI,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AAAA,IAC5C,GAAI,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AAAA,IAC5C,GAAI,kBAAkB,EAAE,WAAW,gBAAgB,IAAI,CAAC;AAAA,IACxD,KAAK;AAAA,IACL,WAAW;AAAA,MACT,GAAG,YAAY;AAAA,MACf,OAAO;AAAA,IACT;AAAA,EACF;AACF;AAIA,SAAS,WACP,MACA,SACuD;AACvD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,SAAoD,EAAE,GAAI,QAAQ,CAAC,EAAG;AAC5E,aAAW,CAAC,OAAO,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACvD,WAAO,KAAK,IAAI,CAAC,GAAI,OAAO,KAAK,KAAK,CAAC,GAAI,GAAG,QAAQ;AAAA,EACxD;AACA,SAAO;AACT;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loop-runner.ts","../src/loop-runner-bin.ts"],"sourcesContent":["/**\n * @experimental\n *\n * `runDelegatedLoop` — the configured delegated loop-runner.\n *\n * One typed entrypoint a worker agent (or a scheduled routine) calls to run a\n * disciplined loop in a chosen MODE, over agent-runtime's hardened engines:\n *\n * code → build-in-a-loop via the coder delegate (no-op + secret floor,\n * optional reviewer gate, winner-selection)\n * review → code mode with a REQUIRED reviewer (the gate is the point)\n * research → research-in-a-loop with valid-only KB growth (createKbGate)\n * audit → analyze trace/run data → findings (runAnalystLoop, caller-wired)\n * self-improve → closed-loop text/config optimization (selfImprove, held-out gated)\n * dynamic → agent-authored topology (runLoop + createDriver)\n *\n * It is intentionally a thin façade: the value is that EVERY product reuses the\n * one hardened engine instead of forking delegation logic. The dispatcher owns\n * mode routing, timing, fail-loud on an unregistered mode, and a uniform result\n * shape; each mode's engine is a pre-configured runner in the registry (build it\n * with the factories below, or inject your own / a stub).\n */\n\nimport type { Scenario } from '@tangle-network/agent-eval/campaign'\nimport {\n type SelfImproveOptions,\n type SelfImproveResult,\n selfImprove,\n} from '@tangle-network/agent-eval/contract'\nimport { runAnalystLoop } from './analyst-loop'\nimport type { RunAnalystLoopOpts, RunAnalystLoopResult } from './analyst-loop/types'\nimport { ConfigError } from './errors'\nimport {\n type CoderReviewer,\n type CoderWinnerSelection,\n createDefaultCoderDelegate,\n type DelegateRunCtx,\n} from './mcp/delegates'\nimport { type CreateKbGateOptions, createKbGate, type FactCandidate } from './mcp/kb-gate'\nimport type { DelegateCodeArgs } from './mcp/types'\nimport type { CoderOutput } from './profiles/coder'\nimport {\n type AgentRunSpec,\n type CreateDriverOptions,\n createDriver,\n type DriverDecision,\n type LoopResult,\n type OutputAdapter,\n runLoop,\n type SandboxClient,\n type TopologyPlanner,\n type Validator,\n} from './runtime'\n\n/** @experimental Every delegated-loop mode, for validation + CLI surfaces. */\nexport const DELEGATED_LOOP_MODES = [\n 'code',\n 'review',\n 'research',\n 'audit',\n 'self-improve',\n 'dynamic',\n] as const\n\n/** @experimental */\nexport type DelegatedLoopMode = (typeof DELEGATED_LOOP_MODES)[number]\n\n/** @experimental Type guard for an untrusted mode string (CLI / config input). */\nexport function isDelegatedLoopMode(value: unknown): value is DelegatedLoopMode {\n return typeof value === 'string' && (DELEGATED_LOOP_MODES as readonly string[]).includes(value)\n}\n\n/** @experimental A pre-configured loop for one mode. Returns the mode's raw\n * output; the dispatcher wraps it in a {@link DelegatedLoopResult}. */\nexport type DelegatedLoopRunner<T = unknown> = (signal: AbortSignal) => Promise<T>\n\n/** @experimental Mode → configured runner. Partial: only register the modes a\n * given product/routine actually uses. */\nexport type DelegatedLoopRegistry = Partial<Record<DelegatedLoopMode, DelegatedLoopRunner>>\n\n/** @experimental Uniform result — never throws from a registered runner; a\n * thrown engine becomes `{ ok: false, error }` so a routine can record + move on. */\nexport interface DelegatedLoopResult<T = unknown> {\n mode: DelegatedLoopMode\n ok: boolean\n output?: T\n error?: string\n durationMs: number\n}\n\n/** @experimental */\nexport interface RunDelegatedLoopOptions {\n signal?: AbortSignal\n /** Clock override for deterministic tests. */\n now?: () => number\n}\n\n/**\n * @experimental\n *\n * Dispatch a configured loop by mode. Fails loud (throws `ConfigError`) when no\n * runner is registered for the mode — a routine pointed at an unwired mode is a\n * config bug, not a silent no-op. A runner that throws is captured as\n * `{ ok: false }` so unattended runs record the failure rather than crash.\n */\nexport async function runDelegatedLoop<T = unknown>(\n mode: DelegatedLoopMode,\n registry: DelegatedLoopRegistry,\n options: RunDelegatedLoopOptions = {},\n): Promise<DelegatedLoopResult<T>> {\n const runner = registry[mode] as DelegatedLoopRunner<T> | undefined\n if (!runner) {\n throw new ConfigError(\n `runDelegatedLoop: no runner registered for mode '${mode}' (registered: ${\n Object.keys(registry).join(', ') || 'none'\n })`,\n )\n }\n const now = options.now ?? Date.now\n const signal = options.signal ?? new AbortController().signal\n const start = now()\n try {\n const output = await runner(signal)\n return { mode, ok: true, output, durationMs: now() - start }\n } catch (err) {\n return {\n mode,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n durationMs: now() - start,\n }\n }\n}\n\n/** @experimental Options for the default `code`/`review` runner. */\nexport interface CoderLoopRunnerOptions {\n sandboxClient: SandboxClient\n /** What to build — the delegate args (goal, repoRoot, variants, config, …). */\n args: DelegateCodeArgs\n /** Adversarial reviewer. REQUIRED for `review` mode (see `reviewLoopRunner`). */\n reviewer?: CoderReviewer\n /** Winner-selection strategy. Default `highest-score`. */\n winnerSelection?: CoderWinnerSelection\n /** Harnesses for `variants > 1` fanout. */\n fanoutHarnesses?: string[]\n}\n\n/** @experimental Build a `code`-mode runner over the hardened coder delegate. */\nexport function coderLoopRunner(options: CoderLoopRunnerOptions): DelegatedLoopRunner<CoderOutput> {\n const delegate = createDefaultCoderDelegate({\n sandboxClient: options.sandboxClient,\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n ...(options.winnerSelection ? { winnerSelection: options.winnerSelection } : {}),\n ...(options.fanoutHarnesses ? { fanoutHarnesses: options.fanoutHarnesses } : {}),\n })\n return async (signal) => {\n const ctx: DelegateRunCtx = { signal, report: () => {} }\n return delegate(options.args, ctx)\n }\n}\n\n/**\n * @experimental\n *\n * `review` mode = `code` with a REQUIRED reviewer. The gate is the whole point,\n * so the type forces a reviewer (a \"review loop\" with no reviewer is a code loop).\n */\nexport function reviewLoopRunner(\n options: CoderLoopRunnerOptions & { reviewer: CoderReviewer },\n): DelegatedLoopRunner<CoderOutput> {\n return coderLoopRunner(options)\n}\n\n/** @experimental Options for the default `dynamic` runner. */\nexport interface DynamicLoopRunnerOptions<Task, Output> {\n sandboxClient: SandboxClient\n /** The agent-authored topology planner (sync or async; an async planner is where an LLM call goes). */\n planner: TopologyPlanner<Task, Output>\n task: Task\n output: OutputAdapter<Output>\n validator?: Validator<Output>\n /** Exactly one of `agentRun` / `agentRuns` (runLoop validates). */\n agentRun?: AgentRunSpec<Task>\n agentRuns?: AgentRunSpec<Task>[]\n maxIterations?: number\n maxFanout?: number\n /** Optional trace-analyst hook forwarded to the dynamic driver so the loop runs\n * `f(trace, findings)` — see `CreateDriverOptions.analyze`. Caller-side\n * seam to `runAnalystLoop`; keeps this runner analyst-free. */\n analyze?: CreateDriverOptions<Task, Output>['analyze']\n}\n\n/** @experimental `dynamic` mode — agent-authored topology over `runLoop`. */\nexport function dynamicLoopRunner<Task, Output>(\n o: DynamicLoopRunnerOptions<Task, Output>,\n): DelegatedLoopRunner<LoopResult<Task, Output, DriverDecision>> {\n return async (signal) =>\n runLoop<Task, Output, DriverDecision>({\n driver: createDriver<Task, Output>({\n planner: o.planner,\n ...(o.maxIterations !== undefined ? { maxIterations: o.maxIterations } : {}),\n ...(o.maxFanout !== undefined ? { maxFanout: o.maxFanout } : {}),\n ...(o.analyze ? { analyze: o.analyze } : {}),\n }),\n ...(o.agentRun ? { agentRun: o.agentRun } : {}),\n ...(o.agentRuns ? { agentRuns: o.agentRuns } : {}),\n output: o.output,\n ...(o.validator ? { validator: o.validator } : {}),\n task: o.task,\n ctx: { sandboxClient: o.sandboxClient, signal },\n ...(o.maxIterations !== undefined ? { maxIterations: o.maxIterations } : {}),\n })\n}\n\n/** @experimental A fact rejected at the KB gate — surfaced, never dropped. */\nexport interface VetoedFact {\n candidate: FactCandidate\n vetoedBy?: string\n reason?: string\n}\n\n/** @experimental */\nexport interface ResearchLoopResult {\n /** Facts that passed the fail-closed gate — safe to write to the KB. */\n accepted: FactCandidate[]\n /** Facts the gate vetoed in the final round — escalate, do not silently drop. */\n vetoed: VetoedFact[]\n /** Research rounds actually run. */\n rounds: number\n}\n\n/** @experimental Options for the default `research` runner. */\nexport interface ResearchLoopRunnerOptions {\n /**\n * The research engine (the consumer's web/doc searcher + extractor). Called\n * each round with the prior round's vetoes so it can re-research the gaps.\n * Returns fact candidates carrying their grounding (`verbatimPassage` +\n * `sourceText`).\n */\n research: (round: number, vetoed: VetoedFact[]) => Promise<FactCandidate[]>\n /** Gate config (extra judges, self-artifact kinds, …). The floor is always on. */\n gate?: CreateKbGateOptions\n /** Max research rounds (correct-on-veto remediation). Default 1. */\n maxRounds?: number\n}\n\n/**\n * @experimental `research` mode — research-in-a-loop with valid-only KB growth.\n *\n * Each round: research → gate every candidate (fail-closed; passage MUST be in\n * the source) → accept the clean ones → re-research the vetoed ones next round,\n * up to `maxRounds`. Vetoed facts in the final round are RETURNED (escalate,\n * never silently dropped) so the caller audits vs retries.\n */\nexport function researchLoopRunner(\n o: ResearchLoopRunnerOptions,\n): DelegatedLoopRunner<ResearchLoopResult> {\n const gate = createKbGate(o.gate)\n const maxRounds = Math.max(1, Math.trunc(o.maxRounds ?? 1))\n return async (signal) => {\n const accepted: FactCandidate[] = []\n let vetoed: VetoedFact[] = []\n let rounds = 0\n for (let round = 0; round < maxRounds; round += 1) {\n if (signal.aborted) break\n rounds += 1\n const candidates = await o.research(round, vetoed)\n if (candidates.length === 0) break\n vetoed = []\n for (const c of candidates) {\n const v = await gate(c)\n if (v.accepted) accepted.push(c)\n else vetoed.push({ candidate: c, vetoedBy: v.vetoedBy, reason: v.reason })\n }\n if (vetoed.length === 0) break\n }\n return { accepted, vetoed, rounds }\n }\n}\n\n/** @experimental `self-improve` mode — agent-eval's one-call closed loop (held-out gated). */\nexport function selfImproveLoopRunner<TScenario extends Scenario, TArtifact>(\n options: SelfImproveOptions<TScenario, TArtifact>,\n): DelegatedLoopRunner<SelfImproveResult<TScenario, TArtifact>> {\n return async () => selfImprove<TScenario, TArtifact>(options)\n}\n\n/** @experimental `audit` mode — analyst loop over captured trace/run data. */\nexport function auditLoopRunner<TProposal = unknown, TEdit = unknown>(\n options: RunAnalystLoopOpts,\n): DelegatedLoopRunner<RunAnalystLoopResult<TProposal, TEdit>> {\n return async () => runAnalystLoop<TProposal, TEdit>(options)\n}\n","#!/usr/bin/env node\n/**\n * @experimental\n *\n * `agent-runtime-loop` — the schedulable entrypoint for the configured\n * delegated loop-runner. A cron job / routine / Makefile target invokes:\n *\n * agent-runtime-loop --mode research --config ./loops.config.js\n *\n * The config module wires the registry (with full access to env / creds —\n * which is why the deps live there, not in this generic bin). It must default-\n * export a `DelegatedLoopRegistry`, or a `() => DelegatedLoopRegistry | Promise<…>`.\n * The bin runs the selected mode, prints the `DelegatedLoopResult` as JSON, and\n * exits 0 on `ok`, 1 on a recorded failure, 2 on a usage/config error.\n */\n\nimport {\n DELEGATED_LOOP_MODES,\n type DelegatedLoopMode,\n type DelegatedLoopRegistry,\n type DelegatedLoopResult,\n isDelegatedLoopMode,\n runDelegatedLoop,\n} from './loop-runner'\n\n/** @experimental Parsed CLI invocation. */\nexport interface LoopRunnerCliArgs {\n mode: string\n /** Loads the registry — the bin wires this from `--config`; tests inject a stub. */\n loadRegistry: () => Promise<DelegatedLoopRegistry> | DelegatedLoopRegistry\n now?: () => number\n}\n\n/** @experimental */\nexport interface LoopRunnerCliResult {\n exitCode: number\n result?: DelegatedLoopResult\n error?: string\n}\n\n/**\n * @experimental\n *\n * Pure CLI core (no process / argv / IO) so it's unit-testable: validate the\n * mode, load the registry, dispatch, map to an exit code (0 ok / 1 failed /\n * 2 usage). Exported for embedding in custom runners + tests.\n */\nexport async function runLoopRunnerCli(args: LoopRunnerCliArgs): Promise<LoopRunnerCliResult> {\n if (!isDelegatedLoopMode(args.mode)) {\n return {\n exitCode: 2,\n error: `unknown mode '${args.mode}' (expected one of: ${DELEGATED_LOOP_MODES.join(', ')})`,\n }\n }\n let registry: DelegatedLoopRegistry\n try {\n registry = await args.loadRegistry()\n } catch (err) {\n return { exitCode: 2, error: `failed to load registry: ${errMsg(err)}` }\n }\n if (!registry[args.mode]) {\n return {\n exitCode: 2,\n error: `config registers no runner for mode '${args.mode}' (registered: ${\n Object.keys(registry).join(', ') || 'none'\n })`,\n }\n }\n // runDelegatedLoop throws only on a missing runner (guarded above); a failing\n // engine is captured as { ok: false } → exit 1, not a crash.\n const result = await runDelegatedLoop(args.mode as DelegatedLoopMode, registry, {\n ...(args.now ? { now: args.now } : {}),\n })\n return { exitCode: result.ok ? 0 : 1, result }\n}\n\n/** Parse `--mode X --config Y` from an argv tail (`process.argv.slice(2)`). */\nexport function parseLoopRunnerArgv(argv: string[]): { mode?: string; config?: string } {\n const out: { mode?: string; config?: string } = {}\n for (let i = 0; i < argv.length; i += 1) {\n const a = argv[i]\n if (a === '--mode') out.mode = argv[++i]\n else if (a === '--config') out.config = argv[++i]\n else if (a?.startsWith('--mode=')) out.mode = a.slice('--mode='.length)\n else if (a?.startsWith('--config=')) out.config = a.slice('--config='.length)\n }\n return out\n}\n\n/** Normalize a config module's default export → a registry. */\nfunction resolveRegistry(mod: unknown): DelegatedLoopRegistry {\n const def = (mod as { default?: unknown })?.default ?? mod\n const value = typeof def === 'function' ? (def as () => unknown)() : def\n return value as DelegatedLoopRegistry\n}\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/** The argv → IO → exit shell. Kept thin; logic lives in `runLoopRunnerCli`. */\nasync function main(): Promise<void> {\n const { mode, config } = parseLoopRunnerArgv(process.argv.slice(2))\n if (!mode || !config) {\n process.stderr.write(\n 'usage: agent-runtime-loop --mode <mode> --config <module>\\n' +\n ` modes: ${DELEGATED_LOOP_MODES.join(' | ')}\\n` +\n ' config: a JS/TS module default-exporting a DelegatedLoopRegistry (or a factory)\\n',\n )\n process.exit(2)\n }\n const { pathToFileURL } = await import('node:url')\n const { resolve } = await import('node:path')\n const cli = await runLoopRunnerCli({\n mode,\n loadRegistry: async () => resolveRegistry(await import(pathToFileURL(resolve(config)).href)),\n })\n process.stdout.write(`${JSON.stringify(cli.result ?? { error: cli.error }, null, 2)}\\n`)\n if (cli.error) process.stderr.write(`${cli.error}\\n`)\n process.exit(cli.exitCode)\n}\n\n// Run only when executed as the bin — never when imported for the testable\n// core, and never when bundled into a runtime that has no `process.argv`\n// (e.g. Cloudflare Workers, where `process` is a shim without `argv`). Reading\n// `process.argv[1]` directly would throw at module load there; `process.argv?.`\n// keeps the guard a no-op instead of crashing the Worker on startup.\nconst invokedScript = typeof process !== 'undefined' ? process.argv?.[1] : undefined\nif (invokedScript && /loop-runner-bin\\.(js|ts|mjs)$/.test(invokedScript)) {\n void main()\n}\n"],"mappings":"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","names":[]}
|