@tangle-network/agent-runtime 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/agent.d.ts +57 -2
  2. package/dist/agent.js +54 -0
  3. package/dist/agent.js.map +1 -1
  4. package/dist/chunk-7JITYN6T.js +72 -0
  5. package/dist/chunk-7JITYN6T.js.map +1 -0
  6. package/dist/{chunk-3WQJRSUJ.js → chunk-BDGYYO7K.js} +3 -3
  7. package/dist/{chunk-6HI3QUJD.js → chunk-HCL2ZG5L.js} +51 -5
  8. package/dist/chunk-HCL2ZG5L.js.map +1 -0
  9. package/dist/{chunk-HSX6PFZR.js → chunk-HVYOHJHK.js} +338 -2
  10. package/dist/chunk-HVYOHJHK.js.map +1 -0
  11. package/dist/{chunk-OISRXLWI.js → chunk-IFG6GX6A.js} +64 -40
  12. package/dist/chunk-IFG6GX6A.js.map +1 -0
  13. package/dist/chunk-NRZOXCJK.js +64 -0
  14. package/dist/chunk-NRZOXCJK.js.map +1 -0
  15. package/dist/{chunk-VFKBIZTY.js → chunk-WMBYQPYM.js} +5 -4
  16. package/dist/chunk-WMBYQPYM.js.map +1 -0
  17. package/dist/delegation-profile-1GbW5yA3.d.ts +73 -0
  18. package/dist/{dynamic-BT9Ji3jE.d.ts → dynamic-B_7GgCwu.d.ts} +1 -1
  19. package/dist/index.d.ts +7 -8
  20. package/dist/index.js +9 -8
  21. package/dist/index.js.map +1 -1
  22. package/dist/{kb-gate-C4tho31v.d.ts → kb-gate-DTBum3vH.d.ts} +9 -1
  23. package/dist/{loop-runner-bin-C1MuoT8c.d.ts → loop-runner-bin-CVoCBmYk.d.ts} +3 -3
  24. package/dist/loop-runner-bin.d.ts +4 -5
  25. package/dist/loop-runner-bin.js +3 -3
  26. package/dist/loops.d.ts +65 -7
  27. package/dist/loops.js +7 -1
  28. package/dist/mcp/bin.js +28 -17
  29. package/dist/mcp/bin.js.map +1 -1
  30. package/dist/mcp/index.d.ts +6 -6
  31. package/dist/mcp/index.js +17 -49
  32. package/dist/mcp/index.js.map +1 -1
  33. package/dist/{otel-export-xgf4J6bo.d.ts → otel-export-BzvF1Ela.d.ts} +1 -1
  34. package/dist/profiles.d.ts +1 -2
  35. package/dist/{types-CNs7_1R3.d.ts → types-Bcp071Jg.d.ts} +488 -3
  36. package/package.json +11 -22
  37. package/dist/chunk-6HI3QUJD.js.map +0 -1
  38. package/dist/chunk-7ZECSZ3C.js +0 -400
  39. package/dist/chunk-7ZECSZ3C.js.map +0 -1
  40. package/dist/chunk-HSX6PFZR.js.map +0 -1
  41. package/dist/chunk-OISRXLWI.js.map +0 -1
  42. package/dist/chunk-VFKBIZTY.js.map +0 -1
  43. package/dist/types-CsCCryln.d.ts +0 -489
  44. /package/dist/{chunk-3WQJRSUJ.js.map → chunk-BDGYYO7K.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../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","../src/otel-export.ts"],"sourcesContent":["/**\n * @experimental\n *\n * In-memory state for async MCP delegations. State machine:\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 * Persistent state (sqlite) is a Phase 2 follow-up. The README documents the\n * in-memory limitation explicitly so consumers know a worker restart drops\n * pending delegations.\n */\n\nimport type {\n DelegateCodeArgs,\n DelegateResearchArgs,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusResult,\n} from './types'\n\n/** @experimental */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegateCodeArgs | DelegateResearchArgs\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 /** Feedback events keyed by this delegation's taskId. */\n feedback: DelegationFeedbackSnapshot[]\n}\n\n/** @experimental */\nexport interface SubmitInput<Args extends DelegateCodeArgs | DelegateResearchArgs> {\n profile: DelegationProfile\n args: Args\n namespace?: string\n idempotencyKey?: 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: {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n }) => Promise<DelegationResultPayload['output']>\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/** @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\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\n constructor(options: DelegationTaskQueueOptions = {}) {\n this.generateId = options.generateId ?? randomTaskId\n this.now = options.now ?? (() => new Date().toISOString())\n }\n\n /**\n * Kick off a delegation in the background. Returns immediately. The\n * `taskId` is queryable via `status` once this method returns.\n */\n submit<Args extends DelegateCodeArgs | DelegateResearchArgs>(\n input: SubmitInput<Args>,\n ): SubmitOutput {\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 }\n this.records.set(taskId, record)\n this.controllers.set(taskId, controller)\n if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId)\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 */\n status(taskId: string): DelegationStatusResult | undefined {\n const record = this.records.get(taskId)\n if (!record) return undefined\n return toStatusResult(record)\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 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 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 /** 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 DelegateCodeArgs | DelegateResearchArgs>(\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 try {\n const output = await input.run({\n signal: controller.signal,\n report: (progress) => {\n if (record.status === 'running') record.progress = progress\n },\n })\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 } catch (err) {\n if (currentStatus(record) === 'cancelled') return\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n } finally {\n this.controllers.delete(taskId)\n }\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 toStatusResult(record: DelegationRecord): 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 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 }\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 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 DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\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 {\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\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 submitted = options.queue.submit<DelegateCodeArgs>({\n profile: 'coder',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: 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 {\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\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 submitted = options.queue.submit<DelegateResearchArgs>({\n profile: 'researcher',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: 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 '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 '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 },\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 return { taskId: taskId.trim() }\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(args.taskId)\n if (!status) {\n throw new NotFoundError(`delegation_status: unknown taskId \"${args.taskId}\"`)\n }\n return status\n }\n}\n","/**\n * OTEL span exporter — streams LoopTraceEvents to an OTLP/HTTP collector.\n *\n * Reads OTEL_EXPORTER_OTLP_ENDPOINT + OTEL_EXPORTER_OTLP_HEADERS from env\n * when no explicit config is given. Keeps the runtime dep-free from\n * @opentelemetry/sdk-trace-base — minimal OTLP/JSON serializer.\n *\n * The exporter accepts both raw OtelSpan objects and LoopTraceEvents\n * (which get converted to OTLP spans automatically).\n */\n\nexport interface OtelExportConfig {\n /** OTLP endpoint. Reads OTEL_EXPORTER_OTLP_ENDPOINT env by default. */\n endpoint?: string\n /** OTLP headers. Reads OTEL_EXPORTER_OTLP_HEADERS env by default. */\n headers?: Record<string, string>\n /** Batch size before flush. Default 64. */\n batchSize?: number\n /** Flush interval ms. Default 5000. */\n flushIntervalMs?: number\n /** Resource attributes stamped on every export. */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Service name. Default 'agent-runtime'. */\n serviceName?: string\n}\n\nexport interface OtelExporter {\n /** Export a span. */\n exportSpan(span: OtelSpan): void\n /** Force flush pending spans. */\n flush(): Promise<void>\n /** Shutdown cleanly. */\n shutdown(): Promise<void>\n}\n\nexport interface OtelSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind?: number\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes?: OtelAttribute[]\n status?: { code: number; message?: string }\n}\n\nexport interface OtelAttribute {\n key: string\n value: { stringValue?: string; intValue?: string; doubleValue?: number; boolValue?: boolean }\n}\n\ninterface OtlpResourceSpans {\n resource: { attributes: OtelAttribute[] }\n scopeSpans: Array<{ scope: { name: string; version: string }; spans: OtelSpan[] }>\n}\n\ninterface OtlpExport {\n resourceSpans: OtlpResourceSpans[]\n}\n\nconst SCOPE = { name: '@tangle-network/agent-runtime', version: '0.33.0' }\n\n/**\n * Current (non-deprecated) OpenTelemetry GenAI semantic-convention keys.\n * Registry: https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/\n * NB: `gen_ai.system` / `gen_ai.usage.prompt_tokens` / `completion_tokens` are\n * DEPRECATED — do not emit them. We use `provider.name` + `input/output_tokens`.\n */\nconst GEN_AI = {\n operation: 'gen_ai.operation.name',\n agentName: 'gen_ai.agent.name',\n conversationId: 'gen_ai.conversation.id',\n inputTokens: 'gen_ai.usage.input_tokens',\n outputTokens: 'gen_ai.usage.output_tokens',\n} as const\n\n/**\n * Create an OTEL exporter. Returns undefined when no endpoint is configured.\n */\nexport function createOtelExporter(config?: OtelExportConfig): OtelExporter | undefined {\n const resolvedEndpoint =\n config?.endpoint ??\n (typeof process !== 'undefined' ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : undefined)\n if (!resolvedEndpoint) return undefined\n const endpoint: string = resolvedEndpoint\n\n const headers = config?.headers ?? parseHeadersFromEnv()\n const batchSize = config?.batchSize ?? 64\n const flushIntervalMs = config?.flushIntervalMs ?? 5000\n const serviceName = config?.serviceName ?? 'agent-runtime'\n const resourceAttrs = config?.resourceAttributes ?? {}\n\n const pending: OtelSpan[] = []\n let timer: ReturnType<typeof setInterval> | undefined\n let stopped = false\n\n const exporter: OtelExporter = {\n exportSpan(span: OtelSpan): void {\n if (stopped) return\n pending.push(span)\n if (pending.length >= batchSize) {\n void doFlush()\n }\n },\n\n async flush(): Promise<void> {\n await doFlush()\n },\n\n async shutdown(): Promise<void> {\n stopped = true\n if (timer !== undefined) {\n clearInterval(timer)\n timer = undefined\n }\n await doFlush()\n },\n }\n\n timer = setInterval(() => {\n if (pending.length > 0) void doFlush()\n }, flushIntervalMs)\n if (typeof timer === 'object' && 'unref' in timer) {\n ;(timer as NodeJS.Timeout).unref()\n }\n\n async function doFlush(): Promise<void> {\n if (pending.length === 0) return\n const batch = pending.splice(0)\n const body: OtlpExport = {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': serviceName,\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: SCOPE, spans: batch }],\n },\n ],\n }\n const url = `${endpoint.replace(/\\/+$/, '')}/v1/traces`\n try {\n await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...headers },\n body: JSON.stringify(body),\n })\n } catch {\n // Best-effort — telemetry export must not crash the runtime.\n }\n }\n\n return exporter\n}\n\n/**\n * Convert a LoopTraceEvent into an OtelSpan for export.\n */\nexport function loopEventToOtelSpan(\n event: {\n kind: string\n runId: string\n timestamp: number\n payload: object\n },\n traceId: string,\n parentSpanId?: string,\n): OtelSpan {\n const spanId = generateSpanId()\n const attrs: Record<string, string | number | boolean> = {\n 'loop.event_kind': event.kind,\n 'loop.run_id': event.runId,\n }\n for (const [k, v] of Object.entries(event.payload)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n attrs[`loop.${k}`] = v\n }\n }\n const ts = msToNs(event.timestamp)\n return {\n traceId: padTraceId(traceId),\n spanId,\n parentSpanId: parentSpanId ? padSpanId(parentSpanId) : undefined,\n name: event.kind,\n kind: 1,\n startTimeUnixNano: ts,\n endTimeUnixNano: ts,\n attributes: toAttributes(attrs),\n status: { code: 1 },\n }\n}\n\n/**\n * Build a nested, real-duration OTLP span tree for ONE loop run from its full\n * ordered `LoopTraceEvent` stream. Unlike `loopEventToOtelSpan` (one flat,\n * zero-duration span per event), this reconstructs the topology hierarchy a\n * GenAI trace viewer renders natively:\n *\n * loop (invoke_workflow)\n * └─ loop.round[k] (invoke_workflow) ← tangle.loop.move.{kind,width,rationale}\n * ├─ loop.iteration[i] (invoke_agent) ← gen_ai.agent.name + usage + verdict + placement\n * └─ …\n *\n * Attributes follow the current GenAI semconv (`gen_ai.*`) where they apply and\n * a namespaced `tangle.loop.*` / `tangle.cost.usd` extension for topology /\n * verdict / placement / cost (not yet standardized). Pure: feed it a buffered\n * per-runId event array (e.g. flushed on `loop.ended`) and export the result.\n */\nexport function buildLoopOtelSpans(\n events: ReadonlyArray<{ kind: string; runId: string; timestamp: number; payload: object }>,\n traceId: string,\n rootParentSpanId?: string,\n): OtelSpan[] {\n if (events.length === 0) return []\n const tid = padTraceId(traceId)\n const out: OtelSpan[] = []\n const num = (v: unknown): number | undefined =>\n typeof v === 'number' && Number.isFinite(v) ? v : undefined\n const str = (v: unknown): string | undefined =>\n typeof v === 'string' && v.length > 0 ? v : undefined\n const rec = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' ? (v as Record<string, unknown>) : {}\n\n const started = events.find((e) => e.kind === 'loop.started')\n const ended = events.find((e) => e.kind === 'loop.ended')\n const runId = events[0]?.runId ?? ''\n const rootStart = started?.timestamp ?? events[0]!.timestamp\n const rootEnd = ended?.timestamp ?? events[events.length - 1]!.timestamp\n const rootId = generateSpanId()\n\n const make = (\n spanId: string,\n parentSpanId: string | undefined,\n name: string,\n startMs: number,\n endMs: number,\n attrs: Record<string, string | number | boolean>,\n statusCode = 1,\n ): OtelSpan => ({\n traceId: tid,\n spanId,\n parentSpanId: parentSpanId ? padSpanId(parentSpanId) : undefined,\n name,\n kind: 1,\n startTimeUnixNano: msToNs(startMs),\n endTimeUnixNano: msToNs(endMs),\n attributes: toAttributes(attrs),\n status: { code: statusCode },\n })\n\n // root\n const sp = rec(started?.payload)\n const rootAttrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_workflow',\n [GEN_AI.conversationId]: runId,\n 'tangle.loop.driver': str(sp.driver) ?? 'driver',\n }\n if (Array.isArray(sp.agentRunNames) && sp.agentRunNames.length > 0) {\n rootAttrs['tangle.loop.agents'] = sp.agentRunNames.map(String).join(',')\n }\n if (ended) {\n const ep = rec(ended.payload)\n const win = num(ep.winnerIterationIndex)\n if (win !== undefined) rootAttrs['tangle.loop.winner.iteration_index'] = win\n const cost = num(ep.totalCostUsd)\n if (cost !== undefined) rootAttrs['tangle.cost.usd'] = cost\n const dur = num(ep.durationMs)\n if (dur !== undefined) rootAttrs['tangle.loop.duration_ms'] = dur\n const iters = num(ep.iterations)\n if (iters !== undefined) rootAttrs['tangle.loop.iterations'] = iters\n }\n out.push(make(rootId, rootParentSpanId, 'loop', rootStart, rootEnd, rootAttrs))\n\n // rounds + iterations\n const iterStartTs = new Map<number, number>()\n const placementByIdx = new Map<number, Record<string, string>>()\n let currentRoundId: string | undefined\n let pendingRound:\n | { id: string; start: number; attrs: Record<string, string | number | boolean> }\n | undefined\n const flushRound = (endMs: number) => {\n if (!pendingRound) return\n out.push(\n make(pendingRound.id, rootId, 'loop.round', pendingRound.start, endMs, pendingRound.attrs),\n )\n pendingRound = undefined\n }\n\n for (const e of events) {\n const p = rec(e.payload)\n switch (e.kind) {\n case 'loop.plan': {\n flushRound(e.timestamp)\n const id = generateSpanId()\n const roundIdx = num(p.roundIndex) ?? 0\n const attrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_workflow',\n 'tangle.loop.round.index': roundIdx,\n 'tangle.loop.move.kind': str(p.moveKind) ?? 'unknown',\n 'tangle.loop.move.round': roundIdx,\n 'tangle.loop.move.width': num(p.plannedCount) ?? 0,\n }\n const r = str(p.rationale)\n if (r) attrs['tangle.loop.move.rationale'] = r\n const parent = num(p.parentIndex)\n if (parent !== undefined) attrs['tangle.loop.move.parent_index'] = parent\n if (Array.isArray(p.childIndices) && p.childIndices.length > 0) {\n attrs['tangle.loop.move.child_indices'] = p.childIndices.map(String).join(',')\n }\n pendingRound = { id, start: e.timestamp, attrs }\n currentRoundId = id\n break\n }\n case 'loop.iteration.started': {\n const idx = num(p.iterationIndex)\n if (idx !== undefined) iterStartTs.set(idx, e.timestamp)\n break\n }\n case 'loop.iteration.dispatch': {\n const idx = num(p.iterationIndex)\n if (idx === undefined) break\n const place: Record<string, string> = {}\n const kind = str(p.placement)\n if (kind) place['tangle.loop.placement.kind'] = kind\n const sid = str(p.sandboxId)\n if (sid) place['tangle.sandbox.id'] = sid\n const fid = str(p.fleetId)\n if (fid) place['tangle.fleet.id'] = fid\n const mid = str(p.machineId)\n if (mid) place['tangle.machine.id'] = mid\n placementByIdx.set(idx, place)\n break\n }\n case 'loop.iteration.ended': {\n const idx = num(p.iterationIndex) ?? 0\n const start = iterStartTs.get(idx) ?? e.timestamp\n const err = str(p.error)\n const attrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_agent',\n 'tangle.loop.iteration.index': idx,\n }\n const agent = str(p.agentRunName)\n if (agent) attrs[GEN_AI.agentName] = agent\n const tu = rec(p.tokenUsage)\n const inTok = num(tu.input)\n if (inTok !== undefined) attrs[GEN_AI.inputTokens] = inTok\n const outTok = num(tu.output)\n if (outTok !== undefined) attrs[GEN_AI.outputTokens] = outTok\n const cost = num(p.costUsd)\n if (cost !== undefined) attrs['tangle.cost.usd'] = cost\n const verdict = rec(p.verdict)\n if (typeof verdict.valid === 'boolean') attrs['tangle.loop.verdict.valid'] = verdict.valid\n const score = num(verdict.score)\n if (score !== undefined) attrs['tangle.loop.verdict.score'] = score\n if (err) attrs['tangle.loop.error'] = err\n const gid = num(p.groupId)\n if (gid !== undefined) attrs['tangle.loop.iteration.group_id'] = gid\n const par = num(p.parentIndex)\n if (par !== undefined) attrs['tangle.loop.iteration.parent_index'] = par\n const dur = num(p.durationMs)\n if (dur !== undefined) attrs['tangle.loop.iteration.duration_ms'] = dur\n const preview = str(p.outputPreview)\n if (preview) attrs['tangle.loop.iteration.output_preview'] = preview\n Object.assign(attrs, placementByIdx.get(idx) ?? {})\n out.push(\n make(\n generateSpanId(),\n currentRoundId ?? rootId,\n 'loop.iteration',\n start,\n e.timestamp,\n attrs,\n err ? 2 : 1,\n ),\n )\n break\n }\n case 'loop.decision': {\n if (pendingRound) {\n const dec = str(p.decision)\n if (dec) pendingRound.attrs['tangle.loop.decision'] = dec\n flushRound(e.timestamp)\n }\n currentRoundId = undefined\n break\n }\n }\n }\n flushRound(rootEnd)\n return out\n}\n\nfunction parseHeadersFromEnv(): Record<string, string> {\n if (typeof process === 'undefined') return {}\n const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS\n if (!raw) return {}\n const out: Record<string, string> = {}\n for (const pair of raw.split(',')) {\n const eq = pair.indexOf('=')\n if (eq < 0) continue\n const key = pair.slice(0, eq).trim()\n const value = pair.slice(eq + 1).trim()\n if (key) out[key] = value\n }\n return out\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtelAttribute[] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction padTraceId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n\nfunction generateSpanId(): string {\n const bytes = new Uint8Array(8)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 8; i++) bytes[i] = Math.floor(Math.random() * 256)\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ─── Eval-run ingest (self-improvement provenance) ───────────────────────────\n//\n// Tangle Intelligence has a first-class, non-trace record for self-improvement\n// runs: POST /v1/ingest/eval-runs (\"Mode D\"). Each generation carries a\n// `surfaceHash` (the proposed-change identity) + arbitrary `surface` provenance;\n// a later `gate-decided` event re-emits the same `runId` (idempotent upsert) with\n// a real `gateDecision` + `holdoutLift`, so proposal→verdict is one diffable\n// record. This is how a consumer's RSI loop records WHAT it changed, WHY, from\n// which evidence — the audit trail behind agentic self-improvement.\n\n/** Wire version the eval-runs ingest enforces (X-Tangle-Wire-Version + body). */\nexport const INTELLIGENCE_WIRE_VERSION = '2026-05-26.v1'\n\nexport interface EvalRunGeneration {\n /** 0-based ordinal of this generation within the run (required by ingest). */\n index: number\n /** Identity of the proposed surface change (content-addressed hash). */\n surfaceHash: string\n /** Arbitrary provenance for this generation (rationale, evidence, source). */\n surface?: unknown\n /** Per-scenario results; empty until the generation is measured. */\n cells?: unknown[]\n /** Mean composite score (0 when unmeasured — pair with labels.measured). */\n compositeMean: number\n costUsd: number\n durationMs: number\n}\n\nexport interface EvalRunEvent {\n runId: string\n runDir: string\n /** ISO timestamp. */\n timestamp: string\n status:\n | 'started'\n | 'baseline-complete'\n | 'generation-complete'\n | 'gate-decided'\n | 'finished'\n | 'errored'\n labels?: Record<string, string>\n baseline?: EvalRunGeneration\n generations?: EvalRunGeneration[]\n gateDecision?: 'ship' | 'hold' | 'need_more_work' | 'model_ceiling' | 'arch_ceiling'\n holdoutLift?: number\n totalCostUsd: number\n totalDurationMs: number\n errorMessage?: string\n}\n\nexport interface EvalRunsExportConfig {\n /** Bearer key — tenant is resolved server-side from it. Reads TANGLE_API_KEY. */\n apiKey?: string\n /** Intelligence base. Reads INTELLIGENCE_BASE env, else prod. */\n base?: string\n /** Idempotency-Key header (e.g. the runId) — safe retries + upsert. */\n idempotencyKey?: string\n}\n\nexport interface EvalRunsExportResult {\n ok: boolean\n status: number\n accepted: number\n rejected: Array<{ index: number; reason: string }>\n}\n\nconst DEFAULT_INTELLIGENCE_BASE = 'https://intelligence.tangle.tools'\n\n/**\n * Ship self-improvement eval-run events to Tangle Intelligence. Unlike the\n * best-effort span exporter, this RESOLVES with the ingest verdict (accepted /\n * rejected per event) so a consumer's loop can assert its provenance landed.\n * Throws only on a missing key or network failure.\n */\nexport async function exportEvalRuns(\n events: EvalRunEvent[],\n config?: EvalRunsExportConfig,\n): Promise<EvalRunsExportResult> {\n if (events.length === 0) return { ok: true, status: 0, accepted: 0, rejected: [] }\n const apiKey =\n config?.apiKey ?? (typeof process !== 'undefined' ? process.env.TANGLE_API_KEY : undefined)\n if (!apiKey)\n throw new Error('exportEvalRuns: apiKey required (pass config.apiKey or set TANGLE_API_KEY)')\n const base =\n config?.base ??\n (typeof process !== 'undefined' ? process.env.INTELLIGENCE_BASE : undefined) ??\n DEFAULT_INTELLIGENCE_BASE\n const url = `${base.replace(/\\/+$/, '')}/v1/ingest/eval-runs`\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${apiKey}`,\n 'X-Tangle-Wire-Version': INTELLIGENCE_WIRE_VERSION,\n ...(config?.idempotencyKey ? { 'Idempotency-Key': config.idempotencyKey } : {}),\n },\n body: JSON.stringify({ wireVersion: INTELLIGENCE_WIRE_VERSION, events }),\n })\n let parsed: { accepted?: number; rejected?: Array<{ index: number; reason: string }> } = {}\n try {\n parsed = (await res.json()) as typeof parsed\n } catch {\n // non-JSON body (e.g. 5xx HTML) — leave parsed empty\n }\n return {\n ok: res.ok,\n status: res.status,\n accepted: parsed.accepted ?? (res.ok ? events.length : 0),\n rejected: parsed.rejected ?? [],\n }\n}\n"],"mappings":"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","names":["SINGLE_VARIANT_ESTIMATE_MS","FANOUT_PER_VARIANT_ESTIMATE_MS","validateConfig","defaultEstimate"]}
@@ -176,7 +176,9 @@ function envelopeToMove(envelope, ctx, decodeTask) {
176
176
  const tasks = resolveFanoutTasks(envelope, ctx, decodeTask);
177
177
  return { kind: "fanout", tasks, rationale };
178
178
  }
179
- throw new PlannerError(`sandbox planner emitted unknown move kind: ${JSON.stringify(envelope.kind)}`);
179
+ throw new PlannerError(
180
+ `sandbox planner emitted unknown move kind: ${JSON.stringify(envelope.kind)}`
181
+ );
180
182
  }
181
183
  function resolveFanoutTasks(envelope, ctx, decodeTask) {
182
184
  if (Array.isArray(envelope.tasks) && envelope.tasks.length > 0) {
@@ -296,6 +298,63 @@ function reportLoopUsage(cost, result, source = "loop") {
296
298
  cost.observeTokens({ input: result.tokenUsage.input, output: result.tokenUsage.output });
297
299
  }
298
300
 
301
+ // src/loops/sandbox-events.ts
302
+ function extractLlmCallEvent(event, agentRunName) {
303
+ if (!event || typeof event !== "object") return void 0;
304
+ const type = String(event.type ?? "");
305
+ const data = event.data && typeof event.data === "object" ? event.data : {};
306
+ if (type === "llm_call" || type === "cost.usage" || type === "usage") {
307
+ return buildLlmCall(data, agentRunName);
308
+ }
309
+ if (type === "message.completed" || type === "result" || type === "final") {
310
+ const usage = data.usage;
311
+ if (!usage || typeof usage !== "object") return void 0;
312
+ return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName);
313
+ }
314
+ return void 0;
315
+ }
316
+ function buildLlmCall(data, agentRunName) {
317
+ const tokensIn = pickFiniteNumber(data, ["tokensIn", "inputTokens", "prompt_tokens"]);
318
+ const tokensOut = pickFiniteNumber(data, ["tokensOut", "outputTokens", "completion_tokens"]);
319
+ const costUsd = pickFiniteNumber(data, ["costUsd", "totalCostUsd", "cost_usd", "cost"]);
320
+ if (tokensIn === void 0 && tokensOut === void 0 && costUsd === void 0) {
321
+ return void 0;
322
+ }
323
+ const model = typeof data.model === "string" && data.model.length > 0 ? data.model : agentRunName;
324
+ const event = {
325
+ type: "llm_call",
326
+ model
327
+ };
328
+ if (tokensIn !== void 0) event.tokensIn = tokensIn;
329
+ if (tokensOut !== void 0) event.tokensOut = tokensOut;
330
+ if (costUsd !== void 0) event.costUsd = costUsd;
331
+ return event;
332
+ }
333
+ function pickFiniteNumber(data, keys) {
334
+ for (const key of keys) {
335
+ const value = data[key];
336
+ if (typeof value === "number" && Number.isFinite(value)) return value;
337
+ }
338
+ return void 0;
339
+ }
340
+ function mapSandboxEvent(event, opts = {}) {
341
+ if (!event || typeof event !== "object") return void 0;
342
+ const type = String(event.type ?? "");
343
+ const data = event.data && typeof event.data === "object" ? event.data : {};
344
+ if (type === "message.part.updated") {
345
+ const part = data.part && typeof data.part === "object" ? data.part : {};
346
+ const partType = String(part.type ?? "");
347
+ const delta = typeof data.delta === "string" ? data.delta : void 0;
348
+ const text = delta ?? (typeof part.text === "string" ? part.text : void 0);
349
+ if (text === void 0) return void 0;
350
+ if (partType === "text") return { type: "text_delta", text };
351
+ if (partType === "reasoning" || partType === "thinking")
352
+ return { type: "reasoning_delta", text };
353
+ return void 0;
354
+ }
355
+ return extractLlmCallEvent(event, opts.agentRunName ?? "agent");
356
+ }
357
+
299
358
  // src/loops/run-loop.ts
300
359
  var DEFAULT_MAX_ITERATIONS = 10;
301
360
  var DEFAULT_MAX_CONCURRENCY = 4;
@@ -672,44 +731,6 @@ function throwAbort() {
672
731
  err.name = "AbortError";
673
732
  throw err;
674
733
  }
675
- function extractLlmCallEvent(event, agentRunName) {
676
- if (!event || typeof event !== "object") return void 0;
677
- const type = String(event.type ?? "");
678
- const data = event.data && typeof event.data === "object" ? event.data : {};
679
- if (type === "llm_call" || type === "cost.usage" || type === "usage") {
680
- return buildLlmCall(data, agentRunName);
681
- }
682
- if (type === "message.completed" || type === "result" || type === "final") {
683
- const usage = data.usage;
684
- if (!usage || typeof usage !== "object") return void 0;
685
- return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName);
686
- }
687
- return void 0;
688
- }
689
- function buildLlmCall(data, agentRunName) {
690
- const tokensIn = pickFiniteNumber(data, ["tokensIn", "inputTokens", "prompt_tokens"]);
691
- const tokensOut = pickFiniteNumber(data, ["tokensOut", "outputTokens", "completion_tokens"]);
692
- const costUsd = pickFiniteNumber(data, ["costUsd", "totalCostUsd", "cost_usd", "cost"]);
693
- if (tokensIn === void 0 && tokensOut === void 0 && costUsd === void 0) {
694
- return void 0;
695
- }
696
- const model = typeof data.model === "string" && data.model.length > 0 ? data.model : agentRunName;
697
- const event = {
698
- type: "llm_call",
699
- model
700
- };
701
- if (tokensIn !== void 0) event.tokensIn = tokensIn;
702
- if (tokensOut !== void 0) event.tokensOut = tokensOut;
703
- if (costUsd !== void 0) event.costUsd = costUsd;
704
- return event;
705
- }
706
- function pickFiniteNumber(data, keys) {
707
- for (const key of keys) {
708
- const value = data[key];
709
- if (typeof value === "number" && Number.isFinite(value)) return value;
710
- }
711
- return void 0;
712
- }
713
734
  function hashJson(value) {
714
735
  let str;
715
736
  try {
@@ -766,8 +787,11 @@ export {
766
787
  refineWinnerIndex,
767
788
  createSandboxPlanner,
768
789
  reportLoopUsage,
790
+ extractLlmCallEvent,
791
+ mapSandboxEvent,
769
792
  runLoop,
793
+ createSandboxForSpec,
770
794
  loopDispatch,
771
795
  loopCampaignDispatch
772
796
  };
773
- //# sourceMappingURL=chunk-OISRXLWI.js.map
797
+ //# sourceMappingURL=chunk-IFG6GX6A.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/loops/drivers/dynamic.ts","../src/loops/drivers/refine.ts","../src/loops/drivers/sandbox-planner.ts","../src/loops/report-usage.ts","../src/loops/sandbox-events.ts","../src/loops/run-loop.ts","../src/loops/loop-dispatch.ts"],"sourcesContent":["/**\n * @experimental\n *\n * Dynamic driver — the agent authors the loop topology at runtime.\n *\n * Where `refine` and `fanout-vote` encode a fixed shape as a pure function of\n * history, this driver delegates the per-round shape to an injected\n * `TopologyPlanner`. Each round the planner inspects the task + iteration\n * history and emits one `TopologyMove`:\n * - `refine` → one task next round (optionally rewritten from the prior attempt)\n * - `fanout` → N tasks next round (the kernel round-robins `agentRuns`, so a\n * 2-harness fanout dispatches branch 0 to harness A and branch 1 to harness B)\n * - `stop` → terminate; the kernel selects the winner across all iterations\n *\n * The planner is the brain; this driver is the structure. It maps moves onto\n * the kernel's `plan`/`decide` contract, enforces the iteration + fanout caps,\n * and fails loud on a malformed move. The planner is injected exactly like\n * `refine`'s `refineTask` and `fanout-vote`'s `selector` — so a test can drive\n * a deterministic policy through the real kernel, and production can wire it to\n * an LLM via `createSandboxPlanner`.\n *\n * Topology is orthogonal to harness: the planner never names a backend. Which\n * harness runs a branch is decided by the `AgentRunSpec` the kernel round-robins\n * to, so one dynamic driver works across claude-code, codex, opencode, pi —\n * including fanning a single round across several at once.\n */\n\nimport { PlannerError, ValidationError } from '../../errors'\nimport type { Driver, Iteration } from '../types'\n\n/** Terminal once `decide` returns `'done'` (a kernel terminal decision). */\nexport type DynamicDecision = 'continue' | 'done'\n\n/**\n * One topology decision for the next round. `fanout` carries explicit tasks\n * rather than a count so the planner can issue heterogeneous branches (a\n * different sub-task per harness); pass N copies of one task for a homogeneous\n * fanout that relies on `agentRuns` diversity instead.\n *\n * @experimental\n */\nexport type TopologyMove<Task> =\n | { kind: 'refine'; task: Task; rationale?: string; parentIndex?: number }\n | { kind: 'fanout'; tasks: Task[]; rationale?: string; parentIndex?: number }\n | { kind: 'stop'; rationale?: string }\n\n/** @experimental */\nexport interface PlannerContext<Task, Output> {\n /** The root task the loop was invoked with — stable across rounds. */\n task: Task\n /** Every iteration so far, in dispatch order, with outputs + verdicts. */\n history: ReadonlyArray<Iteration<Task, Output>>\n /** `history.length` — iterations already spent. */\n iterationsSpent: number\n /** Iterations left before the driver's `maxIterations` cap forces a stop. */\n iterationsRemaining: number\n}\n\n/**\n * Chooses the next topology move from the task + history. Sync or async; an\n * async planner is where an LLM call goes (see `createSandboxPlanner`).\n *\n * @experimental\n */\nexport type TopologyPlanner<Task, Output> = (\n ctx: PlannerContext<Task, Output>,\n) => TopologyMove<Task> | Promise<TopologyMove<Task>>\n\n/** @experimental */\nexport interface CreateDynamicDriverOptions<Task, Output> {\n /** The agent-authored topology policy. Invoked once per round in `plan`. */\n planner: TopologyPlanner<Task, Output>\n /**\n * Hard safety cap on total iterations. When reached, the driver stops before\n * consulting the planner. Default 8. Set the kernel's `runLoop`\n * `maxIterations >= ` this so the driver's cap governs and the loop closes on\n * a clean `'done'` rather than a truncated `'continue'`.\n */\n maxIterations?: number\n /** Max branches a single `fanout` move may dispatch. Default 4. */\n maxFanout?: number\n /** Stable identifier surfaced in trace events. Default `'dynamic'`. */\n name?: string\n}\n\n/** @experimental */\nexport function createDynamicDriver<Task, Output>(\n options: CreateDynamicDriverOptions<Task, Output>,\n): Driver<Task, Output, DynamicDecision> {\n if (typeof options.planner !== 'function') {\n throw new ValidationError('createDynamicDriver: planner must be a function')\n }\n const maxIterations = options.maxIterations ?? 8\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('createDynamicDriver: maxIterations must be > 0')\n }\n const maxFanout = options.maxFanout ?? 4\n if (!Number.isFinite(maxFanout) || maxFanout < 1) {\n throw new ValidationError('createDynamicDriver: maxFanout must be >= 1')\n }\n\n // The kernel calls plan(), runs the batch, then calls decide() — strictly\n // sequential, one driver instance per loop. Caching the move the planner\n // chose this round lets decide() report terminality without re-invoking the\n // planner (which would double every LLM call).\n let pending: TopologyMove<Task> | undefined\n\n return {\n name: options.name ?? 'dynamic',\n async plan(task, history) {\n if (history.length >= maxIterations) {\n pending = { kind: 'stop', rationale: `maxIterations (${maxIterations}) reached` }\n return []\n }\n const move = await options.planner({\n task,\n history,\n iterationsSpent: history.length,\n iterationsRemaining: maxIterations - history.length,\n })\n pending = validateMove(move, maxFanout)\n switch (pending.kind) {\n case 'refine':\n return [pending.task]\n case 'fanout':\n return pending.tasks\n case 'stop':\n return []\n }\n },\n decide() {\n // pending is set by the plan() call that immediately precedes every\n // decide(). Only a `stop` move terminates; refine/fanout keep looping so\n // plan() — and thus the planner — runs again next round.\n return pending?.kind === 'stop' ? 'done' : 'continue'\n },\n describePlan() {\n // Surface the move the planner just chose (kind + rationale + an optional\n // DECLARED branch source) so the kernel's loop.plan trace carries the\n // agent's intent — including faithful edge lineage when the planner\n // branched off a specific (non-winner) iteration. `pending` is the move\n // set by the preceding plan().\n if (!pending) return undefined\n const out: { kind: string; rationale?: string; parentIndex?: number } = { kind: pending.kind }\n if (pending.rationale !== undefined) out.rationale = pending.rationale\n if (pending.kind !== 'stop' && pending.parentIndex !== undefined) {\n out.parentIndex = pending.parentIndex\n }\n return out\n },\n }\n}\n\nfunction validateMove<Task>(move: TopologyMove<Task>, maxFanout: number): TopologyMove<Task> {\n if (!move || typeof move !== 'object' || typeof (move as { kind?: unknown }).kind !== 'string') {\n throw new PlannerError(`dynamic planner returned a non-move value: ${describe(move)}`)\n }\n switch (move.kind) {\n case 'refine':\n return move\n case 'stop':\n return move\n case 'fanout': {\n if (!Array.isArray(move.tasks) || move.tasks.length === 0) {\n throw new PlannerError('dynamic planner fanout move must carry a non-empty tasks[]')\n }\n if (move.tasks.length <= maxFanout) return move\n // Clamp rather than reject — over-fanning is a budget concern, not a\n // structural error. The clamp is recorded in the rationale for traces.\n return {\n kind: 'fanout',\n tasks: move.tasks.slice(0, maxFanout),\n rationale: `${move.rationale ?? ''} [clamped ${move.tasks.length}→${maxFanout}]`.trim(),\n }\n }\n default:\n throw new PlannerError(\n `dynamic planner returned unknown move kind: ${describe((move as { kind: unknown }).kind)}`,\n )\n }\n}\n\nfunction describe(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value)\n } catch {\n return String(value)\n }\n}\n\n/**\n * Compact, planner-friendly view of iteration history — what an LLM planner\n * needs to choose the next move without the raw event streams. Output is\n * truncated so a long run's prompt stays bounded.\n *\n * @experimental\n */\nexport function summarizeHistory<Task, Output>(\n history: ReadonlyArray<Iteration<Task, Output>>,\n opts: { maxOutputChars?: number } = {},\n): Array<{\n index: number\n agentRunName: string\n valid?: boolean\n score?: number\n error?: string\n output?: string\n}> {\n const maxOutputChars = opts.maxOutputChars ?? 600\n return history.map((iter) => {\n const row: {\n index: number\n agentRunName: string\n valid?: boolean\n score?: number\n error?: string\n output?: string\n } = { index: iter.index, agentRunName: iter.agentRunName }\n if (iter.verdict) {\n row.valid = iter.verdict.valid\n if (typeof iter.verdict.score === 'number') row.score = iter.verdict.score\n }\n if (iter.error) row.error = iter.error.message\n if (iter.output !== undefined) {\n const serialized = describe(iter.output)\n row.output =\n serialized.length > maxOutputChars ? `${serialized.slice(0, maxOutputChars)}…` : serialized\n }\n return row\n })\n}\n","/**\n * @experimental\n *\n * Refine driver — single task per iteration, validator-gated.\n *\n * `plan` returns `[task]` (possibly transformed via `refineTask`) until the\n * prior verdict is valid OR the local cap is hit, then `[]`.\n * `decide` returns `'stop'` once the latest verdict is valid OR the cap is\n * reached. The kernel's `maxIterations` is an orthogonal safety cap;\n * whichever is lower wins.\n */\n\nimport { ValidationError } from '../../errors'\nimport type { DefaultVerdict, Driver, Iteration } from '../types'\n\nexport type RefineDecision = 'continue' | 'stop'\n\n/** @experimental */\nexport interface CreateRefineDriverOptions<Task> {\n /** Hard cap on iterations. Default 5. */\n maxIterations?: number\n /**\n * Optional task transform applied each round based on the prior verdict.\n * When omitted, the same task is replayed and the agent is expected to\n * inspect the sandbox session state for prior attempts.\n */\n refineTask?: (task: Task, prior: DefaultVerdict) => Task\n /** Stable identifier surfaced in trace events. Default `'refine'`. */\n name?: string\n}\n\n/** @experimental */\nexport function createRefineDriver<Task, Output>(\n options: CreateRefineDriverOptions<Task> = {},\n): Driver<Task, Output, RefineDecision> {\n const maxIterations = options.maxIterations ?? 5\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('createRefineDriver: maxIterations must be > 0')\n }\n const refineTask = options.refineTask\n return {\n name: options.name ?? 'refine',\n async plan(task, history) {\n if (history.length >= maxIterations) return []\n if (history.length === 0) return [task]\n const prior = history.at(-1)\n if (!prior) return [task]\n if (prior.verdict?.valid === true) return []\n // Worker error: replay the same task so the agent can self-correct.\n // The driver has no signal beyond `verdict`; only the validator\n // controls \"good enough\".\n if (!refineTask || !prior.verdict) return [prior.task]\n return [refineTask(prior.task, prior.verdict)]\n },\n decide(history) {\n const last = history.at(-1)\n if (!last) return 'continue'\n if (last.verdict?.valid === true) return 'stop'\n if (history.length >= maxIterations) return 'stop'\n return 'continue'\n },\n }\n}\n\n/**\n * Test helper: select the last-valid iteration (or the last attempt if\n * none passed). Mirrors the kernel's default selector ordering for refine\n * topologies — the most recent successful attempt wins.\n *\n * @experimental\n */\nexport function refineWinnerIndex<Task, Output>(\n iterations: ReadonlyArray<Iteration<Task, Output>>,\n): number | undefined {\n for (let i = iterations.length - 1; i >= 0; i -= 1) {\n if (iterations[i]?.verdict?.valid) return i\n }\n return iterations.length > 0 ? iterations.length - 1 : undefined\n}\n","/**\n * @experimental\n *\n * `createSandboxPlanner` — wire the dynamic driver's `TopologyPlanner` to a\n * real agent. Each round it spins a sandbox on `profile`, streams a prompt that\n * carries the history summary, and decodes the agent's chosen `TopologyMove`\n * from a JSON envelope it emits. This is the \"agent authors its own loop\n * topology\" path: the planner profile can be any harness (claude-code, codex,\n * opencode, pi) — its only job is to read what happened and emit the next move.\n *\n * The planner profile is deliberately distinct from the worker `agentRuns`: a\n * cheap fast model can steer topology while expensive workers do the labor, and\n * the planner never names which harness runs a branch — the kernel's\n * `agentRuns` round-robin decides that.\n *\n * Envelope contract the agent must emit (fenced ```json or a structured\n * `result`/`final` event payload):\n * { \"kind\": \"refine\" | \"fanout\" | \"stop\",\n * \"tasks\"?: [ <task>, ... ], // decoded via `decodeTask`\n * \"n\"?: number, // fanout shorthand: N copies of the root task\n * \"rationale\"?: string }\n *\n * A missing / unparseable / unknown-kind envelope throws `PlannerError` — the\n * loop never silently runs a topology the agent did not choose.\n */\n\nimport type { AgentProfile, CreateSandboxOptions, SandboxEvent } from '@tangle-network/sandbox'\nimport { PlannerError, ValidationError } from '../../errors'\nimport type { AgentRunSpec, LoopSandboxClient } from '../types'\nimport type { PlannerContext, TopologyMove, TopologyPlanner } from './dynamic'\nimport { summarizeHistory } from './dynamic'\n\n/** Raw, pre-decode envelope an agent emits to choose the next move. */\nexport interface TopologyMoveEnvelope {\n kind: string\n tasks?: unknown[]\n n?: number\n rationale?: string\n}\n\n/** @experimental */\nexport interface CreateSandboxPlannerOptions<Task, Output> {\n /** Sandbox client — the planner calls `.create()` once per round. */\n client: LoopSandboxClient\n /** The planner agent. Steers topology; does not run the work. */\n profile: AgentProfile\n /**\n * Decode one raw task from the envelope's `tasks[]` into a domain `Task`.\n * Required because `Task` is opaque to this module — only the caller knows\n * its shape. Throw to reject a malformed task; the error surfaces as a\n * `PlannerError`.\n */\n decodeTask: (raw: unknown, ctx: PlannerContext<Task, Output>) => Task\n /** Override the default prompt (history summary + envelope contract). */\n buildPrompt?: (ctx: PlannerContext<Task, Output>) => string\n /** Override envelope extraction from the event stream. */\n parseEnvelope?: (events: SandboxEvent[]) => TopologyMoveEnvelope | undefined\n /** Sandbox overrides for the planner sandbox (timeouts, env, etc.). */\n sandboxOverrides?: AgentRunSpec<Task>['sandboxOverrides']\n /** Cancellation for the planner's own LLM call. */\n signal?: AbortSignal\n}\n\n/** @experimental */\nexport function createSandboxPlanner<Task, Output>(\n opts: CreateSandboxPlannerOptions<Task, Output>,\n): TopologyPlanner<Task, Output> {\n if (!opts.client || typeof opts.client.create !== 'function') {\n throw new ValidationError('createSandboxPlanner: client.create is required')\n }\n if (typeof opts.decodeTask !== 'function') {\n throw new ValidationError('createSandboxPlanner: decodeTask is required')\n }\n const buildPrompt = opts.buildPrompt ?? defaultBuildPrompt\n const parseEnvelope = opts.parseEnvelope ?? defaultParseEnvelope\n\n return async (ctx) => {\n const box = await opts.client.create(buildSandboxOptions(opts.profile, opts.sandboxOverrides))\n const events: SandboxEvent[] = []\n for await (const event of box.streamPrompt(buildPrompt(ctx), { signal: opts.signal })) {\n events.push(event)\n }\n const envelope = parseEnvelope(events)\n if (!envelope) {\n throw new PlannerError('sandbox planner emitted no parseable topology-move envelope')\n }\n return envelopeToMove(envelope, ctx, opts.decodeTask)\n }\n}\n\nfunction envelopeToMove<Task, Output>(\n envelope: TopologyMoveEnvelope,\n ctx: PlannerContext<Task, Output>,\n decodeTask: (raw: unknown, ctx: PlannerContext<Task, Output>) => Task,\n): TopologyMove<Task> {\n const kind = String(envelope.kind ?? '').toLowerCase()\n const rationale = typeof envelope.rationale === 'string' ? envelope.rationale : undefined\n if (kind === 'stop') {\n return { kind: 'stop', rationale }\n }\n if (kind === 'refine') {\n const raw = Array.isArray(envelope.tasks) ? envelope.tasks[0] : undefined\n // No new task → replay the root task; the worker self-corrects from its\n // own prior attempt in sandbox state, mirroring the refine driver default.\n const task = raw === undefined ? ctx.task : decodeTaskGuarded(decodeTask, raw, ctx)\n return { kind: 'refine', task, rationale }\n }\n if (kind === 'fanout') {\n const tasks = resolveFanoutTasks(envelope, ctx, decodeTask)\n return { kind: 'fanout', tasks, rationale }\n }\n throw new PlannerError(\n `sandbox planner emitted unknown move kind: ${JSON.stringify(envelope.kind)}`,\n )\n}\n\nfunction resolveFanoutTasks<Task, Output>(\n envelope: TopologyMoveEnvelope,\n ctx: PlannerContext<Task, Output>,\n decodeTask: (raw: unknown, ctx: PlannerContext<Task, Output>) => Task,\n): Task[] {\n if (Array.isArray(envelope.tasks) && envelope.tasks.length > 0) {\n return envelope.tasks.map((raw) => decodeTaskGuarded(decodeTask, raw, ctx))\n }\n // `n` shorthand: N copies of the root task, leaning on `agentRuns` diversity.\n if (typeof envelope.n === 'number' && Number.isFinite(envelope.n) && envelope.n >= 1) {\n return Array.from({ length: Math.floor(envelope.n) }, () => ctx.task)\n }\n throw new PlannerError('sandbox planner fanout envelope needs a non-empty tasks[] or n >= 1')\n}\n\nfunction decodeTaskGuarded<Task, Output>(\n decodeTask: (raw: unknown, ctx: PlannerContext<Task, Output>) => Task,\n raw: unknown,\n ctx: PlannerContext<Task, Output>,\n): Task {\n try {\n return decodeTask(raw, ctx)\n } catch (err) {\n throw new PlannerError(`sandbox planner decodeTask rejected ${JSON.stringify(raw)}`, {\n cause: err,\n })\n }\n}\n\nfunction buildSandboxOptions(\n profile: AgentProfile,\n overrides: AgentRunSpec<unknown>['sandboxOverrides'],\n): CreateSandboxOptions {\n const base = overrides ?? {}\n const overrideBackend = base.backend\n const explicitType = profile.metadata?.backendType\n type BackendType = NonNullable<CreateSandboxOptions['backend']>['type']\n return {\n ...base,\n backend: {\n type: (overrideBackend?.type ?? explicitType ?? 'opencode') as BackendType,\n profile,\n ...(overrideBackend?.model ? { model: overrideBackend.model } : {}),\n ...(overrideBackend?.server ? { server: overrideBackend.server } : {}),\n },\n }\n}\n\nfunction defaultBuildPrompt<Task, Output>(ctx: PlannerContext<Task, Output>): string {\n const summary = summarizeHistory(ctx.history)\n return [\n 'You are the loop planner. You do not do the work — you decide the topology of the next round.',\n '',\n `Root task:\\n${safeJson(ctx.task)}`,\n '',\n `Iterations spent: ${ctx.iterationsSpent}. Remaining before the hard cap: ${ctx.iterationsRemaining}.`,\n '',\n ctx.history.length === 0\n ? 'No attempts yet.'\n : `Attempts so far (index, agent, verdict, output):\\n${safeJson(summary)}`,\n '',\n 'Choose ONE move and emit it as a fenced JSON block:',\n ' - {\"kind\":\"refine\",\"tasks\":[<task>],\"rationale\":\"...\"} — one more attempt; omit tasks to replay the root task.',\n ' - {\"kind\":\"fanout\",\"tasks\":[<task>,<task>],\"rationale\":\"...\"} — N parallel branches (or \"n\": N for N copies of the root task).',\n ' - {\"kind\":\"stop\",\"rationale\":\"...\"} — a valid result exists or further attempts will not help.',\n '',\n 'Stop as soon as an attempt is valid. Prefer refine when an attempt is close; fan out when attempts disagree or the approach is uncertain.',\n 'Emit ONLY the JSON block.',\n ].join('\\n')\n}\n\nfunction defaultParseEnvelope(events: SandboxEvent[]): TopologyMoveEnvelope | undefined {\n // Structured payload on a terminal event wins — sandbox SDKs lift emitted\n // JSON onto data.result / data.output / data of a result|final event.\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : undefined\n if (!data) continue\n if (type === 'result' || type === 'final' || type === 'planner.move') {\n const direct = coerceEnvelope(data.result ?? data.output ?? data)\n if (direct) return direct\n }\n }\n // Fall back to a fenced JSON block in the most recent text delta.\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : undefined\n if (!data) continue\n const text = pickString(data.text) ?? pickString(data.delta) ?? pickString(data.content)\n if (!text) continue\n const fenced = extractFencedJson(text)\n const coerced = coerceEnvelope(fenced)\n if (coerced) return coerced\n }\n return undefined\n}\n\nfunction coerceEnvelope(value: unknown): TopologyMoveEnvelope | undefined {\n if (!isRecord(value)) return undefined\n if (typeof value.kind !== 'string' || value.kind.length === 0) return undefined\n const out: TopologyMoveEnvelope = { kind: value.kind }\n if (Array.isArray(value.tasks)) out.tasks = value.tasks\n if (typeof value.n === 'number') out.n = value.n\n if (typeof value.rationale === 'string') out.rationale = value.rationale\n return out\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n const body = (match?.[1] ?? text).trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction safeJson(value: unknown): string {\n try {\n return JSON.stringify(value, null, 2) ?? String(value)\n } catch {\n return String(value)\n }\n}\n","/**\n * Bridge a finished `runLoop` into an agent-eval campaign / profile-matrix\n * dispatch.\n *\n * `runProfileMatrix` (and `runCampaign`) run the backend-integrity guard over\n * the token usage a dispatch reports through `ctx.cost`. A dispatch that wraps\n * `runLoop` must forward the loop's cost AND token usage, or the guard reads\n * the run as a stub and throws. `reportLoopUsage` is that one line:\n *\n * const dispatch: ProfileDispatchFn<S, A> = async (profile, scenario, ctx) => {\n * const result = await runLoop({ ...optsFor(profile, scenario), ctx: loopCtx })\n * reportLoopUsage(ctx, result)\n * return result.winner?.output as A\n * }\n *\n * Typed structurally against the campaign `DispatchContext.cost` so this module\n * stays free of an agent-eval import — it works with any cost meter exposing\n * `observe` + `observeTokens`.\n */\n\nimport type { LoopResult } from './types'\n\n/** The slice of an agent-eval campaign `DispatchContext.cost` this needs. */\nexport interface UsageSink {\n observe(amountUsd: number, source: string): void\n observeTokens(usage: { input: number; output: number }): void\n}\n\n/**\n * Forward a `LoopResult`'s aggregated cost + token usage into a campaign cost\n * meter so the backend-integrity guard sees real LLM activity. `source`\n * defaults to `'loop'`.\n */\nexport function reportLoopUsage<Task, Output, Decision>(\n cost: UsageSink,\n result: Pick<LoopResult<Task, Output, Decision>, 'costUsd' | 'tokenUsage'>,\n source = 'loop',\n): void {\n cost.observe(result.costUsd, source)\n cost.observeTokens({ input: result.tokenUsage.input, output: result.tokenUsage.output })\n}\n","/**\n * Sandbox-event → runtime-event mapping.\n *\n * The sandbox SDK emits a polymorphic `SandboxEvent = { type, data, id? }`\n * whose `type` vocabulary is backend-determined (opencode, etc.) rather than\n * enumerated by the SDK. Two consumers project it:\n * - the loop kernel's cost ledger (`extractLlmCallEvent`) — sums usage off\n * every cost-bearing event, regardless of stream shape;\n * - the `AgentRuntime.act` streaming contract (`mapSandboxEvent`) — projects\n * incremental events to the `RuntimeStreamEvent` chat-UX vocabulary.\n *\n * Both live here so the empirically-observed `type` vocabulary has one home.\n */\n\nimport type { SandboxEvent } from '@tangle-network/sandbox'\nimport type { RuntimeStreamEvent } from '../types'\n\n/**\n * Extract a `RuntimeStreamEvent`-shaped `llm_call` from a sandbox event when\n * the event carries usage/cost data. Returns `undefined` for non-cost events\n * so the kernel can iterate the full stream without branching.\n *\n * Canonical cost-carrying types observed in the wild:\n * - `llm_call` — `data: { model, tokensIn, tokensOut, costUsd, ... }`\n * - `message.completed` / `result` — `data: { usage: { inputTokens,\n * outputTokens, totalCostUsd? } }`\n * - `cost.usage` / `usage` — same shape under a dedicated type\n *\n * Numeric coercion is strict: `Number.isFinite` gates every accumulator write\n * so a sentinel `NaN` from a misbehaving backend cannot poison the ledger.\n */\nexport function extractLlmCallEvent(\n event: SandboxEvent,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'llm_call' || type === 'cost.usage' || type === 'usage') {\n return buildLlmCall(data, agentRunName)\n }\n if (type === 'message.completed' || type === 'result' || type === 'final') {\n const usage = data.usage as Record<string, unknown> | undefined\n if (!usage || typeof usage !== 'object') return undefined\n return buildLlmCall({ ...usage, model: data.model ?? usage.model }, agentRunName)\n }\n return undefined\n}\n\nfunction buildLlmCall(\n data: Record<string, unknown>,\n agentRunName: string,\n): (RuntimeStreamEvent & { type: 'llm_call' }) | undefined {\n const tokensIn = pickFiniteNumber(data, ['tokensIn', 'inputTokens', 'prompt_tokens'])\n const tokensOut = pickFiniteNumber(data, ['tokensOut', 'outputTokens', 'completion_tokens'])\n const costUsd = pickFiniteNumber(data, ['costUsd', 'totalCostUsd', 'cost_usd', 'cost'])\n if (tokensIn === undefined && tokensOut === undefined && costUsd === undefined) {\n return undefined\n }\n const model = typeof data.model === 'string' && data.model.length > 0 ? data.model : agentRunName\n const event: RuntimeStreamEvent & { type: 'llm_call' } = {\n type: 'llm_call',\n model,\n }\n if (tokensIn !== undefined) event.tokensIn = tokensIn\n if (tokensOut !== undefined) event.tokensOut = tokensOut\n if (costUsd !== undefined) event.costUsd = costUsd\n return event\n}\n\nfunction pickFiniteNumber(data: Record<string, unknown>, keys: string[]): number | undefined {\n for (const key of keys) {\n const value = data[key]\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\n/**\n * Project one `SandboxEvent` onto the `RuntimeStreamEvent` chat-UX vocabulary,\n * for runtimes that bridge a sandbox `streamPrompt` into the\n * `AgentRuntime.act` streaming contract. Returns `undefined` for events that\n * have no faithful projection — the raw stream is preserved separately for the\n * `OutputAdapter`, so an unmapped event never loses data.\n *\n * Mapped (the task-optional incremental variants — no synthesized task\n * lifecycle, no guessed tool-part shapes):\n * - `message.part.updated` text part → `text_delta`\n * - `message.part.updated` reasoning/thinking part → `reasoning_delta`\n * - cost-bearing events → `llm_call` (shared with the ledger extractor)\n *\n * The opencode backend emits incremental text as\n * `{ type: 'message.part.updated', data: { part: { type, text }, delta } }`;\n * `delta` is the increment, `part.text` the running accumulation.\n */\nexport function mapSandboxEvent(\n event: SandboxEvent,\n opts: { agentRunName?: string } = {},\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const type = String(event.type ?? '')\n const data =\n event.data && typeof event.data === 'object'\n ? (event.data as Record<string, unknown>)\n : ({} as Record<string, unknown>)\n\n if (type === 'message.part.updated') {\n const part =\n data.part && typeof data.part === 'object' ? (data.part as Record<string, unknown>) : {}\n const partType = String(part.type ?? '')\n const delta = typeof data.delta === 'string' ? data.delta : undefined\n const text = delta ?? (typeof part.text === 'string' ? part.text : undefined)\n if (text === undefined) return undefined\n if (partType === 'text') return { type: 'text_delta', text }\n if (partType === 'reasoning' || partType === 'thinking')\n return { type: 'reasoning_delta', text }\n return undefined\n }\n\n return extractLlmCallEvent(event, opts.agentRunName ?? 'agent')\n}\n","/**\n * @experimental\n *\n * `runLoop` — the topology-agnostic kernel built atop the sandbox SDK.\n *\n * Each iteration:\n * 1. `driver.plan(task, history)` → N tasks (1 = refine, N = fanout, 0 = stop)\n * 2. For each task (parallel, bounded by `maxConcurrency`):\n * a. round-robin an `AgentRunSpec` from `agentRuns`\n * b. `sandboxClient.create({ backend: { profile }, ...overrides })`\n * c. emit `loop.iteration.dispatch` with the placement\n * (`{ sibling, sandboxId }` or `{ fleet, fleetId, machineId, sandboxId }`)\n * d. iterate `box.streamPrompt(taskToPrompt(task))` and collect events\n * 3. `output.parse(events)` → typed `Output`\n * 4. `validator?.validate(output)` → `DefaultVerdict`\n * 5. Append `Iteration` to history; emit `loop.iteration.ended`\n * 6. `driver.decide(history)` → if terminal, return result + winner\n *\n * The kernel owns: iteration accounting, per-iteration timing, error\n * capture, abort propagation, concurrency cap, cost aggregation, and trace\n * emission. The kernel does NOT own: what the agent runs (sandbox SDK +\n * profile), how outputs are decoded (output adapter), how outputs are\n * scored (validator), or topology (driver).\n */\n\nimport type {\n AgentProfile,\n CreateSandboxOptions,\n SandboxEvent,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport { ValidationError } from '../errors'\nimport { extractLlmCallEvent } from './sandbox-events'\nimport type {\n AgentRunSpec,\n Driver,\n ExecCtx,\n Iteration,\n LoopResult,\n LoopSandboxClient,\n LoopSandboxPlacement,\n LoopTraceEmitter,\n LoopTraceEvent,\n LoopWinner,\n OutputAdapter,\n Validator,\n} from './types'\n\nconst DEFAULT_MAX_ITERATIONS = 10\nconst DEFAULT_MAX_CONCURRENCY = 4\n\n/** @experimental */\nexport interface RunLoopOptions<Task, Output, Decision> {\n driver: Driver<Task, Output, Decision>\n /**\n * Single agent spec — every iteration uses this profile. Mutually\n * exclusive with `agentRuns`.\n */\n agentRun?: AgentRunSpec<Task>\n /**\n * Multiple specs for heterogeneous fanout. The kernel round-robins\n * through them when the driver plans N tasks. Mutually exclusive with\n * `agentRun`.\n */\n agentRuns?: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator?: Validator<Output>\n task: Task\n ctx: ExecCtx\n /** Default 10. Hard cap on total iterations across all `plan()` rounds. */\n maxIterations?: number\n /** Default 4. In-flight worker cap within a single `plan()` batch. */\n maxConcurrency?: number\n /**\n * Pre-allocated id for trace correlation. Default = `loop-${random}`.\n * Surfaces as `runId` on every emitted `LoopTraceEvent`.\n */\n runId?: string\n /**\n * Clock override; default `Date.now`. Deterministic tests pass a\n * monotonic counter to stabilize iteration timing fields.\n */\n now?: () => number\n /**\n * Override the default winner selector (highest-valid-score, ties broken\n * by earliest iteration).\n */\n selectWinner?: (iterations: Iteration<Task, Output>[]) => LoopWinner<Task, Output> | undefined\n}\n\n/** @experimental */\nexport async function runLoop<Task, Output, Decision>(\n options: RunLoopOptions<Task, Output, Decision>,\n): Promise<LoopResult<Task, Output, Decision>> {\n const specs = resolveAgentRuns(options)\n const maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS\n if (!Number.isFinite(maxIterations) || maxIterations <= 0) {\n throw new ValidationError('runLoop: maxIterations must be > 0')\n }\n const maxConcurrency = options.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY\n if (!Number.isFinite(maxConcurrency) || maxConcurrency <= 0) {\n throw new ValidationError('runLoop: maxConcurrency must be > 0')\n }\n if (!options.ctx?.sandboxClient || typeof options.ctx.sandboxClient.create !== 'function') {\n throw new ValidationError('runLoop: ctx.sandboxClient.create is required')\n }\n const now = options.now ?? Date.now\n const runId = options.runId ?? `loop-${randomSuffix()}`\n const loopStart = now()\n const driverName = options.driver.name ?? 'driver'\n const iterations: Iteration<Task, Output>[] = []\n let round = 0\n\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.started',\n runId,\n timestamp: now(),\n payload: {\n driver: driverName,\n agentRunNames: specs.map((spec) => spec.name ?? spec.profile.name ?? 'agent'),\n maxIterations,\n maxConcurrency,\n },\n })\n\n const controller = new AbortController()\n const onOuterAbort = () => controller.abort()\n if (options.ctx.signal) {\n if (options.ctx.signal.aborted) controller.abort()\n else options.ctx.signal.addEventListener('abort', onOuterAbort, { once: true })\n }\n\n try {\n while (iterations.length < maxIterations) {\n if (controller.signal.aborted) throwAbort()\n const planned = await options.driver.plan(options.task, iterations)\n const planDesc = options.driver.describePlan?.()\n const roundIndex = round\n const baseIndex = iterations.length\n const remaining = maxIterations - iterations.length\n const slice = planned.slice(0, remaining)\n // Edge lineage: a driver may DECLARE the branch source (planner-authored\n // topology); otherwise the kernel infers it — round 0 branches from root\n // (undefined), later rounds from the best-valid (else latest) iteration so\n // far. Either way it's emitted, not guessed by the viewer.\n const parentIndex =\n planDesc?.parentIndex ?? (roundIndex === 0 ? undefined : branchPoint(iterations))\n const childIndices = slice.map((_, i) => baseIndex + i)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.plan',\n runId,\n timestamp: now(),\n payload: {\n roundIndex,\n plannedCount: planned.length,\n moveKind:\n planDesc?.kind ??\n (planned.length === 0 ? 'stop' : planned.length === 1 ? 'refine' : 'fanout'),\n rationale: planDesc?.rationale,\n parentIndex,\n childIndices,\n },\n })\n round += 1\n if (planned.length === 0) break\n\n // Reserve slots up front so concurrent workers may mutate by index.\n for (let i = 0; i < slice.length; i += 1) {\n const spec = specs[(baseIndex + i) % specs.length]!\n iterations.push({\n index: baseIndex + i,\n task: slice[i] as Task,\n agentRunName: spec.name ?? spec.profile.name ?? 'agent',\n events: [],\n startedAt: now(),\n endedAt: 0,\n costUsd: 0,\n tokenUsage: { input: 0, output: 0 },\n })\n }\n\n await runBatch({\n slice,\n baseIndex,\n iterations,\n specs,\n output: options.output,\n validator: options.validator,\n maxConcurrency,\n signal: controller.signal,\n ctx: options.ctx,\n runId,\n now,\n roundIndex,\n parentIndex,\n })\n\n if (controller.signal.aborted) throwAbort()\n\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n if (isTerminalDecision(decision)) {\n return finalize({\n options,\n decision,\n iterations,\n startMs: loopStart,\n now,\n runId,\n })\n }\n }\n\n if (iterations.length >= maxIterations) {\n // Cap reached without a terminal decision — ask the driver one more time\n // for its final state, then close out.\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n return finalize({ options, decision, iterations, startMs: loopStart, now, runId })\n }\n // `plan()` returned `[]` before `decide()` reached a terminal state.\n const decision = await options.driver.decide(iterations)\n await emitTrace(options.ctx.traceEmitter, {\n kind: 'loop.decision',\n runId,\n timestamp: now(),\n payload: { decision: serializeDecision(decision), historyLength: iterations.length },\n })\n return finalize({ options, decision, iterations, startMs: loopStart, now, runId })\n } finally {\n if (options.ctx.signal) options.ctx.signal.removeEventListener('abort', onOuterAbort)\n }\n}\n\ninterface RunBatchArgs<Task, Output> {\n slice: Task[]\n baseIndex: number\n iterations: Iteration<Task, Output>[]\n specs: AgentRunSpec<Task>[]\n output: OutputAdapter<Output>\n validator: Validator<Output> | undefined\n maxConcurrency: number\n signal: AbortSignal\n ctx: ExecCtx\n runId: string\n now: () => number\n /** Plan round these iterations belong to — stamped as `groupId`. */\n roundIndex: number\n /** Iteration this round branched from — stamped as `parentIndex`. */\n parentIndex?: number\n}\n\nasync function runBatch<Task, Output>(args: RunBatchArgs<Task, Output>) {\n const queue = args.slice.map((task, offset) => ({ task, index: args.baseIndex + offset }))\n const inflight = new Set<Promise<void>>()\n while (queue.length > 0 || inflight.size > 0) {\n while (inflight.size < args.maxConcurrency && queue.length > 0) {\n const item = queue.shift()!\n const p = executeIteration({ ...args, item }).finally(() => inflight.delete(p))\n inflight.add(p)\n }\n if (inflight.size === 0) break\n await Promise.race(inflight)\n }\n}\n\ninterface ExecuteIterationArgs<Task, Output> extends RunBatchArgs<Task, Output> {\n item: { task: Task; index: number }\n}\n\nasync function executeIteration<Task, Output>(args: ExecuteIterationArgs<Task, Output>) {\n const slot = args.iterations[args.item.index]\n if (!slot)\n throw new ValidationError(`runLoop: missing iteration slot at index ${args.item.index}`)\n const spec = args.specs[args.item.index % args.specs.length]\n if (!spec) throw new ValidationError('runLoop: no AgentRunSpec available for iteration')\n slot.startedAt = args.now()\n slot.agentRunName = spec.name ?? spec.profile.name ?? 'agent'\n\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.started',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n taskHash: hashJson(args.item.task),\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n },\n })\n\n try {\n const box = await createSandboxForSpec(args.ctx.sandboxClient, spec, args.signal)\n const placement = describePlacementSafe(args.ctx.sandboxClient, box)\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.dispatch',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n placement: placement.kind,\n sandboxId: placement.sandboxId,\n fleetId: placement.fleetId,\n machineId: placement.machineId,\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n },\n })\n const message = spec.taskToPrompt(args.item.task)\n const events: SandboxEvent[] = []\n for await (const event of box.streamPrompt(message, { signal: args.signal })) {\n events.push(event)\n const llmCall = extractLlmCallEvent(event, slot.agentRunName)\n if (llmCall) {\n slot.costUsd += llmCall.costUsd ?? 0\n slot.tokenUsage.input += llmCall.tokensIn ?? 0\n slot.tokenUsage.output += llmCall.tokensOut ?? 0\n args.ctx.runHandle?.observe(llmCall)\n }\n }\n slot.events = events\n slot.output = args.output.parse(events)\n if (args.validator) {\n slot.verdict = await args.validator.validate(slot.output, {\n iteration: args.item.index,\n signal: args.signal,\n traceEmitter: args.ctx.traceEmitter,\n })\n }\n } catch (err) {\n slot.error = err instanceof Error ? err : new Error(String(err))\n } finally {\n slot.endedAt = args.now()\n await emitTrace(args.ctx.traceEmitter, {\n kind: 'loop.iteration.ended',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n iterationIndex: args.item.index,\n agentRunName: slot.agentRunName,\n outputHash: slot.output !== undefined ? hashJson(slot.output) : undefined,\n verdict: slot.verdict,\n error: slot.error?.message,\n costUsd: slot.costUsd,\n durationMs: slot.endedAt - slot.startedAt,\n tokenUsage:\n slot.tokenUsage.input || slot.tokenUsage.output ? { ...slot.tokenUsage } : undefined,\n groupId: args.roundIndex,\n parentIndex: args.parentIndex,\n outputPreview: slot.output !== undefined ? previewOutput(slot.output) : undefined,\n },\n })\n }\n}\n\n/**\n * Branch point for a new round — the iteration a later round descends from.\n * Highest-valid-score iteration so far; ties + no-valid fall back to the latest\n * index. Inferred (not driver-declared), so refine renders as a chain and\n * fanout→refine chains off the fanout winner.\n */\nfunction branchPoint<Task, Output>(\n iterations: ReadonlyArray<Iteration<Task, Output>>,\n): number | undefined {\n if (iterations.length === 0) return undefined\n let best = iterations.length - 1\n let bestScore = -Infinity\n for (const iter of iterations) {\n if (iter.verdict?.valid !== true) continue\n const score = iter.verdict.score ?? 0\n if (score > bestScore) {\n bestScore = score\n best = iter.index\n }\n }\n return best\n}\n\n/** Bounded string preview of a parsed output for a viewer's drawer — never the\n * full payload. JSON when serializable, else `String()`, truncated to 280. */\nfunction previewOutput(output: unknown): string {\n let s: string\n try {\n s = typeof output === 'string' ? output : (JSON.stringify(output) ?? String(output))\n } catch {\n s = String(output)\n }\n return s.length > 280 ? `${s.slice(0, 280)}…` : s\n}\n\nfunction describePlacementSafe(\n client: LoopSandboxClient,\n box: SandboxInstance,\n): LoopSandboxPlacement {\n if (typeof client.describePlacement === 'function') {\n try {\n const result = client.describePlacement(box)\n if (\n result &&\n typeof result === 'object' &&\n (result.kind === 'sibling' || result.kind === 'fleet')\n ) {\n return {\n kind: result.kind,\n sandboxId: result.sandboxId ?? readSandboxId(box),\n fleetId: result.fleetId,\n machineId: result.machineId,\n }\n }\n } catch {\n // Adapter bug must not corrupt the iteration; fall through to default.\n }\n }\n return { kind: 'sibling', sandboxId: readSandboxId(box) }\n}\n\nfunction readSandboxId(box: SandboxInstance): string | undefined {\n const raw = (box as unknown as { id?: unknown }).id\n return typeof raw === 'string' && raw.length > 0 ? raw : undefined\n}\n\n/**\n * Instantiate a sandbox for an `AgentRunSpec`: sets `backend.profile` to the\n * spec's profile (inferring the backend type when the spec doesn't override\n * it) and merges `sandboxOverrides`. Shared by the loop kernel and the\n * `AgentRuntime.act` sandbox bridge so both boot the sandbox identically.\n */\nexport async function createSandboxForSpec<Task>(\n client: LoopSandboxClient,\n spec: AgentRunSpec<Task>,\n signal: AbortSignal,\n): Promise<SandboxInstance> {\n const overrides = spec.sandboxOverrides ?? {}\n const overrideBackend = overrides.backend\n const opts: CreateSandboxOptions = {\n ...overrides,\n backend: {\n type: overrideBackend?.type ?? inferBackendType(spec.profile),\n profile: spec.profile satisfies AgentProfile,\n ...(overrideBackend?.model ? { model: overrideBackend.model } : {}),\n ...(overrideBackend?.server ? { server: overrideBackend.server } : {}),\n },\n }\n // Cooperative cancellation: if the abort signal fires while .create is\n // pending, the promise itself is not abortable but the inflight prompt is.\n if (signal.aborted) throwAbort()\n return client.create(opts)\n}\n\nfunction inferBackendType(\n profile: AgentProfile,\n): CreateSandboxOptions['backend'] extends infer B\n ? B extends { type: infer T }\n ? T\n : never\n : never {\n // The sandbox SDK accepts profile-driven backend selection by name. When the\n // profile has no explicit hint we fall through to the SDK's default\n // ('opencode' on the platform side). Returning a literal here would lie\n // about provenance — let the SDK pick.\n type BackendType = NonNullable<CreateSandboxOptions['backend']>['type']\n const explicit = profile.metadata?.backendType\n if (typeof explicit === 'string') return explicit as BackendType\n return 'opencode' as BackendType\n}\n\ninterface FinalizeArgs<Task, Output, Decision> {\n options: RunLoopOptions<Task, Output, Decision>\n decision: Decision\n iterations: Iteration<Task, Output>[]\n startMs: number\n now: () => number\n runId: string\n}\n\nfunction finalize<Task, Output, Decision>(\n args: FinalizeArgs<Task, Output, Decision>,\n): LoopResult<Task, Output, Decision> {\n const winner = (args.options.selectWinner ?? defaultSelectWinner)(args.iterations)\n const costUsd = args.iterations.reduce((sum, iter) => sum + (iter.costUsd || 0), 0)\n const tokenUsage = args.iterations.reduce(\n (acc, iter) => {\n acc.input += iter.tokenUsage?.input ?? 0\n acc.output += iter.tokenUsage?.output ?? 0\n return acc\n },\n { input: 0, output: 0 },\n )\n const result: LoopResult<Task, Output, Decision> = {\n decision: args.decision,\n iterations: args.iterations,\n winner,\n durationMs: args.now() - args.startMs,\n costUsd,\n tokenUsage,\n }\n void emitTrace(args.options.ctx.traceEmitter, {\n kind: 'loop.ended',\n runId: args.runId,\n timestamp: args.now(),\n payload: {\n winnerIterationIndex: winner?.iterationIndex,\n totalCostUsd: costUsd,\n durationMs: result.durationMs,\n iterations: args.iterations.length,\n },\n })\n return result\n}\n\nfunction defaultSelectWinner<Task, Output>(\n iterations: Iteration<Task, Output>[],\n): LoopWinner<Task, Output> | undefined {\n const candidates = iterations.filter((iter) => iter.output !== undefined && !iter.error)\n if (candidates.length === 0) return undefined\n const valid = candidates.filter((iter) => iter.verdict?.valid === true)\n const pool = valid.length > 0 ? valid : candidates\n const sorted = [...pool].sort(\n (a, b) => (b.verdict?.score ?? 0) - (a.verdict?.score ?? 0) || a.index - b.index,\n )\n const top = sorted[0]\n if (!top || top.output === undefined) return undefined\n return {\n task: top.task,\n output: top.output,\n verdict: top.verdict,\n iterationIndex: top.index,\n agentRunName: top.agentRunName,\n }\n}\n\nfunction resolveAgentRuns<Task, Output, Decision>(\n options: RunLoopOptions<Task, Output, Decision>,\n): AgentRunSpec<Task>[] {\n if (options.agentRun && options.agentRuns) {\n throw new ValidationError('runLoop: pass exactly one of `agentRun` or `agentRuns`')\n }\n if (options.agentRun) return [options.agentRun]\n if (options.agentRuns && options.agentRuns.length > 0) return options.agentRuns\n throw new ValidationError('runLoop: `agentRun` or non-empty `agentRuns` is required')\n}\n\nfunction isTerminalDecision(decision: unknown): boolean {\n return (\n decision === 'stop' || decision === 'pick-winner' || decision === 'fail' || decision === 'done'\n )\n}\n\nfunction serializeDecision(decision: unknown): string {\n if (typeof decision === 'string') return decision\n if (decision === null || decision === undefined) return 'null'\n try {\n return JSON.stringify(decision)\n } catch {\n return String(decision)\n }\n}\n\nasync function emitTrace(\n emitter: LoopTraceEmitter | undefined,\n event: LoopTraceEvent,\n): Promise<void> {\n if (!emitter) return\n await emitter.emit(event)\n}\n\nfunction randomSuffix(len = 8): string {\n return Math.random()\n .toString(36)\n .slice(2, 2 + len)\n}\n\nfunction throwAbort(): never {\n const err = new Error('aborted')\n err.name = 'AbortError'\n throw err\n}\n\n/**\n * Stable hash for the trace payload. Not cryptographic — only used so\n * downstream eval pipelines can group iterations whose task / output is the\n * same. Bare structural hash; non-JSON values stringify via their `toString`.\n */\nfunction hashJson(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(value) ?? String(value)\n } catch {\n str = String(value)\n }\n // FNV-1a 32-bit — branch-free, dependency-free, good enough for grouping.\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","/**\n * `loopDispatch` — turn `runLoop` into an agent-eval campaign dispatch.\n *\n * Without this adapter a consumer wiring `runLoop` into `runProfileMatrix` /\n * `runCampaign` has to, by hand, every time: (a) build an `ExecCtx` with a\n * sandbox client, (b) adapt the campaign `DispatchContext.trace` into a\n * `LoopTraceEmitter` (or lose all loop trace correlation), and (c) remember to\n * forward the loop's cost + tokens via `ctx.cost` (forgetting it yields a\n * `{0,0}` cell the backend-integrity guard reads as a stub). Three foot-guns,\n * the third silent. The fleet's products skipped (c) and fell back to a\n * `workerRecords[]` side-channel — the exact anti-pattern the substrate exists\n * to kill.\n *\n * `loopDispatch` collapses all three into one typed call:\n *\n * const dispatch = loopDispatch({\n * sandboxClient,\n * toLoopOptions: (scenario, profile) => ({ driver, agentRun, output, validator, task }),\n * })\n * await runProfileMatrix({ profiles, scenarios, dispatch, judges, commitSha })\n *\n * Usage is reported automatically; trace events are forwarded automatically;\n * the ctx is built automatically. The seam becomes impossible to mis-wire.\n *\n * Typed structurally against the campaign `DispatchContext` (imported type-only\n * from `@tangle-network/agent-eval/campaign`) — a downward dependency, never an\n * inversion.\n */\n\n// agent-eval's AgentProfile (the eval-harness unit of variation, `model: string`)\n// — NOT sandbox's AgentProfile. ProfileDispatchFn is keyed on the former.\nimport type { AgentProfile } from '@tangle-network/agent-eval'\nimport type {\n CampaignTraceWriter,\n DispatchContext,\n DispatchFn,\n ProfileDispatchFn,\n Scenario,\n} from '@tangle-network/agent-eval/campaign'\nimport { reportLoopUsage } from './report-usage'\nimport { type RunLoopOptions, runLoop } from './run-loop'\nimport type { LoopResult, LoopSandboxClient, LoopTraceEmitter } from './types'\n\n/** runLoop options minus the `ctx` (loopDispatch builds the ctx). */\nexport type LoopOptionsForDispatch<Task, Output, Decision> = Omit<\n RunLoopOptions<Task, Output, Decision>,\n 'ctx'\n>\n\nexport interface LoopDispatchOptions<\n Task,\n Output,\n Decision,\n TScenario extends Scenario,\n TArtifact,\n> {\n /** Sandbox client used for every cell's `runLoop`. Supplied once. */\n sandboxClient: LoopSandboxClient\n /** Build the per-cell runLoop options from the scenario (+ profile, when\n * used with `runProfileMatrix`). */\n toLoopOptions: (\n scenario: TScenario,\n profile: AgentProfile,\n ) => LoopOptionsForDispatch<Task, Output, Decision>\n /** Map the finished loop to the artifact the judges score. Default:\n * `result.winner?.output`. A loop with no winner yields `undefined` (judges\n * skip the cell) — but the loop's token usage is STILL reported, so the\n * integrity guard sees real activity. */\n toArtifact?: (result: LoopResult<Task, Output, Decision>) => TArtifact\n /** Forward `loop.*` trace events into the campaign's scoped trace so loop\n * spans correlate with the cell. Default true. */\n forwardTrace?: boolean\n /** Cost-meter source label for the loop's spend. Default `'loop'`. */\n costSource?: string\n}\n\n/** Bridge a campaign `DispatchContext.trace` to a `LoopTraceEmitter` so every\n * `loop.*` event lands as a span under the cell's scoped trace. */\nfunction campaignTraceToLoopEmitter(trace: CampaignTraceWriter): LoopTraceEmitter {\n return {\n emit(event) {\n trace\n .span(event.kind, { runId: event.runId, timestamp: event.timestamp, ...event.payload })\n .end()\n },\n }\n}\n\nasync function runLoopForCell<Task, Output, Decision, TScenario extends Scenario, TArtifact>(\n opts: LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact>,\n scenario: TScenario,\n profile: AgentProfile,\n ctx: DispatchContext,\n): Promise<TArtifact> {\n const loopOptions = opts.toLoopOptions(scenario, profile)\n const result = await runLoop<Task, Output, Decision>({\n ...loopOptions,\n ctx: {\n sandboxClient: opts.sandboxClient,\n signal: ctx.signal,\n traceEmitter: opts.forwardTrace === false ? undefined : campaignTraceToLoopEmitter(ctx.trace),\n },\n })\n reportLoopUsage(ctx.cost, result, opts.costSource ?? 'loop')\n const toArtifact =\n opts.toArtifact ?? ((r: LoopResult<Task, Output, Decision>) => r.winner?.output as TArtifact)\n return toArtifact(result)\n}\n\n/**\n * Adapter for `runProfileMatrix` (profile is an axis). Returns a\n * `ProfileDispatchFn` that runs `runLoop` per (profile, scenario) cell and\n * reports usage automatically.\n */\nexport function loopDispatch<Task, Output, Decision, TScenario extends Scenario, TArtifact>(\n opts: LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact>,\n): ProfileDispatchFn<TScenario, TArtifact> {\n return (profile, scenario, ctx) => runLoopForCell(opts, scenario, profile, ctx)\n}\n\n/**\n * Adapter for `runCampaign` (no profile axis). `toLoopOptions` receives only\n * the scenario; the `profile` passed to the shared core is a stable sentinel\n * so a single `runLoop` config is reused across cells.\n */\nexport function loopCampaignDispatch<Task, Output, Decision, TScenario extends Scenario, TArtifact>(\n opts: Omit<LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact>, 'toLoopOptions'> & {\n toLoopOptions: (scenario: TScenario) => LoopOptionsForDispatch<Task, Output, Decision>\n },\n): DispatchFn<TScenario, TArtifact> {\n const profileSentinel = { id: 'loop-campaign', model: 'n/a@loop-campaign' } as AgentProfile\n const profiled: LoopDispatchOptions<Task, Output, Decision, TScenario, TArtifact> = {\n ...opts,\n toLoopOptions: (scenario) => opts.toLoopOptions(scenario),\n }\n return (scenario, ctx) => runLoopForCell(profiled, scenario, profileSentinel, ctx)\n}\n"],"mappings":"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","names":["decision"]}
@@ -0,0 +1,64 @@
1
+ import {
2
+ DELEGATE_CODE_DESCRIPTION,
3
+ DELEGATE_CODE_INPUT_SCHEMA,
4
+ DELEGATE_CODE_TOOL_NAME,
5
+ DELEGATE_FEEDBACK_DESCRIPTION,
6
+ DELEGATE_FEEDBACK_INPUT_SCHEMA,
7
+ DELEGATE_FEEDBACK_TOOL_NAME,
8
+ DELEGATE_RESEARCH_DESCRIPTION,
9
+ DELEGATE_RESEARCH_INPUT_SCHEMA,
10
+ DELEGATE_RESEARCH_TOOL_NAME,
11
+ DELEGATION_HISTORY_DESCRIPTION,
12
+ DELEGATION_HISTORY_INPUT_SCHEMA,
13
+ DELEGATION_HISTORY_TOOL_NAME,
14
+ DELEGATION_STATUS_DESCRIPTION,
15
+ DELEGATION_STATUS_INPUT_SCHEMA,
16
+ DELEGATION_STATUS_TOOL_NAME
17
+ } from "./chunk-HVYOHJHK.js";
18
+
19
+ // src/mcp/openai-tools.ts
20
+ function buildTool(name, description, parameters) {
21
+ return {
22
+ type: "function",
23
+ function: { name, description, parameters: { ...parameters } }
24
+ };
25
+ }
26
+ function mcpToolsForRuntimeMcp() {
27
+ return [
28
+ buildTool(
29
+ DELEGATE_CODE_TOOL_NAME,
30
+ DELEGATE_CODE_DESCRIPTION,
31
+ DELEGATE_CODE_INPUT_SCHEMA
32
+ ),
33
+ buildTool(
34
+ DELEGATE_RESEARCH_TOOL_NAME,
35
+ DELEGATE_RESEARCH_DESCRIPTION,
36
+ DELEGATE_RESEARCH_INPUT_SCHEMA
37
+ ),
38
+ buildTool(
39
+ DELEGATE_FEEDBACK_TOOL_NAME,
40
+ DELEGATE_FEEDBACK_DESCRIPTION,
41
+ DELEGATE_FEEDBACK_INPUT_SCHEMA
42
+ ),
43
+ buildTool(
44
+ DELEGATION_STATUS_TOOL_NAME,
45
+ DELEGATION_STATUS_DESCRIPTION,
46
+ DELEGATION_STATUS_INPUT_SCHEMA
47
+ ),
48
+ buildTool(
49
+ DELEGATION_HISTORY_TOOL_NAME,
50
+ DELEGATION_HISTORY_DESCRIPTION,
51
+ DELEGATION_HISTORY_INPUT_SCHEMA
52
+ )
53
+ ];
54
+ }
55
+ function mcpToolsForRuntimeMcpSubset(names) {
56
+ const allowed = new Set(names);
57
+ return mcpToolsForRuntimeMcp().filter((tool) => allowed.has(tool.function.name));
58
+ }
59
+
60
+ export {
61
+ mcpToolsForRuntimeMcp,
62
+ mcpToolsForRuntimeMcpSubset
63
+ };
64
+ //# sourceMappingURL=chunk-NRZOXCJK.js.map