@tangle-network/agent-runtime 0.240.0 → 0.247.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 (79) hide show
  1. package/dist/{activation-q224yRQK.js → activation-DYqnl8zq.js} +3 -3
  2. package/dist/{activation-q224yRQK.js.map → activation-DYqnl8zq.js.map} +1 -1
  3. package/dist/{activation-CtkpoWet.d.ts → activation-DizpINK3.d.ts} +115 -5
  4. package/dist/agent.d.ts +2 -2
  5. package/dist/agent.js +2 -2
  6. package/dist/candidate-execution/index.js +7 -7
  7. package/dist/candidate-execution/index.js.map +1 -1
  8. package/dist/{coordination-driver-CMprWr0k.js → coordination-driver-BV4AAUns.js} +35 -14
  9. package/dist/coordination-driver-BV4AAUns.js.map +1 -0
  10. package/dist/{delegate-kwBecu_w.js → delegate-DQAzB5Xv.js} +2 -2
  11. package/dist/{delegate-kwBecu_w.js.map → delegate-DQAzB5Xv.js.map} +1 -1
  12. package/dist/{durable-file-D24y9zg7.js → durable-file-DWQA4ooo.js} +2 -2
  13. package/dist/{durable-file-D24y9zg7.js.map → durable-file-DWQA4ooo.js.map} +1 -1
  14. package/dist/durable.d.ts +2 -2
  15. package/dist/durable.js +3 -3
  16. package/dist/{graph-Bke7I2gs.js → graph-DcBmMLIp.js} +3 -3
  17. package/dist/{graph-Bke7I2gs.js.map → graph-DcBmMLIp.js.map} +1 -1
  18. package/dist/{improvement-cycle-BpSVwIJw.js → improvement-cycle-B049YmQ8.js} +458 -60
  19. package/dist/improvement-cycle-B049YmQ8.js.map +1 -0
  20. package/dist/{index-CbZaoYbD.d.ts → index-DLzlXwr6.d.ts} +14 -9
  21. package/dist/index.d.ts +11 -8
  22. package/dist/index.js +27 -17
  23. package/dist/index.js.map +1 -1
  24. package/dist/intelligence.d.ts +7 -5
  25. package/dist/intelligence.js +15 -11
  26. package/dist/intelligence.js.map +1 -1
  27. package/dist/kernel.d.ts +3 -3
  28. package/dist/kernel.js +9 -9
  29. package/dist/{loop-runner-bin-BUkkPt10.d.ts → loop-runner-bin-HbMECmxT.d.ts} +3 -3
  30. package/dist/{loop-runner-bin-DU8XqsGN.js → loop-runner-bin-iqq1azfy.js} +3 -3
  31. package/dist/{loop-runner-bin-DU8XqsGN.js.map → loop-runner-bin-iqq1azfy.js.map} +1 -1
  32. package/dist/loop-runner-bin.d.ts +1 -1
  33. package/dist/loop-runner-bin.js +1 -1
  34. package/dist/mcp/bin.js +3 -3
  35. package/dist/mcp/index.d.ts +5 -5
  36. package/dist/mcp/index.js +4 -4
  37. package/dist/{openai-tools-BI1ofIfL.d.ts → openai-tools-DvLk_Ddg.d.ts} +2 -2
  38. package/dist/{prepare-Dc30WRB0.js → prepare-CibQrhfi.js} +28 -28
  39. package/dist/prepare-CibQrhfi.js.map +1 -0
  40. package/dist/profiles.d.ts +2 -2
  41. package/dist/{protected-model-port-D5gDcnrH.js → protected-model-port-Dhdi5mDl.js} +3 -3
  42. package/dist/{protected-model-port-D5gDcnrH.js.map → protected-model-port-Dhdi5mDl.js.map} +1 -1
  43. package/dist/{protected-redaction-wGo44k2K.js → protected-redaction-Fn1ETfJ-.js} +6 -6
  44. package/dist/protected-redaction-Fn1ETfJ-.js.map +1 -0
  45. package/dist/{provision-supervisor-DoSrqsM7.js → provision-supervisor-BgQx2Avp.js} +5 -5
  46. package/dist/{provision-supervisor-DoSrqsM7.js.map → provision-supervisor-BgQx2Avp.js.map} +1 -1
  47. package/dist/{run-layout-hZREkcfu.js → run-layout-hKAJGF4g.js} +7 -2
  48. package/dist/run-layout-hKAJGF4g.js.map +1 -0
  49. package/dist/{runtime-CmuAQsWI.js → runtime-HpTXhB3g.js} +16 -13
  50. package/dist/{runtime-CmuAQsWI.js.map → runtime-HpTXhB3g.js.map} +1 -1
  51. package/dist/{server-shkdLqls.js → server-OOE7mXrN.js} +3 -3
  52. package/dist/{server-shkdLqls.js.map → server-OOE7mXrN.js.map} +1 -1
  53. package/dist/{stream-agent-turn-DayHmtvw.d.ts → stream-agent-turn-CcumM0Bu.d.ts} +2 -2
  54. package/dist/{structural-rollout-CW67upUV.js → structural-rollout-z1A0okaB.js} +2 -2
  55. package/dist/{structural-rollout-CW67upUV.js.map → structural-rollout-z1A0okaB.js.map} +1 -1
  56. package/dist/{substrate-iQOskmQ_.d.ts → substrate-CQ0hfewn.d.ts} +2 -2
  57. package/dist/{supervise-DzoCYAe-.js → supervise-DZEOpzRw.js} +148 -35
  58. package/dist/supervise-DZEOpzRw.js.map +1 -0
  59. package/dist/{supervisor-CFSPj8rx.js → supervisor-BIBWUFUr.js} +325 -150
  60. package/dist/supervisor-BIBWUFUr.js.map +1 -0
  61. package/dist/testing.d.ts +2 -2
  62. package/dist/testing.js +398 -398
  63. package/dist/{top-app-CMMd8DgR.js → top-app-d-bmwO7O.js} +2 -2
  64. package/dist/{top-app-CMMd8DgR.js.map → top-app-d-bmwO7O.js.map} +1 -1
  65. package/dist/tui/bin.js +1 -1
  66. package/dist/tui/index.d.ts +1 -1
  67. package/dist/tui/index.js +2 -2
  68. package/dist/{types-CEma9LKR.d.ts → types-BUhz284C.d.ts} +25 -11
  69. package/dist/{workspace-archive-CBX0hwL_.js → workspace-archive-DSRT4Tro.js} +8 -8
  70. package/dist/workspace-archive-DSRT4Tro.js.map +1 -0
  71. package/package.json +6 -6
  72. package/dist/coordination-driver-CMprWr0k.js.map +0 -1
  73. package/dist/improvement-cycle-BpSVwIJw.js.map +0 -1
  74. package/dist/prepare-Dc30WRB0.js.map +0 -1
  75. package/dist/protected-redaction-wGo44k2K.js.map +0 -1
  76. package/dist/run-layout-hZREkcfu.js.map +0 -1
  77. package/dist/supervise-DzoCYAe-.js.map +0 -1
  78. package/dist/supervisor-CFSPj8rx.js.map +0 -1
  79. package/dist/workspace-archive-CBX0hwL_.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["deriveTurnId","canonicalCandidateDigest"],"sources":["../src/runtime/profile-execution-backend.ts","../src/conversation/call-policy.ts","../src/conversation/headers.ts","../src/conversation/turn-id.ts","../src/conversation/run-conversation.ts","../src/conversation/conversation-backend.ts","../src/conversation/define-conversation.ts","../src/conversation/journal.ts","../src/conversation/journal-sql.ts","../src/conversation/run-persona.ts","../src/improvement/build-prompts.ts","../src/improvement/mcp-serve-verifier.ts","../src/improvement/official-optimizers.ts","../src/improvement/profile-improvement-harness.ts","../src/improvement/prompt-instructions-profile-components.ts","../src/improvement/reflective-generator.ts","../src/knowledge/activation.ts","../src/knowledge/supervised-update.ts","../src/knowledge/improvement-job.ts","../src/model-resolution.ts","../src/readiness.ts","../src/run.ts","../src/runtime-run.ts","../src/sse.ts"],"sourcesContent":["import type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { AgentTurnInput } from '@tangle-network/agent-interface/environment-provider'\nimport { BackendTransportError, ValidationError } from '../errors'\nimport type {\n AgentBackendContext,\n AgentExecutionBackend,\n BackendErrorDetail,\n RuntimeStreamEvent,\n} from '../types'\nimport { streamAgentTurn } from './stream-agent-turn'\nimport { executableAgentProfileSnapshot } from './supervise/executable-spec'\nimport type { ExecutorFactory } from './supervise/types'\n\n/**\n * Bind one exact profile and Runtime executor to the stable `AgentExecutionBackend` contract used\n * by `runAgentTaskStream` and conversations.\n *\n * Runtime still owns the model call through `streamAgentTurn`.\n * The adapter only translates the two stream protocols and carries the caller's request headers\n * into `ExecutorContext` so an HTTP executor can preserve authorization, recursion depth, and\n * trace identity.\n *\n * @stable\n */\nexport function createProfileExecutionBackend(options: {\n profile: AgentProfile\n executor: ExecutorFactory<unknown>\n}): AgentExecutionBackend {\n const profile = executableAgentProfileSnapshot(options.profile, 'createProfileExecutionBackend')\n const executor = options.executor\n\n return {\n kind: 'runtime-profile',\n async *stream(input, context) {\n const propagatedHeaders = snapshotPropagatedHeaders(context.propagatedHeaders)\n const contextualExecutor: ExecutorFactory<unknown> = (spec, executorContext) =>\n executor(spec, {\n ...executorContext,\n ...(propagatedHeaders === undefined ? {} : { propagatedHeaders }),\n })\n const providerMessages = input.providerOptions?.messages\n const turnInput: AgentTurnInput =\n input.messages !== undefined\n ? { providerOptions: { messages: input.messages.map((message) => ({ ...message })) } }\n : Array.isArray(providerMessages)\n ? { providerOptions: { messages: structuredClone(providerMessages) } }\n : { prompt: input.message ?? context.task.intent }\n let terminal = false\n let emittedText = false\n\n for await (const event of streamAgentTurn(\n { kind: 'executor', profile, factory: contextualExecutor },\n turnInput,\n {\n signal: context.signal,\n ...(context.turnId ? { callId: context.turnId } : {}),\n ...(context.runId ? { correlationId: context.runId } : {}),\n },\n )) {\n if (event.type === 'backend_start') continue\n if (event.type === 'backend_error') throw backendError(event.error, event.message)\n if (event.type === 'final') {\n terminal = true\n if (event.status !== 'completed') {\n throw backendError(event.error, event.reason)\n }\n if (!emittedText && event.text) {\n yield {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text: event.text,\n timestamp: event.timestamp,\n }\n }\n continue\n }\n if (event.type === 'text_delta') emittedText = true\n yield rebindEvent(event, context)\n }\n\n if (!terminal) {\n throw new ValidationError(\n 'createProfileExecutionBackend: streamAgentTurn ended without a terminal event',\n )\n }\n },\n }\n}\n\nfunction snapshotPropagatedHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n): Readonly<Record<string, string>> | undefined {\n if (headers === undefined) return undefined\n const snapshot: Record<string, string> = {}\n for (const [name, value] of Object.entries(headers)) {\n if (typeof value !== 'string') {\n throw new ValidationError(\n `createProfileExecutionBackend: propagated header ${JSON.stringify(name)} must be a string`,\n )\n }\n snapshot[name] = value\n }\n return Object.freeze(snapshot)\n}\n\nfunction backendError(detail: BackendErrorDetail | undefined, message: string): Error {\n if (detail?.kind === 'transport') {\n return new BackendTransportError('runtime-profile', detail.message, {\n status: detail.status,\n body: detail.body,\n })\n }\n return new Error(detail?.message ?? message)\n}\n\nfunction rebindEvent(event: RuntimeStreamEvent, context: AgentBackendContext): RuntimeStreamEvent {\n return {\n ...event,\n task: context.task,\n session: context.session,\n } as RuntimeStreamEvent\n}\n","/**\n *\n * Per-call resilience policy for participant backends: deadline, retry with\n * backoff, and a circuit breaker. Each policy is applied *around* a single\n * turn's backend invocation, not across the whole conversation — the\n * conversation-level credit cap and `maxTurns` bound the broader run.\n *\n * Deadlines abort the underlying backend stream via `AbortSignal` linkage so\n * the OpenAI/SDK clients tear down their HTTP request cleanly instead of\n * leaking sockets. Retries replay the same logical turn (same `turnId`) so\n * any caching gateway can dedupe. Circuit breakers are *per participant*: A's\n * failures don't open B's breaker.\n *\n * @stable\n */\n\n/** Pure judgment of whether an error is worth retrying. Defaults: TimeoutError, AbortError, fetch-level network errors. */\nexport type RetryableErrorPredicate = (err: unknown) => boolean\n\n/** Backoff between attempts. Constant ms, or `(attempt: 1-indexed) => ms`. */\nexport type RetryBackoff = number | ((attempt: number) => number)\n\n/** Circuit-breaker tuning. `failuresToOpen` consecutive failures opens it; closed only after `cooldownMs`. */\nexport interface CircuitBreakerConfig {\n failuresToOpen: number\n cooldownMs: number\n}\n\nexport interface BackendCallPolicy {\n /** Per-attempt wall clock limit. Exceeding fires an AbortSignal and is treated as a retryable failure. */\n perAttemptDeadlineMs?: number\n /** Number of retries after the first attempt; total attempts = 1 + maxRetries. Default 0. */\n maxRetries?: number\n /** Backoff between attempts. Default 250ms with jitter. */\n retryBackoffMs?: RetryBackoff\n /** Custom retry classifier. Defaults to retrying transport failures and retryable HTTP statuses. */\n isRetryable?: RetryableErrorPredicate\n /** Circuit breaker that opens after N consecutive failures per participant. */\n circuitBreaker?: CircuitBreakerConfig\n}\n\n/** Thrown when the circuit breaker is open for a participant and no retry is allowed yet. */\nexport class CircuitOpenError extends Error {\n constructor(participant: string, retryAfterMs: number) {\n super(\n `circuit open for participant '${participant}'; ${retryAfterMs}ms remaining before retry allowed`,\n )\n this.name = 'CircuitOpenError'\n }\n}\n\n/** Thrown when a backend call exceeds its per-attempt deadline. */\nexport class DeadlineExceededError extends Error {\n constructor(deadlineMs: number) {\n super(`backend call exceeded per-attempt deadline of ${deadlineMs}ms`)\n this.name = 'DeadlineExceededError'\n }\n}\n\n/**\n * Default retryable classification — network/timeout class errors. Errors\n * a model deliberately throws (validation, refusal, 4xx) are not retried;\n * those represent real outcomes, not transient infrastructure faults.\n */\nexport const defaultIsRetryable: RetryableErrorPredicate = (err) => {\n if (err instanceof DeadlineExceededError) return true\n if (err instanceof Error) {\n const name = err.name\n const message = err.message.toLowerCase()\n if (name === 'AbortError' || name === 'TimeoutError') return true\n if (\n message.includes('econnreset') ||\n message.includes('etimedout') ||\n message.includes('econnrefused') ||\n message.includes('socket hang up') ||\n message.includes('network') ||\n message.includes('fetch failed')\n ) {\n return true\n }\n }\n return false\n}\n\n/** Live circuit-breaker state — one instance per (participant, conversation run). */\nexport class CircuitBreakerState {\n private consecutiveFailures = 0\n private openedAt: number | undefined\n\n constructor(private readonly config: CircuitBreakerConfig | undefined) {}\n\n /**\n * Check whether the next call is allowed. Throws `CircuitOpenError` when\n * the breaker is open and the cooldown hasn't elapsed.\n */\n preflight(participant: string, now: number = Date.now()): void {\n if (!this.config || this.openedAt === undefined) return\n const remaining = this.config.cooldownMs - (now - this.openedAt)\n if (remaining > 0) {\n throw new CircuitOpenError(participant, remaining)\n }\n this.openedAt = undefined\n this.consecutiveFailures = 0\n }\n\n recordSuccess(): void {\n this.consecutiveFailures = 0\n this.openedAt = undefined\n }\n\n recordFailure(now: number = Date.now()): void {\n if (!this.config) return\n this.consecutiveFailures += 1\n if (this.consecutiveFailures >= this.config.failuresToOpen) {\n this.openedAt = now\n }\n }\n}\n\n/**\n * Build a per-attempt AbortSignal linked to the parent signal AND fired when\n * the deadline elapses. The returned `dispose()` MUST be called in a\n * `finally` (clears the timer, detaches the listener) so we don't leak.\n *\n * When the deadline fires, the signal's `reason` is a `DeadlineExceededError`\n * — callers can detect timeout-vs-cancel by reading `signal.reason` after\n * the underlying operation throws.\n */\nexport function makePerAttemptSignal(\n parentSignal: AbortSignal | undefined,\n deadlineMs: number | undefined,\n): {\n signal: AbortSignal\n dispose: () => void\n getDeadlineError(): DeadlineExceededError | undefined\n} {\n const controller = new AbortController()\n let deadlineError: DeadlineExceededError | undefined\n const cleanups: Array<() => void> = []\n\n if (parentSignal) {\n if (parentSignal.aborted) controller.abort(parentSignal.reason)\n else {\n const onAbort = () => controller.abort(parentSignal.reason)\n parentSignal.addEventListener('abort', onAbort, { once: true })\n cleanups.push(() => parentSignal.removeEventListener('abort', onAbort))\n }\n }\n if (deadlineMs !== undefined) {\n const ms = deadlineMs\n const timer = setTimeout(() => {\n deadlineError = new DeadlineExceededError(ms)\n controller.abort(deadlineError)\n }, ms)\n cleanups.push(() => clearTimeout(timer))\n }\n return {\n signal: controller.signal,\n dispose() {\n for (const c of cleanups) c()\n },\n getDeadlineError() {\n return deadlineError\n },\n }\n}\n\n/** Compute the delay before the next attempt. Default: 250ms exponential with jitter. */\nexport function computeBackoff(spec: RetryBackoff | undefined, attempt: number): number {\n if (spec === undefined) {\n const base = 250\n const jitter = Math.floor(Math.random() * base)\n return base * 2 ** (attempt - 1) + jitter\n }\n if (typeof spec === 'function') return Math.max(0, spec(attempt))\n return Math.max(0, spec)\n}\n\n/** Resolve after `ms` milliseconds — used for retry backoff in conversation call policy. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n *\n * Cross-gateway forwarding headers — the wire-level contract that makes\n * agent-to-agent communication composable across organizational boundaries.\n * Every header here is read on inbound and re-emitted on outbound, so a chain\n * `caller → A's gateway → A's runtime → B's gateway → B's runtime` ends with\n * B billing the original user, the depth counter monotonically incremented,\n * and the run/turn correlation IDs preserved end-to-end.\n *\n * The actual depth refusal (HTTP 413 at MAX_DEPTH) is enforced by\n * `agent-gateway`'s middleware; this module owns the names + the propagation\n * rules so both sides agree.\n *\n * Full protocol: `docs/agent-bus-protocol.md`.\n *\n * @stable\n */\n\n/** Standard names — lowercased so Headers maps interop on every runtime. */\nexport const FORWARD_HEADERS = {\n /** Forwarded original-user identity (`Bearer sk-tan-<user>`); downstream gateways bill against this. */\n authorization: 'x-tangle-forwarded-authorization',\n /** Monotonically incremented on every gateway hop. Refused at MAX_DEPTH. */\n depth: 'x-tangle-forwarded-depth',\n /** Top-level conversation run identifier, propagated through every nested call. */\n runId: 'x-tangle-runid',\n /** This call's turn within the run; deterministic + stable across retries. */\n turnId: 'x-tangle-turnid',\n /** When the call is *inside* another turn (recursion), the parent turn's id. */\n parentTurnId: 'x-tangle-parent-turnid',\n /** Logical conversation peer label at the sending side, for trace stitching. */\n speaker: 'x-tangle-speaker',\n} as const\n\nexport type ForwardHeaderName = (typeof FORWARD_HEADERS)[keyof typeof FORWARD_HEADERS]\n\n/** Hard cap on chained gateway hops; refused beyond this. Default keeps recursion bounded. */\nexport const DEFAULT_MAX_DEPTH = 4\n\n/**\n * Lowercase a header lookup so we read the same key regardless of source\n * casing (Hono, fetch's `Headers`, raw Node IncomingMessage, …).\n */\nfunction lc(name: string): string {\n return name.toLowerCase()\n}\n\n/**\n * Read the depth counter off an inbound request. Missing → 0 (caller is the\n * origin). Non-integer → throws — silent coercion would let a bad caller\n * reset depth and bypass the limit.\n */\nexport function readDepth(\n headers: Readonly<Record<string, string | string[] | undefined>>,\n): number {\n const raw = pickHeader(headers, FORWARD_HEADERS.depth)\n if (raw === undefined || raw === '') return 0\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 0) {\n throw new Error(\n `invalid ${FORWARD_HEADERS.depth} header value '${raw}' — must be a non-negative integer`,\n )\n }\n return n\n}\n\n/**\n * Refuse further forwarding when the inbound depth has reached the limit.\n * Callers (the gateway middleware) translate the boolean to an HTTP 413.\n */\nexport function isDepthExceeded(inboundDepth: number, max: number = DEFAULT_MAX_DEPTH): boolean {\n return inboundDepth >= max\n}\n\n/**\n * Build the headers to emit on an outbound participant call, given the\n * conversation's propagation context. Depth is incremented from the inbound\n * value; runId / turnId / speaker stamp the current hop; the user's\n * `Authorization` is preserved verbatim so the downstream gateway bills the\n * right wallet.\n */\nexport function buildForwardHeaders(input: {\n inboundDepth: number\n forwardedAuthorization?: string\n runId: string\n turnId: string\n parentTurnId?: string\n speaker: string\n}): Record<string, string> {\n const out: Record<string, string> = {\n [FORWARD_HEADERS.depth]: String(input.inboundDepth + 1),\n [FORWARD_HEADERS.runId]: input.runId,\n [FORWARD_HEADERS.turnId]: input.turnId,\n [FORWARD_HEADERS.speaker]: input.speaker,\n }\n if (input.forwardedAuthorization !== undefined) {\n out[FORWARD_HEADERS.authorization] = input.forwardedAuthorization\n }\n if (input.parentTurnId !== undefined) {\n out[FORWARD_HEADERS.parentTurnId] = input.parentTurnId\n }\n return out\n}\n\n/**\n * Header bag carried through `AgentBackendContext.propagatedHeaders` so\n * backends that opt in can merge them into their outbound HTTP requests.\n * Distinct from `buildForwardHeaders` so callers can attach extra\n * non-protocol headers (e.g. tracing) without colliding.\n */\nexport type PropagatedHeaders = Readonly<Record<string, string>>\n\nfunction pickHeader(\n headers: Readonly<Record<string, string | string[] | undefined>>,\n name: string,\n): string | undefined {\n const target = lc(name)\n for (const key of Object.keys(headers)) {\n if (lc(key) === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value[0]\n return value\n }\n }\n return undefined\n}\n","/**\n *\n * Deterministic turn identifier. Stable across retries of the same logical\n * turn so backends (and any caching gateway in between) can dedupe on it.\n * A retry triggered by a network blip or deadline timeout MUST produce the\n * same `turn_id`; only the underlying attempt count differs.\n *\n * Shape: `${runId}.t${index}.${speakerSlug}` — readable in logs, sortable by\n * turn index, attributable to a speaker. Slugify keeps the speaker portion\n * URL-safe so it can ride in HTTP headers without escaping.\n *\n * @stable\n */\n\nexport function turnId(runId: string, index: number, speaker: string): string {\n return `${runId}.t${index}.${slugifySpeaker(speaker)}`\n}\n\n/**\n * Reduce a speaker name to ASCII alphanumerics + dashes. Preserves enough\n * substance to read in a log line; collisions between speakers within a\n * single Conversation are prevented by `defineConversation`'s\n * unique-name check, so the slug only needs to be deterministic, not unique.\n */\nexport function slugifySpeaker(speaker: string): string {\n const cleaned = speaker\n .normalize('NFKD')\n .replace(/[^\\w-]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .toLowerCase()\n return cleaned || 'anon'\n}\n","/**\n *\n * Conversation orchestrator. Drives N participants in turn through their own\n * `AgentExecutionBackend`s, aggregating per-turn text + usage, enforcing\n * `maxTurns` / `maxCreditsCents` / `haltOn`, and emitting per-event stream\n * markers so callers can plumb the run through SSE without buffering.\n *\n * `runConversation` returns the full result; `runConversationStream` returns\n * an `AsyncIterable<ConversationStreamEvent>` for callers that want to\n * forward events as they arrive. Both share one driving loop.\n *\n * Distributed-systems primitives layered on top of the loop:\n * - **Participant sessions**: one backend session per participant is resumed\n * between turns; stateless backends receive one reconstructed transcript.\n * - **Idempotent turn ids** — `turnId(runId, index, speaker)` stays stable\n * across retries so caching gateways can dedupe.\n * - **Durable journal** — optional `ConversationJournal` persists every\n * committed turn; reusing a runId against the same journal resumes\n * transparently from the last committed turn.\n * - **Per-turn call policy** — deadline, retry-with-backoff, and a\n * per-participant circuit breaker. Retries replay the same logical turn\n * (same `turnId`); the retry loop lives inside the outer generator so\n * deltas yield naturally without cross-coroutine buffering.\n * - **Header propagation** — run/turn/depth headers (+ forwarded user\n * authorization) stamped onto every outbound backend call so downstream\n * gateways can bill the right user and enforce `X-Tangle-Forwarded-Depth`.\n *\n * Credit cap is enforced *between turns*, not mid-stream: a turn that\n * overshoots the cap completes, the cap then halts the conversation before\n * the next turn.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { BackendTransportError } from '../errors'\nimport { InMemoryRuntimeSessionStore, nowIso, startOrResumeRuntimeSession } from '../sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentTaskSpec,\n RuntimeSessionStore,\n} from '../types'\nimport {\n type BackendCallPolicy,\n CircuitBreakerState,\n computeBackoff,\n defaultIsRetryable,\n makePerAttemptSignal,\n sleep,\n} from './call-policy'\nimport { buildForwardHeaders, FORWARD_HEADERS } from './headers'\nimport { turnId as deriveTurnId, slugifySpeaker } from './turn-id'\nimport type {\n Conversation,\n ConversationParticipant,\n ConversationResult,\n ConversationStreamEvent,\n ConversationTurn,\n HaltContext,\n HaltReason,\n RunConversationOptions,\n TurnOrder,\n} from './types'\n\n/** Run a conversation to completion and return its terminal result. */\nexport async function runConversation(\n conversation: Conversation,\n options: RunConversationOptions,\n): Promise<ConversationResult> {\n let result: ConversationResult | undefined\n for await (const event of runConversationStream(conversation, options)) {\n if (options.onEvent) await options.onEvent(event)\n if (event.type === 'conversation_end') result = event.result\n }\n if (!result) {\n throw new BackendTransportError(\n 'conversation',\n 'conversation stream ended without a conversation_end event',\n )\n }\n return result\n}\n\n/** Streaming conversation orchestrator: drives N participants in turn through their own backends, enforcing `maxTurns` / `maxCreditsCents` / `haltOn`, yielding per-event stream markers. */\nexport async function* runConversationStream(\n conversation: Conversation,\n options: RunConversationOptions,\n): AsyncIterable<ConversationStreamEvent> {\n const runId = options.runId ?? `conv_${crypto.randomUUID()}`\n const inboundDepth = options.inboundDepth ?? 0\n const callerHeaders = options.propagatedHeaders ?? {}\n const forwardedAuthorization = callerHeaders[FORWARD_HEADERS.authorization]\n\n const breakers = new Map<string, CircuitBreakerState>()\n for (const participant of conversation.participants) {\n const cfg =\n participant.callPolicy?.circuitBreaker ??\n conversation.policy.defaultCallPolicy?.circuitBreaker\n breakers.set(participant.name, new CircuitBreakerState(cfg))\n }\n\n let transcript: ConversationTurn[] = []\n let spentCreditsCents = 0\n let startedAt = nowIso()\n let resumed = false\n const sessionStore = options.sessionStore ?? new InMemoryRuntimeSessionStore()\n\n if (options.journal) {\n const prior = await options.journal.loadRun(runId)\n if (prior) {\n if (prior.halted) {\n // Run already terminated — surface its final state without re-running.\n const replayResult: ConversationResult = {\n runId,\n transcript: prior.turns,\n turns: prior.turns.length,\n spentCreditsCents: prior.turns.reduce(\n (sum, t) => sum + centsFromUsd(t.usage?.costUsd ?? 0),\n 0,\n ),\n halted: prior.halted,\n durationMs: 0,\n startedAt: prior.startedAt,\n endedAt: prior.endedAt ?? prior.startedAt,\n }\n yield {\n type: 'conversation_resumed',\n runId,\n participants: conversation.participants.map((p) => p.name),\n transcript: prior.turns,\n timestamp: nowIso(),\n }\n yield { type: 'conversation_end', runId, result: replayResult, timestamp: nowIso() }\n return\n }\n transcript = [...prior.turns]\n spentCreditsCents = transcript.reduce(\n (sum, t) => sum + centsFromUsd(t.usage?.costUsd ?? 0),\n 0,\n )\n startedAt = prior.startedAt\n resumed = true\n } else {\n await options.journal.beginRun(runId, startedAt)\n }\n }\n const startedAtMs = Date.now()\n const participantSessions = sessionIdsFrom(transcript)\n\n if (resumed) {\n yield {\n type: 'conversation_resumed',\n runId,\n participants: conversation.participants.map((p) => p.name),\n // Snapshot the resumed transcript — the live `transcript` array gets\n // pushed to as the run continues, so handing the bare reference to a\n // subscriber would leak future writes into a past event.\n transcript: [...transcript],\n timestamp: nowIso(),\n }\n } else {\n yield {\n type: 'conversation_start',\n runId,\n participants: conversation.participants.map((p) => p.name),\n seed: options.seed,\n timestamp: startedAt,\n }\n }\n\n // When resumed, the next user input is the last persisted turn's text;\n // for a fresh run, it's the caller's seed.\n let currentInput =\n transcript.length === 0\n ? options.seed\n : (transcript[transcript.length - 1]?.text ?? options.seed)\n let halt: HaltReason | undefined\n\n const initialOffset = transcript.length\n for (let turnIndex = initialOffset; turnIndex < conversation.policy.maxTurns; turnIndex++) {\n if (options.signal?.aborted) {\n halt = { kind: 'abort' }\n break\n }\n if (\n conversation.policy.maxCreditsCents !== undefined &&\n spentCreditsCents >= conversation.policy.maxCreditsCents\n ) {\n halt = {\n kind: 'max_credits',\n spentCents: spentCreditsCents,\n capCents: conversation.policy.maxCreditsCents,\n }\n break\n }\n\n const speakerIdx = selectSpeaker(\n conversation.policy.turnOrder,\n conversation.participants.length,\n { transcript, turnIndex, spentCreditsCents },\n )\n const speaker = conversation.participants[speakerIdx]\n if (!speaker) {\n throw new BackendTransportError(\n 'conversation',\n `turnOrder selector returned out-of-range index ${speakerIdx} for ${conversation.participants.length} participants`,\n )\n }\n\n const tid = deriveTurnId(runId, turnIndex, speaker.name)\n const callPolicy: BackendCallPolicy | undefined =\n speaker.callPolicy ?? conversation.policy.defaultCallPolicy\n const breaker = breakers.get(speaker.name)\n if (!breaker) {\n throw new BackendTransportError(\n 'conversation',\n `internal: no circuit-breaker state registered for participant '${speaker.name}'`,\n )\n }\n const isRetryable = callPolicy?.isRetryable ?? defaultIsRetryable\n const totalAttempts = 1 + (callPolicy?.maxRetries ?? 0)\n\n yield {\n type: 'turn_start',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n attempt: 1,\n timestamp: nowIso(),\n }\n\n let aggregator: TurnAggregator | undefined\n let attemptCount = 0\n let lastError: unknown\n let breakerOpenFailure: unknown\n\n for (let attempt = 1; attempt <= totalAttempts; attempt++) {\n attemptCount = attempt\n try {\n breaker.preflight(speaker.name)\n } catch (err) {\n // Breaker open — no point retrying; halt the conversation with this\n // participant's error rather than busy-looping until exhaustion.\n breakerOpenFailure = err\n break\n }\n\n if (attempt > 1) {\n yield {\n type: 'turn_retry',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n attempt,\n reason: lastError instanceof Error ? lastError.message : String(lastError),\n timestamp: nowIso(),\n }\n }\n\n const perAttempt = makePerAttemptSignal(options.signal, callPolicy?.perAttemptDeadlineMs)\n const localAgg = new TurnAggregator({\n index: turnIndex,\n speaker: speaker.name,\n startedAt: nowIso(),\n })\n\n try {\n for await (const delta of driveSingleAttempt({\n speaker,\n participants: conversation.participants,\n seed: options.seed,\n input: currentInput,\n turnIndex,\n runId,\n turnId: tid,\n transcript,\n participantSessions,\n sessionStore,\n signal: perAttempt.signal,\n aggregator: localAgg,\n propagatedHeaders: buildForwardHeaders({\n inboundDepth,\n // When the participant elects to pay for its own outbound calls,\n // drop the forwarded user identity so the downstream gateway\n // bills the participant's own credentials instead. The backend\n // brings its own credentials through its caller-owned backend or\n // profile-bound Runtime executor;\n // omitting the forwarded header is what flips the billing target.\n forwardedAuthorization: resolveAuthForwarding(speaker, {\n transcript,\n turnIndex,\n spentCreditsCents,\n })\n ? forwardedAuthorization\n : undefined,\n runId,\n turnId: tid,\n parentTurnId: options.parentTurnId,\n speaker: speaker.name,\n }),\n })) {\n yield {\n type: 'turn_text_delta',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n text: delta.text,\n timestamp: delta.timestamp,\n }\n }\n perAttempt.dispose()\n breaker.recordSuccess()\n aggregator = localAgg\n break\n } catch (err) {\n perAttempt.dispose()\n breaker.recordFailure()\n // Surface the deadline error explicitly when timeout was the cause —\n // otherwise the upstream may throw a generic AbortError that loses\n // diagnostic info.\n lastError = perAttempt.getDeadlineError() ?? err\n if (attempt >= totalAttempts || !isRetryable(lastError)) {\n break\n }\n await sleep(computeBackoff(callPolicy?.retryBackoffMs, attempt))\n }\n }\n\n if (!aggregator) {\n const failure = breakerOpenFailure ?? lastError\n const message = failure instanceof Error ? failure.message : String(failure)\n halt = { kind: 'participant_error', participant: speaker.name, message }\n break\n }\n\n const turn = aggregator.toTurn({ turnId: tid, attempts: attemptCount })\n if (turn.sessionId) {\n bindParticipantSession(participantSessions, turn.speaker, turn.sessionId)\n }\n transcript.push(turn)\n spentCreditsCents += centsFromUsd(turn.usage?.costUsd ?? 0)\n if (options.journal) {\n await options.journal.appendTurn(runId, turn)\n }\n\n yield { type: 'turn_end', runId, turn, timestamp: nowIso() }\n\n if (conversation.policy.haltOn) {\n const haltCtx: HaltContext = {\n transcript,\n lastTurn: turn,\n turnIndex,\n spentCreditsCents,\n }\n const decision = await conversation.policy.haltOn(haltCtx)\n if (decision === true) {\n halt = { kind: 'predicate', reason: 'predicate_true' }\n break\n }\n if (typeof decision === 'object' && decision !== null && decision.halted) {\n halt = { kind: 'predicate', reason: decision.reason }\n break\n }\n }\n\n currentInput = turn.text\n }\n\n if (!halt) halt = { kind: 'max_turns', turns: transcript.length }\n\n const endedAt = nowIso()\n const result: ConversationResult = {\n runId,\n transcript,\n turns: transcript.length,\n spentCreditsCents,\n halted: halt,\n durationMs: Date.now() - startedAtMs,\n startedAt,\n endedAt,\n }\n if (options.journal) {\n await options.journal.recordHalt(runId, halt, endedAt)\n }\n\n yield { type: 'conversation_end', runId, result, timestamp: endedAt }\n}\n\n// ── Single attempt ───────────────────────────────────────────────────────\n\ninterface SingleAttemptArgs {\n speaker: ConversationParticipant\n participants: readonly ConversationParticipant[]\n seed: string\n input: string\n turnIndex: number\n runId: string\n turnId: string\n transcript: readonly ConversationTurn[]\n participantSessions: Map<string, string>\n sessionStore: RuntimeSessionStore\n signal: AbortSignal\n aggregator: TurnAggregator\n propagatedHeaders: Record<string, string>\n}\n\nasync function* driveSingleAttempt(\n args: SingleAttemptArgs,\n): AsyncGenerator<{ text: string; timestamp?: string }> {\n const task: AgentTaskSpec = {\n id: args.turnId,\n intent: args.input,\n metadata: {\n runId: args.runId,\n turnId: args.turnId,\n turnIndex: args.turnIndex,\n speaker: args.speaker.name,\n participants: args.participants.map((p) => p.name),\n },\n }\n const knowledge = passingReadiness(task.id)\n\n const startCtx: Omit<AgentBackendContext, 'session'> = {\n task,\n knowledge,\n signal: args.signal,\n runId: args.runId,\n turnId: args.turnId,\n propagatedHeaders: args.propagatedHeaders,\n }\n const previousSessionId = args.participantSessions.get(args.speaker.name)\n const opened = await startOrResumeRuntimeSession({\n backend: args.speaker.backend,\n input: () => fullConversationInput(task, args.speaker.name, args.seed, args.transcript),\n continuationInput: () => continuedConversationInput(task, args.speaker.name, args.transcript),\n context: startCtx,\n store: args.sessionStore,\n sessionId:\n previousSessionId ?? participantSessionId(args.runId, args.speaker.name, args.participants),\n resume: previousSessionId !== undefined && args.speaker.backend.resume !== undefined,\n validateSession: (session) =>\n assertParticipantSessionAvailable(args.participantSessions, args.speaker.name, session.id),\n })\n const session = opened.session\n args.aggregator.recordSession(session.id)\n\n const streamCtx: AgentBackendContext = {\n task,\n knowledge,\n session,\n signal: args.signal,\n runId: args.runId,\n turnId: args.turnId,\n propagatedHeaders: args.propagatedHeaders,\n }\n\n for await (const event of args.speaker.backend.stream(opened.input, streamCtx)) {\n if (args.signal.aborted) {\n // Surface the abort so the outer retry/halt logic can react. The signal\n // either fires because of caller-cancel (propagate as-is) or because of\n // the per-attempt deadline timer (signal.reason is DeadlineExceededError).\n const reason = args.signal.reason\n throw reason instanceof Error ? reason : new Error('aborted')\n }\n if (event.type === 'text_delta') {\n args.aggregator.appendText(event.text)\n yield { text: event.text, timestamp: event.timestamp }\n } else if (event.type === 'llm_call') {\n args.aggregator.recordUsage(event)\n } else if (event.type === 'backend_error') {\n throw new BackendTransportError(args.speaker.backend.kind, event.message, {\n status: event.error?.status,\n body: event.error?.body,\n })\n } else if (event.type === 'final') {\n if (event.status !== 'completed') {\n throw new BackendTransportError(\n args.speaker.backend.kind,\n event.error?.message ?? event.reason,\n { status: event.error?.status, body: event.error?.body },\n )\n }\n args.aggregator.adoptFinalText(event.text)\n }\n }\n\n if (!args.aggregator.hasText()) {\n throw new BackendTransportError(\n args.speaker.backend.kind,\n `backend '${args.speaker.backend.kind}' completed without text`,\n )\n }\n}\n\nclass TurnAggregator {\n private text = ''\n private adoptedFinal = false\n private sessionId: string | undefined\n private usage:\n | {\n tokensIn?: number\n tokensOut?: number\n costUsd?: number\n latencyMs?: number\n model?: string\n }\n | undefined\n\n constructor(private readonly base: { index: number; speaker: string; startedAt: string }) {}\n\n appendText(text: string): void {\n if (this.adoptedFinal) return\n this.text += text\n }\n\n /**\n * Use the backend's `final.text` only when no streamed deltas were observed.\n * Some backends emit deltas AND a final summary; treating both as content\n * would double-count.\n */\n adoptFinalText(text: string | undefined): void {\n if (!text) return\n if (this.text.length > 0) return\n this.text = text\n this.adoptedFinal = true\n }\n\n hasText(): boolean {\n return this.text.trim().length > 0\n }\n\n recordSession(sessionId: string): void {\n this.sessionId = sessionId\n }\n\n recordUsage(event: {\n model?: string\n tokensIn?: number\n tokensOut?: number\n costUsd?: number\n latencyMs?: number\n }): void {\n const u = this.usage ?? {}\n if (event.tokensIn !== undefined) u.tokensIn = (u.tokensIn ?? 0) + event.tokensIn\n if (event.tokensOut !== undefined) u.tokensOut = (u.tokensOut ?? 0) + event.tokensOut\n if (event.costUsd !== undefined) u.costUsd = (u.costUsd ?? 0) + event.costUsd\n if (event.latencyMs !== undefined) u.latencyMs = event.latencyMs\n if (event.model !== undefined) u.model = event.model\n this.usage = u\n }\n\n toTurn(meta: { turnId: string; attempts: number }): ConversationTurn {\n return {\n index: this.base.index,\n speaker: this.base.speaker,\n turnId: meta.turnId,\n ...(this.sessionId ? { sessionId: this.sessionId } : {}),\n text: this.text.trim(),\n usage: this.usage,\n attempts: meta.attempts,\n startedAt: this.base.startedAt,\n endedAt: nowIso(),\n }\n }\n}\n\n/**\n * Build the participant's POV of the transcript so an OpenAI-compatible\n * backend sees its own turns as `assistant` and everyone else's as `user`,\n * with explicit speaker tags so 3+ party conversations stay disambiguated.\n */\nfunction buildMessagesFor(\n speakerName: string,\n seed: string,\n transcript: readonly ConversationTurn[],\n): Array<{ role: string; content: string }> {\n const messages: Array<{ role: string; content: string }> = seed\n ? [{ role: 'user', content: seed }]\n : []\n for (const turn of transcript) {\n if (turn.speaker === speakerName) {\n messages.push({ role: 'assistant', content: turn.text })\n } else {\n messages.push({ role: 'user', content: `[${turn.speaker}] ${turn.text}` })\n }\n }\n return messages\n}\n\nfunction fullConversationInput(\n task: AgentTaskSpec,\n speakerName: string,\n seed: string,\n transcript: readonly ConversationTurn[],\n): AgentBackendInput {\n const transcriptText = transcript.map((turn) => `[${turn.speaker}] ${turn.text}`)\n return {\n task,\n message: [seed, ...transcriptText].filter((part) => part.length > 0).join('\\n\\n'),\n messages: buildMessagesFor(speakerName, seed, transcript),\n }\n}\n\nfunction continuedConversationInput(\n task: AgentTaskSpec,\n speakerName: string,\n transcript: readonly ConversationTurn[],\n): AgentBackendInput {\n let lastOwnTurn = -1\n for (let index = transcript.length - 1; index >= 0; index -= 1) {\n if (transcript[index]?.speaker === speakerName) {\n lastOwnTurn = index\n break\n }\n }\n const unseen = transcript.slice(lastOwnTurn + 1)\n const message =\n unseen.length > 0\n ? unseen.map((turn) => `[${turn.speaker}] ${turn.text}`).join('\\n\\n')\n : 'Continue.'\n return { task, message, messages: [{ role: 'user', content: message }] }\n}\n\nfunction sessionIdsFrom(transcript: readonly ConversationTurn[]): Map<string, string> {\n const sessions = new Map<string, string>()\n for (const turn of transcript) {\n if (turn.sessionId) bindParticipantSession(sessions, turn.speaker, turn.sessionId)\n }\n return sessions\n}\n\nfunction bindParticipantSession(\n sessions: Map<string, string>,\n speakerName: string,\n sessionId: string,\n): void {\n assertParticipantSessionAvailable(sessions, speakerName, sessionId)\n sessions.set(speakerName, sessionId)\n}\n\nfunction assertParticipantSessionAvailable(\n sessions: ReadonlyMap<string, string>,\n speakerName: string,\n sessionId: string,\n): void {\n for (const [boundSpeaker, boundSessionId] of sessions) {\n if (boundSpeaker !== speakerName && boundSessionId === sessionId) {\n throw new BackendTransportError(\n 'conversation',\n `session '${sessionId}' is already bound to participant '${boundSpeaker}'`,\n )\n }\n }\n}\n\nfunction participantSessionId(\n runId: string,\n speakerName: string,\n participants: readonly ConversationParticipant[],\n): string {\n const participantIndex = participants.findIndex((participant) => participant.name === speakerName)\n if (participantIndex < 0) {\n throw new BackendTransportError(\n 'conversation',\n `participant '${speakerName}' is not registered in this conversation`,\n )\n }\n return `${runId}.participant.${participantIndex}.${slugifySpeaker(speakerName)}`\n}\n\n/**\n * True when this participant should forward the caller's\n * `X-Tangle-Forwarded-Authorization` on outbound calls (the \"pass-through\"\n * commercial mode). False when it elects to pay for its own outbound calls\n * (the \"reseller\" / \"bundle\" mode). See ConversationParticipant.authSource.\n */\nfunction resolveAuthForwarding(\n participant: ConversationParticipant,\n state: { transcript: readonly ConversationTurn[]; turnIndex: number; spentCreditsCents: number },\n): boolean {\n const decision =\n typeof participant.authSource === 'function'\n ? participant.authSource(state)\n : (participant.authSource ?? 'forward-user')\n return decision === 'forward-user'\n}\n\nfunction selectSpeaker(\n order: TurnOrder | undefined,\n participantCount: number,\n state: { transcript: readonly ConversationTurn[]; turnIndex: number; spentCreditsCents: number },\n): number {\n const resolved = order ?? (participantCount === 2 ? 'alternate' : 'round-robin')\n if (resolved === 'alternate' || resolved === 'round-robin') {\n return state.turnIndex % participantCount\n }\n if (typeof resolved === 'function') {\n const idx = resolved(state)\n if (!Number.isInteger(idx) || idx < 0 || idx >= participantCount) {\n throw new BackendTransportError(\n 'conversation',\n `turnOrder function returned invalid index ${String(idx)} for ${participantCount} participants`,\n )\n }\n return idx\n }\n throw new BackendTransportError('conversation', `unknown turnOrder: ${String(resolved)}`)\n}\n\nfunction centsFromUsd(usd: number): number {\n return Math.round(usd * 100)\n}\n\n/**\n * Synthesize a knowledge-readiness report that *passes* every gate, used to\n * satisfy `AgentBackendContext.knowledge` per turn. Conversations don't apply\n * task-level readiness gating per-turn — that's a `runAgentTask` concern.\n */\nfunction passingReadiness(taskId: string): KnowledgeReadinessReport {\n return {\n taskId,\n readinessScore: 1,\n blockingMissingRequirements: [],\n nonBlockingGaps: [],\n recommendedAction: 'run_agent',\n bundle: {\n taskId,\n requirements: [],\n evidenceIds: [],\n claimIds: [],\n wikiPageIds: [],\n userAnswers: {},\n missing: [],\n readinessScore: 1,\n },\n severity: 'info',\n reason: 'conversation-mode: readiness gating not applied per-turn',\n }\n}\n","/**\n *\n * Wrap a `Conversation` so it satisfies `AgentExecutionBackend`. The result is\n * an addressable \"single agent\" whose internal behavior is an N-party\n * orchestrated conversation — the recursion primitive that lets a swarm be a\n * participant inside another swarm, or be published behind a single\n * agent-gateway endpoint.\n *\n * Stream events from inner participants are NOT forwarded verbatim. Outer\n * callers see one `text_delta` per inner turn (the turn's full text), tagged\n * with `[speaker] ` prefix so the outer transcript stays attributable. The\n * conversation's `conversation_end` halt reason rides on a `final` event.\n *\n * @stable\n */\n\nimport { providerMessageText } from '../runtime/turn-input'\nimport { newRuntimeSession, nowIso } from '../sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentExecutionBackend,\n RuntimeSession,\n RuntimeStreamEvent,\n} from '../types'\nimport { FORWARD_HEADERS, readDepth } from './headers'\nimport { runConversationStream } from './run-conversation'\nimport type { Conversation, HaltReason } from './types'\n\n/** Adapt a multi-participant conversation into the standard execution backend contract. */\nexport function createConversationBackend(options: {\n conversation: Conversation\n /** Optional backend kind label. Defaults to `'conversation'`. */\n kind?: string\n}): AgentExecutionBackend {\n const kind = options.kind ?? 'conversation'\n\n return {\n kind,\n start(_input, context): RuntimeSession {\n return newRuntimeSession(kind, context.requestedSessionId, {\n participants: options.conversation.participants.map((p) => p.name),\n })\n },\n async *stream(\n input: AgentBackendInput,\n context: AgentBackendContext,\n ): AsyncIterable<RuntimeStreamEvent> {\n const seed =\n input.message ??\n input.messages?.at(-1)?.content ??\n providerMessageText(input.providerOptions) ??\n context.task.intent\n const task = context.task\n const session = context.session\n\n yield { type: 'backend_start', task, session, backend: kind, timestamp: nowIso() }\n\n let finalText = ''\n let totalCostUsd = 0\n let totalTokensIn = 0\n let totalTokensOut = 0\n\n // Recursion: forward this call's propagation context into the nested\n // conversation. The nested run INHERITS the parent's runId (protocol\n // invariant: runId is immutable across nesting), continues the depth\n // counter from the headers, and stamps the enclosing turn as the\n // parentTurnId so trace stitching reaches across nesting levels.\n const inboundDepth = parseInboundDepth(context.propagatedHeaders)\n for await (const event of runConversationStream(options.conversation, {\n seed,\n signal: context.signal,\n runId: context.runId,\n propagatedHeaders: context.propagatedHeaders,\n inboundDepth,\n parentTurnId: context.turnId,\n })) {\n if (event.type === 'turn_end') {\n const tagged = `[${event.turn.speaker}] ${event.turn.text}\\n`\n finalText += tagged\n yield { type: 'text_delta', task, session, text: tagged, timestamp: event.timestamp }\n if (event.turn.usage) {\n const u = event.turn.usage\n if (u.costUsd !== undefined) totalCostUsd += u.costUsd\n if (u.tokensIn !== undefined) totalTokensIn += u.tokensIn\n if (u.tokensOut !== undefined) totalTokensOut += u.tokensOut\n yield {\n type: 'llm_call',\n task,\n session,\n model: u.model ?? `${kind}/${event.turn.speaker}`,\n tokensIn: u.tokensIn,\n tokensOut: u.tokensOut,\n costUsd: u.costUsd,\n latencyMs: u.latencyMs,\n timestamp: event.timestamp,\n }\n }\n } else if (event.type === 'conversation_end') {\n const halt = event.result.halted\n yield {\n type: 'final',\n task,\n session,\n status: halt.kind === 'participant_error' ? 'failed' : 'completed',\n reason: describeHalt(halt),\n text: finalText.trim(),\n metadata: {\n conversationRunId: event.result.runId,\n turns: event.result.turns,\n spentCreditsCents: event.result.spentCreditsCents,\n halted: halt,\n durationMs: event.result.durationMs,\n tokensIn: totalTokensIn,\n tokensOut: totalTokensOut,\n costUsd: totalCostUsd,\n },\n timestamp: event.timestamp,\n }\n }\n }\n\n yield { type: 'backend_end', task, session, backend: kind, timestamp: nowIso() }\n },\n }\n}\n\nfunction parseInboundDepth(headers: Readonly<Record<string, string>> | undefined): number {\n if (!headers) return 0\n // Accept either the canonical header key OR a lookup via the keyed name.\n const raw = headers[FORWARD_HEADERS.depth]\n if (raw === undefined) return 0\n try {\n return readDepth({ [FORWARD_HEADERS.depth]: raw })\n } catch {\n return 0\n }\n}\n\nfunction describeHalt(halt: HaltReason): string {\n switch (halt.kind) {\n case 'max_turns':\n return `max_turns (${halt.turns})`\n case 'max_credits':\n return `max_credits (${halt.spentCents}/${halt.capCents}¢)`\n case 'predicate':\n return `predicate: ${halt.reason}`\n case 'abort':\n return 'abort'\n case 'participant_error':\n return `participant_error[${halt.participant}]: ${halt.message}`\n }\n}\n","/**\n *\n * Declarative constructor for a multi-agent `Conversation`. Validates inputs\n * fail-loud at definition time (duplicate participant names, alternate order\n * with ≠2 participants, non-positive `maxTurns`) so misconfiguration is caught\n * before `runConversation` is called and not buried inside a streaming run.\n *\n * @stable\n */\n\nimport { ValidationError } from '../errors'\nimport type { Conversation, ConversationParticipant, ConversationPolicy, TurnOrder } from './types'\n\n/** Validate and define a conversation before execution. */\nexport function defineConversation(input: {\n participants: ConversationParticipant[]\n policy: ConversationPolicy\n}): Conversation {\n if (input.participants.length < 2) {\n throw new ValidationError(\n `Conversation requires at least 2 participants; received ${input.participants.length}.`,\n )\n }\n\n const seen = new Set<string>()\n for (const p of input.participants) {\n if (!p.name || p.name.trim() === '') {\n throw new ValidationError('Conversation participant.name must be a non-empty string.')\n }\n if (seen.has(p.name)) {\n throw new ValidationError(\n `Conversation participant names must be unique within a Conversation; '${p.name}' appears more than once.`,\n )\n }\n seen.add(p.name)\n if (!p.backend || typeof p.backend.stream !== 'function') {\n throw new ValidationError(\n `Conversation participant '${p.name}' is missing a backend with a stream() method.`,\n )\n }\n }\n\n const policy = normalizePolicy(input.policy, input.participants.length)\n\n return {\n participants: input.participants,\n policy,\n }\n}\n\nfunction normalizePolicy(policy: ConversationPolicy, participantCount: number): ConversationPolicy {\n if (!Number.isInteger(policy.maxTurns) || policy.maxTurns < 1) {\n throw new ValidationError(\n `ConversationPolicy.maxTurns must be a positive integer; received ${String(policy.maxTurns)}.`,\n )\n }\n if (\n policy.maxCreditsCents !== undefined &&\n (!Number.isFinite(policy.maxCreditsCents) || policy.maxCreditsCents < 0)\n ) {\n throw new ValidationError(\n `ConversationPolicy.maxCreditsCents must be a non-negative finite number when set; received ${String(\n policy.maxCreditsCents,\n )}.`,\n )\n }\n const turnOrder = policy.turnOrder ?? (participantCount === 2 ? 'alternate' : 'round-robin')\n if (turnOrder === 'alternate' && participantCount !== 2) {\n throw new ValidationError(\n `ConversationPolicy.turnOrder 'alternate' requires exactly 2 participants; received ${participantCount}. Use 'round-robin' or a custom selector for N-party conversations.`,\n )\n }\n return { ...policy, turnOrder: turnOrder as TurnOrder }\n}\n","/**\n *\n * Durable conversation transcript — survives a driver process crash mid-run.\n * The runner journals every committed turn before yielding `turn_end`, so a\n * resumed run replays the same `runId` against the same journal and picks up\n * from the first un-recorded turn. Combined with the deterministic\n * `turnId(runId, index, speaker)`, a retried turn collides with the prior\n * attempt's id and any caching gateway can dedupe.\n *\n * The interface is small enough that a Cloudflare D1 / R2 / postgres adapter\n * is ~30 lines. The in-memory adapter is the default for tests and scratch.\n * The file adapter (JSONL on disk) is the default-durable choice when no\n * upstream store is wired.\n *\n * @stable\n */\n\nimport { prepareJsonlAppend, readCommittedJsonLines, writeAllBytes } from '../durable/jsonl-file'\nimport type { ConversationTurn, HaltReason } from './types'\n\nexport interface ConversationJournalEntry {\n runId: string\n startedAt: string\n /** Set when the run reaches a terminal state. */\n halted?: HaltReason\n endedAt?: string\n turns: ConversationTurn[]\n}\n\nexport interface ConversationJournal {\n /**\n * Load any prior state for `runId`. Returns `undefined` for a fresh run.\n * Implementations MUST NOT mutate the returned object — the runner clones\n * before continuing — but the runtime treats absence and emptiness\n * identically, so a journal with zero turns is equivalent to \"fresh.\"\n */\n loadRun(runId: string): Promise<ConversationJournalEntry | undefined>\n\n /**\n * Initialise journal state for a fresh run. Called once per run, before any\n * `appendTurn`. Idempotent: calling with an existing runId is a no-op if\n * the entry already exists with the same `startedAt`.\n */\n beginRun(runId: string, startedAt: string): Promise<void>\n\n /**\n * Append a committed turn. The runner only calls this AFTER the turn's\n * backend stream completed and the credit total has been updated, so an\n * appended turn is observed-committed and never speculative.\n */\n appendTurn(runId: string, turn: ConversationTurn): Promise<void>\n\n /**\n * Record the run's terminal halt reason + end time. Once called, the run\n * is observed-final; subsequent `loadRun` returns the same halt.\n */\n recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>\n}\n\n/** In-memory `ConversationJournal` — suitable for testing and single-process runs. */\nexport class InMemoryConversationJournal implements ConversationJournal {\n private readonly entries = new Map<string, ConversationJournalEntry>()\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n const entry = this.entries.get(runId)\n if (!entry) return undefined\n // Defensive copy — callers MUST NOT mutate journal-owned arrays.\n return {\n runId: entry.runId,\n startedAt: entry.startedAt,\n halted: entry.halted,\n endedAt: entry.endedAt,\n turns: [...entry.turns],\n }\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = this.entries.get(runId)\n if (existing) {\n if (existing.startedAt !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists with startedAt=${existing.startedAt}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n this.entries.set(runId, { runId, startedAt, turns: [] })\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n const entry = this.entries.get(runId)\n if (!entry) {\n throw new Error(\n `appendTurn called for unknown runId '${runId}'; call beginRun first or use the runner which handles it`,\n )\n }\n if (entry.halted) {\n throw new Error(\n `cannot append turn to halted run '${runId}' (halt reason: ${JSON.stringify(entry.halted)})`,\n )\n }\n entry.turns.push(turn)\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n const entry = this.entries.get(runId)\n if (!entry) {\n throw new Error(`recordHalt called for unknown runId '${runId}'`)\n }\n entry.halted = halt\n entry.endedAt = endedAt\n }\n}\n\n/**\n * JSONL on disk. One line per record; first line is the `begin`, subsequent\n * lines are `turn` records, terminal line is `halt`. Replays the whole file\n * on `loadRun` — cheap for the conversation sizes this is designed for\n * (thousands of turns, not millions). For huge runs, plug in a real DB\n * adapter; the interface is small.\n *\n * Reads and appends over the shared append-only spine (`durable/jsonl-file`): each\n * `appendTurn` / `recordHalt` finishes a short write and calls `fsync`, so a process\n * crash between writes never loses an acknowledged turn, and a crash DURING one leaves\n * an uncommitted final line that the next read skips and the next append truncates.\n */\nexport class FileConversationJournal implements ConversationJournal {\n constructor(private readonly path: string) {}\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n let entry: ConversationJournalEntry | undefined\n for await (const record of readCommittedJsonLines<JournalRecord>(this.path, {\n allowMissing: true,\n })) {\n if (record.runId !== runId) continue\n if (record.kind === 'begin') {\n entry = { runId, startedAt: record.startedAt, turns: [] }\n } else if (record.kind === 'turn') {\n if (!entry) {\n throw new Error(\n `journal corrupted: turn record for runId '${runId}' precedes its begin record`,\n )\n }\n entry.turns.push(record.turn)\n } else if (record.kind === 'halt') {\n if (!entry) {\n throw new Error(\n `journal corrupted: halt record for runId '${runId}' precedes its begin record`,\n )\n }\n entry.halted = record.halted\n entry.endedAt = record.endedAt\n }\n }\n return entry\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = await this.loadRun(runId)\n if (existing) {\n if (existing.startedAt !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists in ${this.path} with startedAt=${existing.startedAt}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n await this.appendRecord({ kind: 'begin', runId, startedAt })\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n await this.appendRecord({ kind: 'turn', runId, turn })\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n await this.appendRecord({ kind: 'halt', runId, halted: halt, endedAt })\n }\n\n private async appendRecord(record: JournalRecord): Promise<void> {\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n await fs.mkdir(path.dirname(this.path), { recursive: true })\n const needsSeparator = await prepareJsonlAppend(this.path)\n const fh = await fs.open(this.path, 'a')\n try {\n await writeAllBytes(fh, `${needsSeparator ? '\\n' : ''}${JSON.stringify(record)}\\n`)\n await fh.sync()\n } finally {\n await fh.close()\n }\n }\n}\n\ntype JournalRecord =\n | { kind: 'begin'; runId: string; startedAt: string }\n | { kind: 'turn'; runId: string; turn: ConversationTurn }\n | { kind: 'halt'; runId: string; halted: HaltReason; endedAt: string }\n","/**\n *\n * Durable conversation journal backed by any SQL store. Adapter-agnostic by\n * design: callers wire a `SqlAdapter` against their driver of choice (D1,\n * postgres, sqlite, libSQL…) and the same journal implementation persists\n * conversation runs durably across process restarts. The schema is two\n * tables — runs (latest state) + events (append-only log) — so a partial\n * crash in the middle of a turn leaves an unambiguous \"last committed turn\"\n * to resume from.\n *\n * Why not bake in a specific driver? agent-runtime ships against multiple\n * runtimes (Cloudflare Workers, Node, Bun, Deno) and consumers' fleets have\n * already standardized on one of D1 / postgres / sqlite / libSQL. Adapter\n * indirection costs ~5 lines per driver in the consumer's code and keeps the\n * SDK free of native deps.\n *\n * @example D1 (Cloudflare Workers)\n * import { SqlConversationJournal, d1ToSqlAdapter } from '@tangle-network/agent-runtime'\n * const journal = new SqlConversationJournal(d1ToSqlAdapter(env.DB))\n * await journal.migrate() // once at deploy\n * await runConversation(conv, { seed, journal, runId: 'run_abc' })\n *\n * @example node-postgres\n * import { Pool } from 'pg'\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL })\n * const pg: SqlAdapter = {\n * exec: async (sql, params = []) => {\n * const r = await pool.query(sql, params as never)\n * return { rowsAffected: r.rowCount ?? 0 }\n * },\n * query: async (sql, params = []) => (await pool.query(sql, params as never)).rows,\n * }\n * const journal = new SqlConversationJournal(pg)\n * await journal.migrate()\n *\n * @stable\n */\n\nimport type { ConversationJournal, ConversationJournalEntry } from './journal'\nimport type { ConversationTurn, HaltReason } from './types'\n\n/**\n * Minimal SQL driver shape. Implementations forward to whichever client the\n * deployment already uses; agent-runtime takes no opinion on which.\n *\n * Parameter placeholders MUST be `?` (positional). All adapters listed in the\n * file header accept this convention.\n */\nexport interface SqlAdapter {\n /** Execute a write statement (INSERT/UPDATE/DELETE/DDL). */\n exec(sql: string, params?: readonly unknown[]): Promise<{ rowsAffected: number }>\n /** Execute a read statement (SELECT). Returns rows as plain objects. */\n query<TRow = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<TRow[]>\n}\n\n/**\n * Adapt a Cloudflare D1 binding to the SqlAdapter shape. Lives here so D1\n * consumers don't have to write the wrapper themselves; the runtime never\n * imports `@cloudflare/workers-types` directly (peer-style typing).\n */\nexport function d1ToSqlAdapter(db: D1DatabaseLike): SqlAdapter {\n return {\n async exec(sql, params = []) {\n const stmt = db.prepare(sql)\n const bound = params.length > 0 ? stmt.bind(...params) : stmt\n const result = await bound.run()\n const meta = (result as { meta?: { rows_written?: number; changes?: number } }).meta\n return { rowsAffected: meta?.rows_written ?? meta?.changes ?? 0 }\n },\n async query<TRow>(sql: string, params: readonly unknown[] = []): Promise<TRow[]> {\n const stmt = db.prepare(sql)\n const bound = params.length > 0 ? stmt.bind(...params) : stmt\n const result = await bound.all<TRow>()\n return result.results ?? []\n },\n }\n}\n\n/**\n * Structural type matching the surface of `D1Database` we depend on, so the\n * SDK never imports `@cloudflare/workers-types`. Consumers pass their real\n * `D1Database` from `env.DB` and TS structural compatibility lines it up.\n */\nexport interface D1DatabaseLike {\n prepare(sql: string): D1StmtLike\n}\nexport interface D1StmtLike {\n bind(...params: unknown[]): D1StmtLike\n run(): Promise<unknown>\n all<TRow = unknown>(): Promise<{ results?: TRow[] }>\n}\n\nconst RUNS_TABLE_DDL = (table: string) => `\n CREATE TABLE IF NOT EXISTS ${table}_runs (\n run_id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n halted_kind TEXT,\n halted_payload TEXT,\n ended_at TEXT\n )\n`\nconst TURNS_TABLE_DDL = (table: string) => `\n CREATE TABLE IF NOT EXISTS ${table}_turns (\n run_id TEXT NOT NULL,\n turn_index INTEGER NOT NULL,\n payload TEXT NOT NULL,\n PRIMARY KEY (run_id, turn_index)\n )\n`\nconst TURNS_INDEX_DDL = (table: string) => `\n CREATE INDEX IF NOT EXISTS idx_${table}_turns_run ON ${table}_turns (run_id, turn_index)\n`\n\n/**\n * SQL-backed ConversationJournal. Two tables — runs (one row per runId, holds\n * start/halt timestamps + halt reason) and turns (one row per committed turn,\n * payload is the ConversationTurn JSON). Replays the turns table on\n * `loadRun` and writes append-only per `appendTurn`.\n */\nexport class SqlConversationJournal implements ConversationJournal {\n /**\n * @param db SQL adapter (D1, postgres, sqlite, libSQL — all work)\n * @param table Table-name prefix; the journal creates `${table}_runs` and\n * `${table}_turns`. Lets multiple journals share a database\n * without colliding (e.g. one per product surface).\n */\n constructor(\n private readonly db: SqlAdapter,\n private readonly table: string = 'agent_runtime_journal',\n ) {}\n\n /**\n * Create the journal's tables if absent. Idempotent. Call once at deploy\n * (or at app boot) — running on every request is harmless but adds latency.\n */\n async migrate(): Promise<void> {\n await this.db.exec(RUNS_TABLE_DDL(this.table))\n await this.db.exec(TURNS_TABLE_DDL(this.table))\n await this.db.exec(TURNS_INDEX_DDL(this.table))\n }\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n const runs = await this.db.query<{\n run_id: string\n started_at: string\n halted_kind: string | null\n halted_payload: string | null\n ended_at: string | null\n }>(\n `SELECT run_id, started_at, halted_kind, halted_payload, ended_at FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n const row = runs[0]\n if (!row) return undefined\n const turns = await this.db.query<{ payload: string; turn_index: number }>(\n `SELECT payload, turn_index FROM ${this.table}_turns WHERE run_id = ? ORDER BY turn_index ASC`,\n [runId],\n )\n return {\n runId: row.run_id,\n startedAt: row.started_at,\n halted: row.halted_payload ? (JSON.parse(row.halted_payload) as HaltReason) : undefined,\n endedAt: row.ended_at ?? undefined,\n turns: turns.map((t) => JSON.parse(t.payload) as ConversationTurn),\n }\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = await this.db.query<{ started_at: string }>(\n `SELECT started_at FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n if (existing.length > 0) {\n if (existing[0]?.started_at !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists with startedAt=${existing[0]?.started_at}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n await this.db.exec(`INSERT INTO ${this.table}_runs (run_id, started_at) VALUES (?, ?)`, [\n runId,\n startedAt,\n ])\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n const halted = await this.db.query<{ halted_kind: string | null }>(\n `SELECT halted_kind FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n if (halted.length === 0) {\n throw new Error(\n `appendTurn called for unknown runId '${runId}'; call beginRun first or use the runner which handles it`,\n )\n }\n if (halted[0]?.halted_kind) {\n throw new Error(\n `cannot append turn to halted run '${runId}' (halt kind: ${halted[0]?.halted_kind})`,\n )\n }\n await this.db.exec(\n `INSERT INTO ${this.table}_turns (run_id, turn_index, payload) VALUES (?, ?, ?)`,\n [runId, turn.index, JSON.stringify(turn)],\n )\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n const rs = await this.db.exec(\n `UPDATE ${this.table}_runs SET halted_kind = ?, halted_payload = ?, ended_at = ? WHERE run_id = ?`,\n [halt.kind, JSON.stringify(halt), endedAt, runId],\n )\n if (rs.rowsAffected === 0) {\n throw new Error(`recordHalt called for unknown runId '${runId}'`)\n }\n }\n}\n","/**\n * `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`\n * (the agent under test) as a multi-round conversation driven by a PERSONA (the\n * simulated user), over the persistent conversation transcript.\n *\n * It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an\n * LLM role-playing the user from its facts) — `runConversation` runs the two\n * against each other. Scripted persona turns are kept as a deterministic\n * fast-path. Only the WORKER is metered (it is the side under test); the\n * persona-driver is the test harness, not billed against the agent.\n *\n * `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops\n * straight into `runProfileMatrix({ dispatch })` — the same loop serves a single\n * cell and the whole matrix, replacing the per-agent hand-rolled\n * `dispatchWithSurface` bridges.\n */\n\nimport type { AgentProfile, MaximumCharge } from '@tangle-network/agent-eval'\nimport type {\n DispatchContext,\n ProfileDispatchFn,\n Scenario,\n} from '@tangle-network/agent-eval/campaign'\nimport { createIterableBackend } from '../backends'\nimport { createProfileExecutionBackend } from '../runtime/profile-execution-backend'\nimport type { ExecutorFactory } from '../runtime/supervise/types'\nimport type { AgentExecutionBackend, RuntimeStreamEvent } from '../types'\nimport { defineConversation } from './define-conversation'\nimport { runConversation } from './run-conversation'\nimport type { ConversationTurn, HaltPredicate, HaltReason } from './types'\n\n/** A persona that drives the conversation: either a full driver `AgentProfile`\n * (an LLM user-sim) or a deterministic script of user turns (the fast-path). */\nexport type PersonaDriver =\n | { kind: 'profile'; profile: AgentProfile }\n | { kind: 'scripted'; turns: string[] }\n\nexport interface RunPersonaConversationOptions {\n /** The agent under test. Metered; its rendered prompt leads its turns. */\n worker: AgentProfile\n /** The simulated user driving the dialogue. */\n persona: PersonaDriver\n /** Resolve transport/executable ports for the exact profile. Runtime still materializes the\n * profile and owns every model call. Applied to the worker and a profile-driven persona. */\n executorFor: (profile: AgentProfile, role: 'worker' | 'persona') => ExecutorFactory<unknown>\n /** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`\n * (worker answers each user turn). REQUIRED for a `profile` persona. */\n maxTurns?: number\n /** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */\n seed?: string\n /** Content-based \"until satisfied\" halt, called after every turn. `maxTurns` is the\n * hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */\n haltOn?: HaltPredicate\n signal?: AbortSignal\n /** Worker participant / transcript speaker label. Default 'agent'. */\n workerName?: string\n}\n\nexport interface PersonaConversationResult {\n transcript: ConversationTurn[]\n turns: number\n halted: HaltReason\n /** Worker-only spend (the side under test). */\n costUsd: number\n tokensIn: number\n tokensOut: number\n /** Absent means every worker call reported complete token usage. */\n tokensKnown?: false\n /** Absent means every worker call reported provider-billed cost, including a known zero. */\n costUsdKnown?: false\n}\n\ninterface UsageCounter {\n tokensIn: number\n tokensOut: number\n costUsd: number\n sawLlmCall: boolean\n tokensKnown: boolean\n usdKnown: boolean\n}\n\n/** Adapt one exact profile + Runtime executor into the conversation stream protocol. */\nfunction profileRuntimeBackend(\n profile: AgentProfile,\n factory: ExecutorFactory<unknown>,\n counter?: UsageCounter,\n): AgentExecutionBackend {\n const backend = createProfileExecutionBackend({ profile, executor: factory })\n if (!counter) return backend\n return {\n ...backend,\n async *stream(input, context) {\n for await (const event of backend.stream(input, context)) {\n if (event.type === 'llm_call') {\n counter.sawLlmCall = true\n counter.tokensIn += event.tokensIn ?? 0\n counter.tokensOut += event.tokensOut ?? 0\n counter.costUsd += event.costUsd ?? 0\n if (\n event.tokensKnown === false ||\n event.tokensIn === undefined ||\n event.tokensOut === undefined\n ) {\n counter.tokensKnown = false\n }\n if (event.usdKnown === false || event.costUsd === undefined) {\n counter.usdKnown = false\n }\n }\n yield event\n }\n },\n }\n}\n\n/** A persona participant that replays scripted user turns in order. */\nfunction scriptedPersonaBackend(turns: readonly string[]): AgentExecutionBackend {\n let idx = 0\n return createIterableBackend({\n kind: 'persona-user',\n async *stream(_input, context) {\n const text = turns[idx]\n if (text === undefined) {\n throw new Error(\n `persona-user: ran out of scripted turns at index ${idx} (had ${turns.length})`,\n )\n }\n idx += 1\n yield {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: new Date().toISOString(),\n } satisfies RuntimeStreamEvent\n },\n })\n}\n\n/**\n * Run one worker profile against one persona as a multi-round conversation.\n * The persona leads (participant 0): it speaks, the worker answers, repeat,\n * until `maxTurns`. Returns the persistent transcript + worker-only usage.\n */\nexport async function runPersonaConversation(\n opts: RunPersonaConversationOptions,\n): Promise<PersonaConversationResult> {\n const counter: UsageCounter = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n sawLlmCall: false,\n // Both flags start true and are lowered by the first unproven reading. They only reach a\n // result when `sawLlmCall` is true (see the terminal read below), so an unmetered\n // conversation never publishes them as a measured zero.\n tokensKnown: true,\n usdKnown: true,\n }\n const workerName = opts.workerName ?? 'agent'\n const worker = profileRuntimeBackend(\n opts.worker,\n opts.executorFor(opts.worker, 'worker'),\n counter,\n )\n\n let persona: AgentExecutionBackend\n let maxTurns: number\n if (opts.persona.kind === 'scripted') {\n if (opts.persona.turns.length === 0) {\n throw new Error('runPersonaConversation: scripted persona has no turns')\n }\n persona = scriptedPersonaBackend(opts.persona.turns)\n maxTurns = opts.maxTurns ?? 2 * opts.persona.turns.length\n } else {\n persona = profileRuntimeBackend(\n opts.persona.profile,\n opts.executorFor(opts.persona.profile, 'persona'),\n )\n if (opts.maxTurns === undefined) {\n throw new Error('runPersonaConversation: maxTurns is required for a profile-driven persona')\n }\n maxTurns = opts.maxTurns\n }\n\n const conversation = defineConversation({\n // Persona leads (participant 0): the seed routes to it, it produces the\n // user turn, the worker answers, alternate.\n participants: [\n { name: 'user', backend: persona },\n { name: workerName, backend: worker },\n ],\n policy: { maxTurns, turnOrder: 'alternate', ...(opts.haltOn ? { haltOn: opts.haltOn } : {}) },\n })\n const result = await runConversation(conversation, {\n seed: opts.seed ?? 'Begin.',\n signal: opts.signal,\n })\n // Worker-only cost. Prefer the worker's own metered llm_call spend. Fall back\n // to the engine's aggregate spend ONLY for a scripted persona — there the\n // harness has no LLM cost so the aggregate IS the worker's. For a\n // profile-driven persona the aggregate also includes the persona-driver's\n // spend, so attributing it to the worker would over-count; report the\n // worker's metered spend (0 if its backend reported none) instead.\n const fallbackCostKnown =\n !counter.sawLlmCall && opts.persona.kind === 'scripted' && result.spentCreditsCents > 0\n const costUsd = fallbackCostKnown ? result.spentCreditsCents / 100 : counter.costUsd\n const tokensKnown = counter.sawLlmCall && counter.tokensKnown\n const costUsdKnown = counter.sawLlmCall ? counter.usdKnown : fallbackCostKnown\n return {\n transcript: result.transcript,\n turns: result.turns,\n halted: result.halted,\n costUsd,\n tokensIn: counter.tokensIn,\n tokensOut: counter.tokensOut,\n ...(tokensKnown ? {} : { tokensKnown: false }),\n ...(costUsdKnown ? {} : { costUsdKnown: false }),\n }\n}\n\nexport interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {\n /** Resolve transport/executable ports for each exact profile. */\n executorFor: (profile: AgentProfile, role: 'worker' | 'persona') => ExecutorFactory<unknown>\n /** The persona driving each scenario — a driver profile or scripted turns. */\n personaOf: (scenario: TScenario) => PersonaDriver\n /** Build the scored artifact from the finished transcript. */\n artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact\n /** Speaker-turn cap (required when a persona is profile-driven). */\n maxTurns?: (scenario: TScenario) => number\n seed?: (scenario: TScenario) => string\n workerName?: string\n /** Provider- or executor-enforced maximum for the whole worker conversation.\n * Required before execution when the enclosing campaign is cost-capped. */\n maximumCharge?:\n | MaximumCharge\n | ((worker: AgentProfile, scenario: TScenario) => MaximumCharge | undefined)\n}\n\n/**\n * Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for\n * `runProfileMatrix`: the profile axis is the worker-under-test, the scenario\n * axis is the persona, and the runner is the cell. Meters the worker through\n * `ctx.cost` so the matrix's backend-integrity guard sees real usage.\n */\nexport function runPersonaDispatch<TScenario extends Scenario, TArtifact>(\n config: RunPersonaConfig<TScenario, TArtifact>,\n): ProfileDispatchFn<TScenario, TArtifact> {\n return async (\n worker: AgentProfile,\n scenario: TScenario,\n ctx: DispatchContext,\n ): Promise<TArtifact> => {\n const model = worker.model?.default ?? 'unknown'\n const maximumCharge =\n typeof config.maximumCharge === 'function'\n ? config.maximumCharge(worker, scenario)\n : config.maximumCharge\n const paid = await ctx.cost.runPaidCall({\n channel: 'agent',\n actor: 'persona-conversation',\n model,\n signal: ctx.signal,\n ...(maximumCharge ? { maximumCharge } : {}),\n execute: (executionSignal) =>\n runPersonaConversation({\n worker,\n persona: config.personaOf(scenario),\n executorFor: config.executorFor,\n maxTurns: config.maxTurns?.(scenario),\n seed: config.seed?.(scenario),\n signal: executionSignal,\n workerName: config.workerName,\n }),\n receipt: (result) => ({\n model,\n inputTokens: result.tokensIn,\n outputTokens: result.tokensOut,\n ...(result.tokensKnown === false ? { usageUnknown: true } : {}),\n ...(result.costUsdKnown === false\n ? { costUnknown: true }\n : { actualCostUsd: result.costUsd }),\n }),\n })\n if (!paid.succeeded) throw paid.error\n const result = paid.value\n return config.artifactOf(result.transcript, scenario)\n }\n}\n","/**\n * Build-prompt starting points for the two buildable artifact types. There is\n * NO `toolGenerator`/`mcpGenerator` wrapper — the factory is `agenticGenerator`\n * + a verifier (docs/artifact-lifecycle-frontier.md), so a tool or an MCP\n * server is built by composing the pieces directly:\n *\n * // a tool:\n * agenticGenerator({ profile, executorForWorktree, buildPrompt: toolBuildPrompt,\n * verify: commandVerifier('pnpm', ['test']) })\n * // an MCP server:\n * agenticGenerator({ profile, executorForWorktree, buildPrompt: mcpBuildPrompt,\n * verify: mcpServeVerifier({ command: 'node', args: ['server.mjs'] }) })\n *\n * These are the only type-specific bit (the phrasing that points the agent at a\n * tool vs. an MCP); the worktree, resume-on-failure loop, and improvement-loop\n * wrapper are shared. MCP is the load-bearing target — it is how a harness\n * acquires tools; raw tools matter where we control the loader.\n */\n\nimport type { ProposalFinding } from '@tangle-network/agent-eval'\nimport { optimizerMethod } from './optimizer-prompt'\n\n/** Evidence supplied to a generated tool or MCP build instruction. */\nexport interface BuildPromptFindingsInput {\n findings: ReadonlyArray<ProposalFinding>\n}\n\n/** Render findings as the ranked-evidence block every build prompt ends with. */\nexport function findingLines(findings: ReadonlyArray<ProposalFinding>): string[] {\n return findings.map((f) => {\n const where = f.subject ? ` [${f.subject}]` : ''\n const action = f.recommended_action ? ` → ${f.recommended_action}` : ''\n return `- (${f.severity})${where} ${f.claim}${action}`\n })\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new tool. */\nexport function toolBuildPrompt(args: BuildPromptFindingsInput): string {\n return [\n 'You are building a new TOOL for this codebase — a capability the agent measurably lacks,',\n 'evidenced by the failure findings at the bottom. The tool is an experiment: after it is',\n 'built and verified, its marginal lift is measured on held-out tasks, and only a real lift',\n 'promotes it.',\n '',\n optimizerMethod,\n '',\n 'THE SURFACE — what a deliverable tool looks like here:',\n '- ONE small, self-contained module PLUS tests that exercise its contract (what callers rely',\n ' on), not its internals. The tests are the experiment for sub-goal correctness — write the',\n ' test that would fail if your hypothesis about the gap were wrong.',\n '- It must compile and its tests must pass — they run automatically; on failure you get the',\n ' verifier output and another attempt, resuming on top of your own edits (fix in place, do',\n ' not start over).',\n '- Match the codebase grain: reuse its existing helpers, style, and test framework; a tool',\n ' that fights the codebase is the wrong tool even if it passes.',\n '- Do not commit; leave the changes in the working tree.',\n '',\n 'FINDINGS — ranked evidence from real failed runs (the gaps the tool must close):',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new MCP server. */\nexport function mcpBuildPrompt(args: BuildPromptFindingsInput): string {\n return [\n 'You are building a new MCP SERVER (Model Context Protocol) exposing tool(s) that close the',\n 'capability gaps evidenced by the failure findings at the bottom, so any harness can mount',\n 'them. The server is an experiment: after it is built and boot-verified, its marginal lift is',\n 'measured on held-out tasks, and only a real lift promotes it.',\n '',\n optimizerMethod,\n '',\n 'RESEARCH FIRST — ADOPT BEFORE BUILD: you may discover and ADOPT an existing external MCP',\n 'server if it fits the gaps better than building one. Registries and vendor docs list',\n 'maintained servers for most common capabilities (web search, fetch, GitHub, filesystems,',\n 'databases). To adopt, deliver a short adoption note instead of an implementation: the',\n \"server's launch command or HTTP endpoint, and the API key it needs BY NAME (e.g.\",\n 'EXA_API_KEY) — never a key value; provisioning injects the value at materialize time. If',\n 'your environment has no web access, decide from what you already know and say so.',\n '',\n 'THE SURFACE — what a deliverable MCP server looks like here (checked by BOOTING it):',\n '- it starts over stdio and answers the MCP `initialize` handshake,',\n '- `tools/list` returns at least one tool with a valid input schema,',\n '- newline-delimited JSON-RPC 2.0, protocol version 2024-11-05,',\n '- a clear start command (a package.json `start` script or an obvious entrypoint).',\n 'Design the tool surface for the FINDINGS, not for generality: each exposed tool should map to',\n 'a named failure mechanism, with a description that tells the agent when to reach for it (a',\n 'tool the agent never calls measures zero). If the boot-and-probe fails you get the error and',\n 'another attempt, resuming on top of your own edits. Do not commit; leave the changes in the',\n 'working tree.',\n '',\n 'FINDINGS — ranked evidence from real failed runs (the capabilities the server must provide):',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n","/**\n * `mcpServeVerifier` — the intrinsic verifier for a built MCP server: the\n * boot-and-probe checker named in docs/artifact-lifecycle-frontier.md. A\n * generated MCP server is only a candidate if it actually *serves* — so this\n * boots it over stdio (the default local MCP transport) and runs the real\n * handshake: `initialize` → `notifications/initialized` → `tools/list`, and\n * asserts the server answers with at least `minTools` tools.\n *\n * The spawn + handshake is the SHARED same-host stdio connection\n * (`connectStdioMcp`) — the same code path that later serves the built server\n * LIVE to a scored run (`materializeLocalMcp`), so \"verified it serves\" and\n * \"served while scored\" can never drift apart.\n *\n * Outcomes follow the `Verifier` contract: a server that fails to start, exits\n * early, errors the handshake, times out, or exposes no tools is a FAILED\n * candidate (`{ok:false}`, fed back into the next generation shot); a missing\n * start binary or spawn fault THROWS (a setup bug, never a silent fallback).\n */\n\nimport {\n connectStdioMcp,\n McpSpawnFault,\n type StdioMcpConnection,\n} from '../runtime/stdio-mcp-client'\nimport type { Verifier, VerifyResult } from './agentic-generator'\n\nexport interface McpServeSpec {\n /** Command that starts the built MCP server in the worktree (stdio transport). */\n command: string\n args?: string[]\n /** Extra env for the server process (merged over `process.env`). */\n env?: Record<string, string>\n /** Handshake timeout (ms). Default 30s. */\n timeoutMs?: number\n /** Minimum tools the server must expose to pass. Default 1. */\n minTools?: number\n}\n\n/** Build a `Verifier` that boots a generated MCP server over stdio and checks it exposes tools. */\nexport function mcpServeVerifier(spec: McpServeSpec): Verifier {\n const minTools = spec.minTools ?? 1\n\n return async (worktreePath: string): Promise<VerifyResult> => {\n let conn: StdioMcpConnection\n try {\n conn = await connectStdioMcp({\n command: spec.command,\n ...(spec.args ? { args: spec.args } : {}),\n cwd: worktreePath,\n ...(spec.env ? { env: spec.env } : {}),\n ...(spec.timeoutMs !== undefined ? { timeoutMs: spec.timeoutMs } : {}),\n })\n } catch (err) {\n if (err instanceof McpSpawnFault) {\n throw new Error(`mcpServeVerifier: ${err.message}`)\n }\n // Crash-on-boot / handshake error / timeout: a failed candidate, with the\n // connection's stderr-tailed message as the feedback for the next shot.\n return { ok: false, feedback: err instanceof Error ? err.message : String(err) }\n }\n try {\n if (conn.tools.length < minTools) {\n return {\n ok: false,\n feedback: `tools/list returned ${conn.tools.length} tool(s), need >= ${minTools}`,\n }\n }\n return { ok: true }\n } finally {\n await conn.close()\n }\n }\n}\n","import { isDeepStrictEqual } from 'node:util'\nimport { canonicalJson } from '@tangle-network/agent-eval'\nimport {\n type GepaOptimizationMethodConfig,\n gepaOptimizationMethod,\n type JudgeScore,\n type OptimizationMethod,\n type SkillOptOptimizationMethodConfig,\n skillOptOptimizationMethod,\n} from '@tangle-network/agent-eval/campaign'\nimport { canonicalCandidateDigest } from '../candidate-execution/digest'\nimport { ConfigError } from '../errors'\nimport {\n defaultRedactor,\n defaultRedactorIdentityMaterial,\n type Redactor,\n resolveRedactor,\n} from '../redact'\nimport type {\n ImproveCandidateValidationInput,\n ImproveMethodContext,\n ImproveMethodFactory,\n} from './improve'\nimport { withMethodRuntimeControls } from './method-controls'\n\nconst defaultMaxFindingsChars = 50_000\nconst pythonClientDocs = 'https://github.com/tangle-network/agent-eval/tree/main/clients/python'\nconst bridgeInstall = '`python -m pip install \"agent-eval-rpc==0.145.0\"`'\nconst gepaWheelInstall = '`python -m pip install \"gepa[full]==0.1.4\"`'\nconst gepaSourceInstall =\n '`python -m pip install \"gepa[full] @ git+https://github.com/gepa-ai/gepa.git@f919db0a622e2e9f9204779b81fe00cc1b2d808f\"`'\nconst skillOptInstall =\n `${bridgeInstall}, then ` +\n '`python -m pip install \"skillopt @ git+https://github.com/microsoft/SkillOpt.git@61735e3922efc2b90c6d6cab561e62e98452ca90\"`'\n\n/** Runtime context appended to an official optimizer's own configuration. */\nexport interface OfficialOptimizerContextOptions {\n /** Context supplied to the optimizer before Runtime appends the profile surface and findings. */\n background?: string\n /** Include current trace or analyst findings in the optimizer background. Default true. */\n includeFindings?: boolean\n /** Reject oversized serialized findings before starting Python. Default 50,000 characters. */\n maxFindingsChars?: number\n /**\n * Redact caller-supplied context and descriptors before they leave Runtime.\n * The built-in redactor is the default. Pass `false` only for public data\n * that has already been reviewed.\n */\n redact?: Redactor | false\n /** Authorize one exact candidate containing structurally sensitive fields.\n * The callback must return true for every accepted baseline and candidate. */\n authorizeSensitiveCandidate?: (input: OfficialSensitiveCandidateInput) => boolean\n}\n\nexport interface OfficialSensitiveCandidateInput extends ImproveCandidateValidationInput {\n sensitivePaths: readonly string[]\n}\n\n/** Official GEPA configuration plus bounded Runtime findings context. */\nexport type OfficialGepaOptions<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n> = Omit<GepaOptimizationMethodConfig<TScenario, TArtifact>, 'background' | 'evaluationId'> &\n OfficialOptimizerContextOptions\n\n/** Official SkillOpt configuration plus bounded Runtime findings context. */\nexport type OfficialSkillOptOptions<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n> = Omit<SkillOptOptimizationMethodConfig<TScenario, TArtifact>, 'background' | 'evaluationId'> &\n OfficialOptimizerContextOptions\n\n/** Missing optional Python dependencies for an official optimizer. */\nexport class OfficialOptimizerUnavailableError extends ConfigError {\n readonly optimizer: 'gepa' | 'skillopt'\n\n constructor(optimizer: 'gepa' | 'skillopt', cause: unknown) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n const install =\n optimizer === 'gepa'\n ? [\n `Install the Python bridge: ${bridgeInstall}.`,\n `The direct GEPA engine uses the published wheel: ${gepaWheelInstall}.`,\n `Composed recipes and source-only engines use the tested source revision: ${gepaSourceInstall}.`,\n ].join(' ')\n : `Install Microsoft SkillOpt: ${skillOptInstall}.`\n super(\n [\n `Official ${optimizer === 'gepa' ? 'GEPA' : 'SkillOpt'} could not start.`,\n 'Runtime did not use a local fallback.',\n install,\n `Setup: ${pythonClientDocs}.`,\n `Cause: ${detail}`,\n ].join(' '),\n { cause },\n )\n this.optimizer = optimizer\n }\n}\n\n/**\n * Build a complete method backed by GEPA's official Optimize Anything API.\n *\n * The recipe is passed through unchanged. Use `engine`, `sequential`,\n * `adaptive-sequential`, `best-of`, `vote`, or `omni` explicitly.\n */\nexport function officialGepa<TScenario extends { id: string; kind: string }, TArtifact = unknown>(\n options: OfficialGepaOptions<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n return officialOptimizer<TScenario, TArtifact, OfficialGepaOptions<TScenario, TArtifact>>(\n 'gepa',\n options,\n (config) => gepaOptimizationMethod(config),\n )\n}\n\n/** Build a complete method backed by Microsoft's official SkillOpt trainer. */\nexport function officialSkillOpt<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n>(\n options: OfficialSkillOptOptions<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n return officialOptimizer<TScenario, TArtifact, OfficialSkillOptOptions<TScenario, TArtifact>>(\n 'skillopt',\n options,\n (config) => skillOptOptimizationMethod(config),\n )\n}\n\ntype PreparedOptimizerContext<TScenario extends { id: string; kind: string }, TArtifact> = Pick<\n GepaOptimizationMethodConfig<TScenario, TArtifact>,\n 'objective' | 'evaluationId' | 'background' | 'describeScenario' | 'describeArtifact'\n>\n\n/** Keep evidence redaction, identity, dependency errors, and candidate controls identical for both wrappers. */\nfunction officialOptimizer<\n TScenario extends { id: string; kind: string },\n TArtifact,\n TOptions extends\n | OfficialGepaOptions<TScenario, TArtifact>\n | OfficialSkillOptOptions<TScenario, TArtifact>,\n>(\n optimizer: 'gepa' | 'skillopt',\n options: TOptions,\n create: (\n config: Omit<\n TOptions,\n keyof OfficialOptimizerContextOptions | 'describeScenario' | 'describeArtifact'\n > &\n PreparedOptimizerContext<TScenario, TArtifact>,\n ) => OptimizationMethod<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n const label = optimizer === 'gepa' ? 'officialGepa' : 'officialSkillOpt'\n const {\n background,\n includeFindings = true,\n maxFindingsChars,\n describeScenario,\n describeArtifact,\n redact,\n authorizeSensitiveCandidate,\n ...config\n } = options\n const redactor = resolveRedactor(redact)\n const redactionPolicyRef = optimizerRedactionPolicyRef(redact)\n assertMaxFindingsChars(label, maxFindingsChars)\n const objective = redactOptimizerText(label, 'objective', config.objective, redactor)\n return (context) => {\n const externalEvaluationRef = optimizerEvidencePolicyRef({\n runtimeEvaluationRef: context.evaluationRef,\n redactionPolicyRef,\n describeScenario,\n describeArtifact,\n authorizeSensitiveCandidate,\n })\n const method = withDependencyHelp(\n optimizer,\n externalEvaluationRef,\n redactor,\n redactionPolicyRef,\n create({\n ...config,\n objective,\n evaluationId: externalEvaluationRef,\n background: methodBackground({\n context,\n background,\n includeFindings,\n maxFindingsChars,\n label,\n redactor,\n }),\n ...(describeScenario\n ? {\n describeScenario: (scenario) =>\n redactOptimizerEvidence(\n label,\n 'scenario descriptor',\n describeScenario(scenario),\n redactor,\n ),\n }\n : {}),\n ...(describeArtifact\n ? {\n describeArtifact: (artifact, scenario) =>\n redactOptimizerEvidence(\n label,\n 'artifact descriptor',\n describeArtifact(artifact, scenario),\n redactor,\n ),\n }\n : {}),\n }),\n )\n return withMethodRuntimeControls(method, {\n costAttribution: 'optimizer-run',\n validateCandidate: (input) =>\n assertSafeOptimizerCandidate(label, input, authorizeSensitiveCandidate),\n })\n }\n}\n\nfunction assertMaxFindingsChars(label: string, value: number | undefined): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new ConfigError(`${label}: maxFindingsChars must be a positive safe integer`)\n }\n}\n\nfunction methodBackground(options: {\n context: ImproveMethodContext\n background: string | undefined\n includeFindings: boolean\n maxFindingsChars: number | undefined\n label: string\n redactor: Redactor\n}): string {\n const {\n context,\n background,\n includeFindings,\n maxFindingsChars = defaultMaxFindingsChars,\n label,\n redactor,\n } = options\n const safeBackground =\n background === undefined\n ? undefined\n : redactOptimizerText(label, 'background', background, redactor)\n const safeProfileName =\n context.profile.name === undefined\n ? undefined\n : redactOptimizerText(label, 'profile name', context.profile.name, redactor)\n const sections = [\n safeBackground?.trim(),\n safeProfileName\n ? `Agent profile: ${safeProfileName}. Surface: ${context.surface}.`\n : `Agent surface: ${context.surface}.`,\n ].filter((value): value is string => Boolean(value))\n if (includeFindings && context.findings.length > 0) {\n let serialized: string\n try {\n serialized = canonicalJson(\n redactOptimizerEvidence(label, 'findings', context.findings, redactor),\n )\n } catch (cause) {\n throw new ConfigError(`${label}: findings must be JSON-serializable`, { cause })\n }\n if (serialized.length > maxFindingsChars) {\n throw new ConfigError(\n `${label}: serialized findings exceed maxFindingsChars (${serialized.length} > ${maxFindingsChars})`,\n )\n }\n sections.push(`Observed failures:\\n${serialized}`)\n }\n return sections.join('\\n\\n')\n}\n\nfunction assertSafeOptimizerCandidate(\n label: string,\n input: ImproveCandidateValidationInput,\n authorizeSensitiveCandidate: ((input: OfficialSensitiveCandidateInput) => boolean) | undefined,\n): void {\n const redactedValue = defaultRedactor(input.value)\n const redactedSurface = defaultRedactor(input.candidateSurface)\n if (\n !isDeepStrictEqual(input.value, redactedValue) ||\n !isDeepStrictEqual(input.candidateSurface, redactedSurface)\n ) {\n throw new ConfigError(\n `${label}: the selected profile surface contains a common credential or private value. ` +\n 'Store live credentials as provider references, or remove private data before starting an external optimizer.',\n )\n }\n const sensitivePaths = sensitiveProfileSurfacePaths(input)\n if (sensitivePaths.length === 0) return\n let authorized = false\n if (authorizeSensitiveCandidate) {\n try {\n authorized =\n authorizeSensitiveCandidate(\n Object.freeze({\n ...input,\n sensitivePaths: Object.freeze([...sensitivePaths]),\n }),\n ) === true\n } catch (cause) {\n throw new ConfigError(`${label}: sensitive candidate authorization failed`, { cause })\n }\n }\n if (!authorized) {\n throw new ConfigError(\n `${label}: the selected profile surface contains fields that may carry private values: ` +\n `${sensitivePaths.slice(0, 8).join(', ')}. Remove them, replace values with safe references, ` +\n 'or authorize the exact profile with authorizeSensitiveCandidate.',\n )\n }\n}\n\nfunction sensitiveProfileSurfacePaths(input: ImproveCandidateValidationInput): string[] {\n const paths = new Set<string>()\n if (\n input.surface === 'tools' ||\n input.surface === 'mcp' ||\n input.surface === 'hooks' ||\n input.surface === 'subagents' ||\n input.surface === 'agent-profile'\n ) {\n paths.add('$')\n }\n const seen = new WeakSet<object>()\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object') return\n if (seen.has(current)) return\n seen.add(current)\n if (Array.isArray(current)) {\n current.forEach((child, index) => {\n visit(child, `${path}[${index}]`)\n })\n return\n }\n for (const [key, child] of Object.entries(current as Record<string, unknown>)) {\n const childPath = `${path}.${key}`\n if (['env', 'headers', 'url', 'metadata', 'extensions'].includes(key.toLowerCase())) {\n paths.add(childPath)\n continue\n }\n visit(child, childPath)\n }\n }\n visit(input.value, '$')\n return [...paths]\n}\n\nfunction redactOptimizerEvidence(\n label: string,\n field: string,\n value: unknown,\n redactor: Redactor,\n): unknown {\n try {\n return redactor(value)\n } catch (cause) {\n throw new ConfigError(`${label}: ${field} redaction failed`, { cause })\n }\n}\n\nfunction redactOptimizerText(\n label: string,\n field: string,\n value: string,\n redactor: Redactor,\n): string {\n const redacted = redactOptimizerEvidence(label, field, value, redactor)\n if (typeof redacted !== 'string' || !redacted.trim()) {\n throw new ConfigError(`${label}: ${field} redaction must return a non-empty string`)\n }\n return redacted\n}\n\nfunction redactJudgeScore(score: JudgeScore, redactor: Redactor): JudgeScore {\n const notes = redactOptimizerEvidence('official optimizer', 'judge notes', score.notes, redactor)\n return {\n ...score,\n notes: typeof notes === 'string' ? notes : '[redacted]',\n }\n}\n\nexport function optimizerRedactionPolicyRef(\n redact: Redactor | false | undefined,\n builtInIdentity: unknown = defaultRedactorIdentityMaterial(),\n): string {\n if (redact === false) return 'caller-approved-raw'\n return canonicalCandidateDigest({\n kind: redact === undefined ? 'default-redactor' : 'caller-redactor-with-default',\n builtIn: builtInIdentity,\n ...(redact === undefined\n ? {}\n : {\n callerSource: Function.prototype.toString.call(redact),\n composition: Function.prototype.toString.call(resolveRedactor),\n }),\n })\n}\n\nfunction optimizerEvidencePolicyRef(input: {\n runtimeEvaluationRef: ImproveMethodContext['evaluationRef']\n redactionPolicyRef: string\n describeScenario: unknown\n describeArtifact: unknown\n authorizeSensitiveCandidate: unknown\n}): ReturnType<typeof canonicalCandidateDigest> {\n return canonicalCandidateDigest({\n runtimeEvaluationRef: input.runtimeEvaluationRef,\n redactionPolicyRef: input.redactionPolicyRef,\n describeScenario: callbackSource(input.describeScenario),\n describeArtifact: callbackSource(input.describeArtifact),\n authorizeSensitiveCandidate: callbackSource(input.authorizeSensitiveCandidate),\n })\n}\n\nfunction callbackSource(callback: unknown): string | null {\n return typeof callback === 'function' ? Function.prototype.toString.call(callback) : null\n}\n\nfunction withDependencyHelp<TScenario extends { id: string; kind: string }, TArtifact>(\n optimizer: 'gepa' | 'skillopt',\n evaluationRef: ImproveMethodContext['evaluationRef'],\n redactor: Redactor,\n redactionPolicyRef: string,\n method: OptimizationMethod<TScenario, TArtifact>,\n): OptimizationMethod<TScenario, TArtifact> {\n return {\n ...method,\n async optimize(input) {\n try {\n const judges = input.judges.map((judge) =>\n Object.freeze({\n ...judge,\n judgeVersion: canonicalCandidateDigest({\n evaluationRef,\n name: judge.name,\n dimensions: judge.dimensions,\n judgeVersion: judge.judgeVersion ?? null,\n outwardEvidence: redactionPolicyRef,\n }),\n async score(scoreInput: Parameters<typeof judge.score>[0]) {\n return redactJudgeScore(await judge.score(scoreInput), redactor)\n },\n }),\n )\n return await method.optimize({\n ...input,\n judges: Object.freeze(judges),\n })\n } catch (cause) {\n if (isMissingDependency(optimizer, cause)) {\n throw new OfficialOptimizerUnavailableError(optimizer, cause)\n }\n throw cause\n }\n },\n }\n}\n\nfunction isMissingDependency(optimizer: 'gepa' | 'skillopt', cause: unknown): boolean {\n const message = cause instanceof Error ? cause.message : String(cause)\n const common = [\n `${optimizer === 'gepa' ? 'GEPA' : 'SkillOpt'} bridge could not start`,\n 'source inspection could not start',\n \"No module named 'agent_eval_rpc'\",\n `No module named 'agent_eval_rpc.${optimizer === 'gepa' ? 'gepa_bridge' : 'skillopt_bridge'}'`,\n ]\n const specific =\n optimizer === 'gepa'\n ? [\n 'requires GEPA',\n \"requires GEPA's Optimize Anything\",\n \"No module named 'gepa'\",\n 'gepa is importable but its package metadata is unavailable',\n ]\n : [\n 'requires skillopt',\n 'requires SkillOpt',\n \"No module named 'skillopt'\",\n 'skillopt is importable but its package metadata is unavailable',\n ]\n return [...common, ...specific].some((fragment) => message.includes(fragment))\n}\n","import type { Scenario } from '@tangle-network/agent-eval/contract'\nimport {\n type AgentProfile,\n agentProfileSchema,\n canonicalAgentProfileDigest,\n type Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { immutableCandidateValue } from '../candidate-execution/digest'\nimport { ConfigError } from '../errors'\nimport { improve } from './improve'\nimport type {\n ImproveCandidateValidator,\n ImproveMethodOptions,\n ImproveMethodResult,\n ImproveProfileAgent,\n} from './improve-types'\nimport type { ReadonlyAgentProfile } from './profile-types'\n\nexport interface CreateProfileImprovementHarnessOptions<TScenario extends Scenario, TArtifact> {\n /** Exact baseline profile. It is parsed, detached, and frozen at construction. */\n profile: AgentProfile\n /**\n * Immutable identity of the bound executor, models, tools, component mapping,\n * and every closure or external setting that can change measured behavior.\n */\n executionRef: Sha256Digest\n /** Execute one exact materialized profile on one scenario. */\n agent: ImproveProfileAgent<TScenario, TArtifact>\n /** Optional validator shared by every run from this harness. */\n validateCandidate?: ImproveCandidateValidator\n}\n\nexport type ProfileImprovementHarnessRunOptions<TScenario extends Scenario, TArtifact> = Omit<\n ImproveMethodOptions<TScenario, TArtifact>,\n 'executionRef' | 'agent' | 'validateCandidate'\n> & {\n /** Override the harness-level validator for this run. */\n validateCandidate?: ImproveCandidateValidator\n}\n\n/**\n * A small, reusable front door over `improve(profile, options)`.\n *\n * The harness freezes the baseline and binds execution identity once, which\n * removes the two easiest sources of accidental experiment drift when a\n * developer runs several methods, surfaces, or held-out suites against the\n * same agent. It does not replace or narrow `improve`; callers retain every\n * method option and may still use the lower-level API directly.\n */\nexport interface ProfileImprovementHarness<TScenario extends Scenario, TArtifact> {\n /** Detached immutable baseline actually used by every run. */\n readonly profile: ReadonlyAgentProfile\n /** Canonical digest of the bound baseline profile. */\n readonly profileDigest: Sha256Digest\n /** Exact execution identity bound at construction. */\n readonly executionRef: Sha256Digest\n run(\n options: ProfileImprovementHarnessRunOptions<TScenario, TArtifact>,\n ): Promise<ImproveMethodResult>\n}\n\n/**\n * Bind one exact profile and executor into a repeatable self-improvement\n * harness. The returned `run` method remains generic over every existing\n * profile surface, optimization method, split, gate, and budget option.\n */\nexport function createProfileImprovementHarness<TScenario extends Scenario, TArtifact>(\n options: CreateProfileImprovementHarnessOptions<TScenario, TArtifact>,\n): ProfileImprovementHarness<TScenario, TArtifact> {\n const parsed = agentProfileSchema.safeParse(options.profile)\n if (!parsed.success) {\n throw new ConfigError(\n `createProfileImprovementHarness: invalid AgentProfile: ${parsed.error.message}`,\n )\n }\n if (!/^sha256:[0-9a-f]{64}$/.test(options.executionRef)) {\n throw new ConfigError(\n 'createProfileImprovementHarness: executionRef must be a lowercase sha256 digest',\n )\n }\n if (typeof options.agent !== 'function') {\n throw new ConfigError('createProfileImprovementHarness: agent must be a function')\n }\n if (options.validateCandidate !== undefined && typeof options.validateCandidate !== 'function') {\n throw new ConfigError(\n 'createProfileImprovementHarness: validateCandidate must be a function when present',\n )\n }\n\n const profile = immutableCandidateValue(parsed.data)\n const executionRef = options.executionRef\n const agent = options.agent\n const defaultValidator = options.validateCandidate\n\n return Object.freeze({\n profile,\n profileDigest: canonicalAgentProfileDigest(profile),\n executionRef,\n run(runOptions: ProfileImprovementHarnessRunOptions<TScenario, TArtifact>) {\n if (\n runOptions.validateCandidate !== undefined &&\n typeof runOptions.validateCandidate !== 'function'\n ) {\n throw new ConfigError(\n 'ProfileImprovementHarness.run: validateCandidate must be a function when present',\n )\n }\n const validateCandidate = runOptions.validateCandidate ?? defaultValidator\n return improve(profile, {\n ...runOptions,\n executionRef,\n agent,\n ...(validateCandidate === undefined ? {} : { validateCandidate }),\n })\n },\n })\n}\n","import { agentProfileSchema } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../errors'\nimport type { ImproveProfileComponents } from './improve-types'\nimport type { ReadonlyAgentProfile } from './profile-types'\n\n/** Stable component-name prefix used for `profile.prompt.instructions`. */\nexport const PROMPT_INSTRUCTION_COMPONENT_PREFIX = 'prompt.instruction:'\n\nconst COMPONENT_INDEX_WIDTH = 6\n\nfunction componentName(index: number): string {\n return `${PROMPT_INSTRUCTION_COMPONENT_PREFIX}${String(index).padStart(COMPONENT_INDEX_WIDTH, '0')}`\n}\n\nfunction orderedInstructionValues(components: Readonly<Record<string, string>>): string[] {\n const entries = Object.entries(components).sort(([left], [right]) => left.localeCompare(right))\n if (entries.length === 0) {\n throw new ConfigError(\n 'promptInstructionsProfileComponents: at least one prompt instruction is required',\n )\n }\n for (const [index, [name, value]] of entries.entries()) {\n const expected = componentName(index)\n if (name !== expected) {\n throw new ConfigError(\n `promptInstructionsProfileComponents: expected component ${JSON.stringify(expected)}, got ${JSON.stringify(name)}`,\n )\n }\n if (typeof value !== 'string') {\n throw new ConfigError(\n `promptInstructionsProfileComponents: component ${JSON.stringify(name)} must be a string`,\n )\n }\n }\n return entries.map(([, value]) => value)\n}\n\n/**\n * Canonical `ImproveProfileComponents` mapping for the ordered\n * `AgentProfile.prompt.instructions` list.\n *\n * Use it with `surface: 'agent-profile'` when an optimizer should rewrite the\n * exact instruction texts without being allowed to change their count, order,\n * labels, or any unrelated profile field:\n *\n * ```ts\n * await improve(profile, {\n * surface: 'agent-profile',\n * profileComponents: promptInstructionsProfileComponents,\n * // method, scenarios, judge, executionRef, agent, ...\n * })\n * ```\n *\n * Component names are zero-padded and stable. Runtime's existing component\n * materializer requires every candidate to preserve the exact key set and\n * verifies that `apply(read(profile))` reproduces the baseline profile. A\n * profile with no prompt instructions is refused rather than inventing a\n * sentinel instruction that could accidentally ship.\n */\nexport const promptInstructionsProfileComponents: ImproveProfileComponents = Object.freeze({\n read(profile: ReadonlyAgentProfile) {\n const instructions = profile.prompt?.instructions ?? []\n if (instructions.length === 0) {\n throw new ConfigError(\n 'promptInstructionsProfileComponents: profile.prompt.instructions must contain at least one instruction',\n )\n }\n return Object.fromEntries(\n instructions.map((instruction: string, index: number) => [componentName(index), instruction]),\n )\n },\n apply(\n profile: ReadonlyAgentProfile,\n components: Readonly<Record<string, string>>,\n ): ReadonlyAgentProfile {\n const instructions = orderedInstructionValues(components)\n return agentProfileSchema.parse({\n ...profile,\n prompt: {\n ...profile.prompt,\n instructions,\n },\n })\n },\n})\n","/**\n *\n * `reflectiveGenerator` — the cheap, no-sandbox `CandidateGenerator`. It drafts\n * surface edits via the existing improvement proposer (`proposeFromFindings`,\n * one LLM patch per finding) and applies them as ONE coherent improvement into\n * the candidate worktree. `maxShots` is ignored — reflection is single-shot by\n * construction (the patches are already drafted).\n *\n * This is the `shots=1, sandbox=off` code-candidate setting.\n * `agenticGenerator` supplies the multi-shot verify-in-session setting.\n *\n * @stable\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { readFileSync, realpathSync } from 'node:fs'\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\nimport type { SurfaceImprovementEdit } from '../agent/improvement-adapter'\nimport type { ImprovementProposalSource } from '../analyst-loop/types'\nimport type { CandidateGenerator } from './improvement-driver'\n\nexport interface ReflectiveGeneratorOptions {\n /** Bind proposal reads and paid calls to this candidate's worktree and account. */\n createImprovementProposalSource(\n context: Parameters<CandidateGenerator['generate']>[0],\n ): ImprovementProposalSource<SurfaceImprovementEdit>\n}\n\n/** Cheap no-sandbox `CandidateGenerator` (the `shots=1` setting): draft surface edits via the improvement adapter and apply them as one coherent candidate. */\nexport function reflectiveGenerator(opts: ReflectiveGeneratorOptions): CandidateGenerator {\n return {\n kind: 'reflective',\n async generate(context) {\n const { worktreePath, findings, signal } = context\n signal.throwIfAborted()\n const source = opts.createImprovementProposalSource(context)\n const batch = await source.proposeFromFindings(findings)\n signal.throwIfAborted()\n if (batch.errors.length > 0) {\n throw new AggregateError(\n batch.errors.map((error) => new Error(`${error.findingId}: ${error.message}`)),\n `reflectiveGenerator: proposal failed: ${batch.errors.map((error) => error.message).join('; ')}`,\n )\n }\n if (batch.edits.length === 0) return { applied: false, summary: '' }\n\n for (const edit of batch.edits) {\n assertPatchTarget(edit, worktreePath)\n assertCurrentBase(edit, worktreePath)\n }\n applyPatches(batch.edits, worktreePath)\n signal.throwIfAborted()\n\n const summary =\n batch.edits.length === 1\n ? batch.edits[0]!.summary\n : `analyst: ${batch.edits.length} surface edits`\n return { applied: true, summary }\n },\n }\n}\n\nfunction assertPatchTarget(edit: SurfaceImprovementEdit, cwd: string): void {\n // Reverse statistics include the source path of a rename or copy.\n for (const reverse of [false, true]) {\n const result = spawnSync(\n 'git',\n ['apply', '--numstat', '-z', '-p0', ...(reverse ? ['--reverse'] : []), '-'],\n { cwd, input: edit.patch, encoding: 'utf8' },\n )\n if (result.error) throw result.error\n if (result.status !== 0) {\n throw new Error(`reflectiveGenerator: invalid patch: ${result.stderr.trim()}`)\n }\n const paths = result.stdout\n .split('\\0')\n .filter(Boolean)\n .map((entry) => entry.slice(entry.indexOf('\\t', entry.indexOf('\\t') + 1) + 1))\n const target = resolve(cwd, edit.target.repoRelativePath)\n if (paths.length === 0 || paths.some((path) => resolve(cwd, path) !== target)) {\n throw new Error('reflectiveGenerator: patch paths do not match the declared target')\n }\n }\n}\n\nfunction assertCurrentBase(edit: SurfaceImprovementEdit, cwd: string): void {\n const root = realpathSync(cwd)\n const path = resolve(root, edit.target.repoRelativePath)\n assertWithinWorktree(root, path)\n let content: string\n try {\n assertWithinWorktree(root, realpathSync(path))\n content = readFileSync(path, 'utf8')\n } catch (error) {\n if (\n edit.target.intent !== 'create-new' ||\n !(error instanceof Error && 'code' in error && error.code === 'ENOENT')\n ) {\n throw error\n }\n content = ''\n }\n const actual = createHash('sha256').update(content, 'utf8').digest('hex')\n if (actual !== edit.baseSha256) {\n throw new Error(`reflectiveGenerator: stale proposal base for ${edit.target.repoRelativePath}`)\n }\n}\n\nfunction assertWithinWorktree(root: string, path: string): void {\n const local = relative(root, path)\n if (local === '..' || local.startsWith(`..${sep}`) || isAbsolute(local)) {\n throw new Error('reflectiveGenerator: proposal target is outside the candidate worktree')\n }\n}\n\nfunction applyPatches(edits: SurfaceImprovementEdit[], cwd: string): void {\n // Git applies the complete batch atomically unless --reject is requested.\n const result = spawnSync('git', ['apply', '-p0', '-'], {\n cwd,\n input: edits.map((edit) => `${edit.patch.trimEnd()}\\n`).join(''),\n encoding: 'utf-8',\n })\n if (result.error) throw result.error\n if (result.status !== 0) {\n throw new Error(`reflectiveGenerator: patch batch failed: ${result.stderr.trim()}`)\n }\n}\n","import type {\n AgentImprovementActivationOutcome,\n AgentImprovementActivationResult,\n AgentImprovementActivationTarget,\n Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { sha256DigestSchema } from '@tangle-network/agent-interface'\nimport {\n fromAgentCandidateKnowledgeRef,\n type KnowledgeImprovementMutationReceipt,\n loadKnowledgeImprovementActivationResult,\n type PromoteKnowledgeCandidateOptions,\n promoteKnowledgeCandidate,\n restoreKnowledgeCandidateBaseline,\n} from '@tangle-network/agent-knowledge'\n\nimport {\n type AgentImprovementActivationReconciliation,\n type AgentImprovementActivationResultStore,\n type AgentImprovementActivationTransition,\n type AgentImprovementActivationTransitionInput,\n createAgentImprovementActivationResult,\n} from '../intelligence/activation'\n\nexport interface CreateKnowledgeImprovementActivationExecutorOptions\n extends Omit<PromoteKnowledgeCandidateOptions, 'root' | 'candidate'> {\n root: string\n identity: string\n results: AgentImprovementActivationResultStore\n}\n\nexport interface KnowledgeImprovementActivationExecutor {\n transition: AgentImprovementActivationTransition\n reconcile: AgentImprovementActivationReconciliation\n}\n\n/** Apply or restore one local knowledge candidate through the shared activation contract. */\nexport function createKnowledgeImprovementActivationExecutor(\n options: CreateKnowledgeImprovementActivationExecutorOptions,\n): KnowledgeImprovementActivationExecutor {\n if (!options.identity.trim()) throw new Error('knowledge activation identity is required')\n return {\n reconcile: async (transition) => {\n const inspected = await inspectKnowledgeActivation(options, transition)\n return inspected.settled ? inspected.result : undefined\n },\n transition: async (transition) => {\n if (transition.expired) {\n throw new Error('knowledge write transition cannot run after authorization expires')\n }\n const inspected = await inspectKnowledgeActivation(options, transition)\n if (inspected.settled) return inspected.result\n\n const mutationOptions = {\n root: options.root,\n candidate: inspected.candidate,\n activation: {\n activation: transition.activation,\n attemptedAt: transition.attemptedAt,\n identity: options.identity,\n createResult: (receipt: KnowledgeImprovementMutationReceipt) =>\n inspected.create(\n knowledgeMutationOutcome(receipt, inspected, transition.activation.intent),\n ),\n },\n ...(options.ownerId ? { ownerId: options.ownerId } : {}),\n ...(options.leaseTtlMs === undefined ? {} : { leaseTtlMs: options.leaseTtlMs }),\n ...(options.now ? { now: options.now } : {}),\n ...(options.onState ? { onState: options.onState } : {}),\n }\n const improvement =\n transition.activation.intent === 'activate-candidate'\n ? await promoteKnowledgeCandidate(mutationOptions)\n : await restoreKnowledgeCandidateBaseline(mutationOptions)\n if (!improvement.activationResult) {\n throw new Error('knowledge mutation did not persist its shared activation result')\n }\n return options.results.putIfAbsent(improvement.activationResult)\n },\n }\n}\n\ntype CreateKnowledgeActivation = (\n outcome: AgentImprovementActivationOutcome,\n) => AgentImprovementActivationResult\n\ntype InspectedKnowledgeActivation =\n | { settled: true; result: unknown | undefined }\n | {\n settled: false\n target: AgentImprovementActivationTransitionInput['targets'][number]\n candidate: PromoteKnowledgeCandidateOptions['candidate']\n expectedDigest: Sha256Digest\n desiredDigest: Sha256Digest\n create: CreateKnowledgeActivation\n }\n\nasync function inspectKnowledgeActivation(\n options: CreateKnowledgeImprovementActivationExecutorOptions,\n transition: AgentImprovementActivationTransitionInput,\n): Promise<InspectedKnowledgeActivation> {\n const stored = await options.results.load(transition.activation.digest)\n if (stored !== undefined) return { settled: true, result: stored }\n\n const create: CreateKnowledgeActivation = (outcome) =>\n createAgentImprovementActivationResult(transition, {\n completedAt: completionTime(transition, options.now),\n outcome,\n })\n const store = (outcome: AgentImprovementActivationOutcome) =>\n options.results.putIfAbsent(create(outcome))\n if (transition.kind !== 'sealed-candidate') {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_PROFILE_TRANSITION_UNSUPPORTED',\n message: 'The knowledge adapter accepts only sealed knowledge candidates.',\n }),\n }\n }\n const target = supportedKnowledgeTarget(transition, options.identity)\n if (!target) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_TARGET_SET_UNSUPPORTED',\n message: 'The knowledge adapter requires exactly one matching knowledge target.',\n }),\n }\n }\n const knowledge = transition.candidateBundle.knowledge\n if (!knowledge) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_CANDIDATE_MISSING',\n message: 'The measured candidate bundle does not contain a knowledge candidate.',\n }),\n }\n }\n const candidate = fromAgentCandidateKnowledgeRef(knowledge.candidate)\n const expectedDigest =\n transition.activation.intent === 'activate-candidate'\n ? knowledge.candidate.baseHash\n : knowledge.candidate.candidateHash\n const desiredDigest =\n transition.activation.intent === 'activate-candidate'\n ? knowledge.candidate.candidateHash\n : knowledge.candidate.baseHash\n if (target.expectedBaseDigest !== expectedDigest || target.desiredDigest !== desiredDigest) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'failed',\n code: 'KNOWLEDGE_TARGET_MISMATCH',\n message: 'The activation target does not match the measured knowledge candidate.',\n }),\n }\n }\n\n const durable = await loadKnowledgeImprovementActivationResult({\n root: options.root,\n candidate,\n activation: transition.activation,\n identity: options.identity,\n })\n if (durable) {\n return {\n settled: true,\n result: await options.results.putIfAbsent(durable),\n }\n }\n if (transition.expired) return { settled: true, result: undefined }\n return { settled: false, target, candidate, expectedDigest, desiredDigest, create }\n}\n\nfunction supportedKnowledgeTarget(\n transition: AgentImprovementActivationTransitionInput,\n identity: string,\n): AgentImprovementActivationTransitionInput['targets'][number] | undefined {\n if (transition.targets.length !== 1) return undefined\n const target = transition.targets[0]\n return target.surface === 'knowledge' && target.identity === identity ? target : undefined\n}\n\nfunction knowledgeMutationOutcome(\n receipt: KnowledgeImprovementMutationReceipt,\n inspected: Extract<InspectedKnowledgeActivation, { settled: false }>,\n intent: AgentImprovementActivationTransitionInput['activation']['intent'],\n): AgentImprovementActivationOutcome {\n const expectedTarget = intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const beforeDigest = prefixedDigest(receipt.beforeHash)\n const afterDigest = prefixedDigest(receipt.afterHash)\n if (\n receipt.target !== expectedTarget ||\n receipt.changed !== (beforeDigest !== afterDigest) ||\n (!receipt.changed && (receipt.transactionId !== null || receipt.recovered))\n ) {\n throw new Error('knowledge mutation returned inconsistent state evidence')\n }\n if (receipt.changed) {\n if (\n receipt.transactionId === null ||\n beforeDigest !== inspected.expectedDigest ||\n afterDigest !== inspected.desiredDigest\n ) {\n throw new Error('knowledge activation did not apply its authorized content transition')\n }\n return {\n status: 'applied',\n transactionId: receipt.transactionId,\n targets: [\n {\n surface: inspected.target.surface,\n identity: inspected.target.identity,\n beforeDigest,\n afterDigest,\n },\n ],\n }\n }\n if (afterDigest === inspected.desiredDigest) {\n return {\n status: 'already-applied',\n targets: [targetState(inspected.target, afterDigest)],\n }\n }\n if (afterDigest === inspected.expectedDigest) {\n throw new Error('knowledge activation did not attempt its authorized content transition')\n }\n return {\n status: 'conflict',\n targets: [targetState(inspected.target, afterDigest)],\n }\n}\n\nfunction targetState(target: AgentImprovementActivationTarget, currentDigest: Sha256Digest) {\n return {\n surface: target.surface,\n identity: target.identity,\n currentDigest,\n }\n}\n\nfunction prefixedDigest(hash: string): Sha256Digest {\n return sha256DigestSchema.parse(`sha256:${hash}`)\n}\n\nfunction completionTime(\n transition: AgentImprovementActivationTransitionInput,\n now: (() => Date) | undefined,\n): string {\n const completedAt = (now ?? (() => new Date()))().toISOString()\n return Date.parse(completedAt) < Date.parse(transition.attemptedAt)\n ? transition.attemptedAt\n : completedAt\n}\n","import { agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { RagKnowledgeUpdateResult } from '@tangle-network/agent-knowledge'\nimport type { DeliverableSpec } from '../runtime/supervise/completion-gate'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type { ExecutorConfig } from '../runtime/supervise/runtime'\nimport { type SuperviseOptions, supervise } from '../runtime/supervise/supervise'\nimport type { SupervisorProfile } from '../runtime/supervise/supervisor-agent'\nimport type { Budget, SupervisedResult } from '../runtime/supervise/types'\n\n/** Standing prompt for a supervisor that grows a shared knowledge base through spawned researchers. */\nexport const RESEARCH_SUPERVISOR_SYSTEM_PROMPT = [\n 'You are a research supervisor. You do not answer the research question yourself.',\n 'You create and manage researcher workers that improve one shared knowledge base until it is ready.',\n '',\n 'Each round:',\n '1. Read the goal and the gaps the readiness check still reports.',\n '2. Decompose the open work into independent sub-topics.',\n '3. Spawn one researcher per sub-topic; split by sub-topic, never duplicate work.',\n '4. Wait for researchers to settle, steer or re-spawn thin sub-topics, then stop when the check passes.',\n '',\n 'Conserve the shared budget. Prefer a small number of well-scoped researchers over a large fanout that re-covers the same ground.',\n].join('\\n')\n\nexport interface KnowledgeReadinessCheckInput {\n root: string\n goal: string\n readinessSpecs?: readonly unknown[]\n readinessTaskId?: string\n readiness?: unknown\n}\n\nexport type KnowledgeReadinessCheckResult =\n | boolean\n | {\n ready: boolean\n summary?: string\n metadata?: Record<string, unknown>\n }\n\nexport type KnowledgeReadinessCheck = (\n input: KnowledgeReadinessCheckInput,\n) => Promise<KnowledgeReadinessCheckResult> | KnowledgeReadinessCheckResult\n\nexport interface SupervisedKnowledgeUpdateInput {\n goal?: string\n root?: string\n candidateRoot?: string\n findings?: readonly unknown[]\n metadata?: Record<string, unknown>\n}\n\nexport interface SupervisedKnowledgeUpdateResult {\n applied: boolean\n summary: string\n supervised: SupervisedResult<unknown>\n metadata: NonNullable<RagKnowledgeUpdateResult['metadata']>\n}\n\nexport interface SupervisedKnowledgeUpdateOptions {\n root: string\n goal: string\n readiness: KnowledgeReadinessCheck\n readinessSpecs?: readonly unknown[]\n readinessTaskId?: string\n readinessOptions?: unknown\n findings?: readonly unknown[]\n metadata?: Record<string, unknown>\n budget: Budget\n backend?: ExecutorConfig\n makeWorkerAgent?: SuperviseOptions['makeWorkerAgent']\n /** Caller-owned exact supervisor harness/provider/model identity. */\n supervisorProfile: SupervisorProfile\n superviseOptions?: Partial<\n Omit<\n SuperviseOptions,\n 'budget' | 'backend' | 'deliverable' | 'makeWorkerAgent' | 'allowedModels'\n >\n >\n allowedModels?: readonly string[]\n runSupervised?: (\n profile: SupervisorProfile,\n task: unknown,\n opts: SuperviseOptions,\n ) => Promise<SupervisedResult<unknown>>\n}\n\nexport type SupervisedKnowledgeUpdater = (\n input: SupervisedKnowledgeUpdateInput,\n) => Promise<SupervisedKnowledgeUpdateResult>\n\n/** Build the completion check a supervised KB update uses to stop only when the KB is ready. */\nexport function knowledgeReadinessDeliverable(\n options: Pick<\n SupervisedKnowledgeUpdateOptions,\n 'root' | 'goal' | 'readiness' | 'readinessSpecs' | 'readinessTaskId' | 'readinessOptions'\n >,\n): DeliverableSpec<unknown> {\n return {\n describe: `knowledge base at ${options.root} is ready for: ${options.goal}`,\n async check() {\n const result = await options.readiness({\n root: options.root,\n goal: options.goal,\n readinessSpecs: options.readinessSpecs,\n readinessTaskId: options.readinessTaskId,\n readiness: options.readinessOptions,\n })\n return typeof result === 'boolean' ? result : result.ready\n },\n }\n}\n\n/** Create an `improveKnowledgeBase` update callback backed by runtime supervision. */\nexport function createSupervisedKnowledgeUpdater(\n options: SupervisedKnowledgeUpdateOptions,\n): SupervisedKnowledgeUpdater {\n return (input) =>\n runSupervisedKnowledgeUpdate({\n ...options,\n root: input.candidateRoot ?? input.root ?? options.root,\n goal: input.goal ?? options.goal,\n findings: input.findings ?? options.findings,\n metadata: { ...options.metadata, ...input.metadata },\n })\n}\n\n/** Run a runtime supervisor that updates one candidate knowledge base and stops on readiness. */\nexport async function runSupervisedKnowledgeUpdate(\n options: SupervisedKnowledgeUpdateOptions,\n): Promise<SupervisedKnowledgeUpdateResult> {\n const exactSupervisor = agentProfileSchema.parse(options.supervisorProfile) as SupervisorProfile\n assertExecutableAgentProfile(exactSupervisor, 'runSupervisedKnowledgeUpdate')\n const run = options.runSupervised ?? supervise\n const task = formatSupervisedKnowledgeTask(options)\n const supervised = await run(exactSupervisor, task, {\n ...options.superviseOptions,\n budget: options.budget,\n backend: options.backend,\n deliverable: knowledgeReadinessDeliverable(options),\n makeWorkerAgent: options.makeWorkerAgent,\n allowedModels: options.allowedModels,\n })\n return {\n applied: supervised.kind === 'winner',\n summary:\n supervised.kind === 'winner'\n ? 'research supervisor completed and the knowledge base passed readiness'\n : `research supervisor stopped without a ready knowledge base: ${supervised.reason}`,\n supervised,\n metadata: {\n supervised: true,\n root: options.root,\n goal: options.goal,\n result: supervised.kind,\n },\n }\n}\n\n/** Format the supervisor task with the KB root, readiness requirements, current findings, and metadata. */\nexport function formatSupervisedKnowledgeTask(\n options: Pick<\n SupervisedKnowledgeUpdateOptions,\n 'root' | 'goal' | 'readinessSpecs' | 'readinessTaskId' | 'findings' | 'metadata'\n >,\n): string {\n const sections = [\n `Goal: ${options.goal}`,\n `Knowledge base root: ${options.root}`,\n options.readinessTaskId ? `Readiness task id: ${options.readinessTaskId}` : undefined,\n options.readinessSpecs?.length\n ? `Readiness specs:\\n${JSON.stringify(options.readinessSpecs, null, 2)}`\n : undefined,\n options.findings?.length\n ? `Current findings:\\n${JSON.stringify(options.findings, null, 2)}`\n : undefined,\n options.metadata && Object.keys(options.metadata).length > 0\n ? `Metadata:\\n${JSON.stringify(options.metadata, null, 2)}`\n : undefined,\n ].filter((section): section is string => Boolean(section))\n return `${sections.join('\\n\\n')}\\n\\nUpdate files under the knowledge base root only. Stop when the readiness check passes.`\n}\n","import { realpath } from 'node:fs/promises'\nimport {\n type AgentCandidateBundle,\n type AgentCandidateCapturedArtifact,\n type AgentCandidateKnowledge,\n agentCandidateKnowledgeSchema,\n} from '@tangle-network/agent-interface'\nimport {\n type BuildEvalKnowledgeBundleOptions,\n evaluateKnowledgeBaseReadiness,\n improveKnowledgeBase,\n type KnowledgeBaseQualityOptions,\n type KnowledgeImprovementOptions,\n type KnowledgeImprovementResult,\n type KnowledgeReadinessSpec,\n knowledgeImprovementCandidateRef,\n normalizeKnowledgeStateScope,\n toAgentCandidateKnowledgeRef,\n withKnowledgeImprovementComparison,\n} from '@tangle-network/agent-knowledge'\nimport { sealAgentCandidateBundle } from '../candidate-execution/bundle'\nimport {\n canonicalCandidateBytes,\n embeddedCandidateArtifact,\n omitTopLevelDigest,\n} from '../candidate-execution/digest'\nimport { persistCandidateOutputArtifact } from '../candidate-execution/output-artifacts'\nimport type { AgentCandidateOutputArtifactPort } from '../candidate-execution/types'\nimport { captureAgentCandidateWorkspace } from '../candidate-execution/workspace-archive'\nimport type { ExecutorConfig } from '../runtime/supervise/runtime'\nimport type { SuperviseOptions } from '../runtime/supervise/supervise'\nimport type { SupervisorProfile } from '../runtime/supervise/supervisor-agent'\nimport type { Budget, SupervisedResult } from '../runtime/supervise/types'\nimport {\n createSupervisedKnowledgeUpdater,\n type KnowledgeReadinessCheck,\n type KnowledgeReadinessCheckResult,\n type SupervisedKnowledgeUpdateOptions,\n} from './supervised-update'\n\nexport interface RunKnowledgeImprovementJobOptions\n extends Omit<KnowledgeImprovementOptions, 'updateKnowledge'> {\n budget: Budget\n readinessCheck?: KnowledgeReadinessCheck\n backend?: ExecutorConfig\n makeWorkerAgent?: SuperviseOptions['makeWorkerAgent']\n supervisorProfile: SupervisorProfile\n superviseOptions?: Partial<\n Omit<\n SuperviseOptions,\n 'budget' | 'backend' | 'deliverable' | 'makeWorkerAgent' | 'allowedModels'\n >\n >\n allowedModels?: readonly string[]\n runSupervised?: (\n profile: SupervisorProfile,\n task: unknown,\n opts: SuperviseOptions,\n ) => Promise<SupervisedResult<unknown>>\n candidateArtifacts?: AgentCandidateOutputArtifactPort\n onMeasurement?: (measurement: KnowledgeImprovementJobMeasurement) => Promise<void> | void\n}\n\nexport interface KnowledgeImprovementJobMeasurement {\n startedAt: string\n finishedAt: string\n durationMs: number\n updateCalls: number\n updateDurationMs: number\n supervisedSpent: {\n iterations: number\n inputTokens: number\n outputTokens: number\n usdKnown: boolean\n usd: number\n ms: number\n }\n}\n\nexport interface KnowledgeImprovementJobResult {\n improvement: KnowledgeImprovementResult\n knowledge?: KnowledgeImprovementCandidatePair\n measurement: KnowledgeImprovementJobMeasurement\n blocked: boolean\n}\n\nexport interface KnowledgeImprovementCandidatePair {\n reference: AgentCandidateKnowledge['candidate']\n stateScope?: AgentCandidateKnowledge['stateScope']\n evaluation: AgentCandidateCapturedArtifact\n baseline: AgentCandidateKnowledge['snapshot']\n candidate: AgentCandidateKnowledge['snapshot']\n}\n\nexport interface KnowledgeImprovementExperimentBundles {\n baseline: AgentCandidateBundle\n candidate: AgentCandidateBundle\n}\n\nexport interface AgentKnowledgeReadinessCheckOptions {\n goal: string\n readinessSpecs?: readonly KnowledgeReadinessSpec[]\n readinessTaskId?: string\n readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>\n strict?: boolean\n kbQuality?: KnowledgeBaseQualityOptions\n}\n\n/** Build the default readiness check backed by `@tangle-network/agent-knowledge` validation and scoring. */\nexport function createAgentKnowledgeReadinessCheck(\n options: AgentKnowledgeReadinessCheckOptions,\n): KnowledgeReadinessCheck {\n return async (input): Promise<KnowledgeReadinessCheckResult> => {\n const readiness = await evaluateKnowledgeBaseReadiness({\n root: input.root,\n goal: input.goal ?? options.goal,\n readinessSpecs:\n (input.readinessSpecs as readonly KnowledgeReadinessSpec[] | undefined) ??\n options.readinessSpecs,\n readinessTaskId: input.readinessTaskId ?? options.readinessTaskId,\n readiness:\n (input.readiness as AgentKnowledgeReadinessCheckOptions['readiness'] | undefined) ??\n options.readiness,\n strict: options.strict,\n kbQuality: options.kbQuality,\n })\n return {\n ready: readiness.ready,\n summary: readiness.summary,\n metadata: {\n dimensions: readiness.dimensions,\n validationOk: readiness.validation.ok,\n kbQualityOk: readiness.kbQuality.ok,\n blockingMissing: readiness.readiness?.report.blockingMissingRequirements.length ?? 0,\n },\n }\n }\n}\n\n/** Produce a frozen KB candidate while leaving live knowledge content unchanged. */\nexport async function runKnowledgeImprovementJob(\n options: RunKnowledgeImprovementJobOptions,\n): Promise<KnowledgeImprovementJobResult> {\n const {\n allowedModels,\n backend,\n budget,\n candidateArtifacts,\n makeWorkerAgent,\n onMeasurement,\n readinessCheck,\n runSupervised,\n supervisorProfile,\n superviseOptions,\n ...knowledgeOptions\n } = options\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const supervisedSpent = emptySpent()\n let updateCalls = 0\n let updateDurationMs = 0\n\n const readiness = readinessCheck ?? createAgentKnowledgeReadinessCheck(options)\n const updateKnowledge = createSupervisedKnowledgeUpdater({\n root: options.root,\n goal: options.goal,\n readiness,\n readinessSpecs: options.readinessSpecs,\n readinessTaskId: options.readinessTaskId,\n readinessOptions: options.readiness,\n budget,\n backend,\n makeWorkerAgent,\n supervisorProfile,\n superviseOptions,\n allowedModels,\n runSupervised,\n } satisfies SupervisedKnowledgeUpdateOptions)\n\n const instrumentedUpdateKnowledge: KnowledgeImprovementOptions['updateKnowledge'] = async (\n input,\n ) => {\n const updateStartedAt = Date.now()\n updateCalls += 1\n const result = await updateKnowledge(input)\n updateDurationMs += Date.now() - updateStartedAt\n addSpent(supervisedSpent, result.supervised)\n return result\n }\n const resolvedImprovement = await improveKnowledgeBase({\n ...knowledgeOptions,\n updateKnowledge: instrumentedUpdateKnowledge,\n })\n let knowledge: KnowledgeImprovementCandidatePair | undefined\n if (\n resolvedImprovement.candidate?.status === 'candidate-ready' ||\n resolvedImprovement.candidate?.status === 'promoted'\n ) {\n knowledge = await freezeKnowledgeCandidatePair(\n options.root,\n resolvedImprovement,\n candidateArtifacts,\n knowledgeOptions.signal,\n )\n }\n const finishedAtMs = Date.now()\n const measurement: KnowledgeImprovementJobMeasurement = {\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n durationMs: finishedAtMs - startedAtMs,\n updateCalls,\n updateDurationMs,\n supervisedSpent,\n }\n await onMeasurement?.(measurement)\n return {\n improvement: resolvedImprovement,\n ...(knowledge ? { knowledge } : {}),\n measurement,\n blocked: resolvedImprovement.blocked,\n }\n}\n\n/** Attach both frozen knowledge inputs to one otherwise-identical bundle pair. */\nexport function buildKnowledgeImprovementExperimentBundles(\n bundle: AgentCandidateBundle,\n knowledge: KnowledgeImprovementCandidatePair,\n): KnowledgeImprovementExperimentBundles {\n const input = omitTopLevelDigest(bundle)\n const withSnapshot = (snapshot: AgentCandidateKnowledge['snapshot']) =>\n agentCandidateKnowledgeSchema.parse({\n candidate: knowledge.reference,\n ...(knowledge.stateScope ? { stateScope: knowledge.stateScope } : {}),\n snapshot,\n evaluation: knowledge.evaluation,\n })\n return Object.freeze({\n baseline: sealAgentCandidateBundle({ ...input, knowledge: withSnapshot(knowledge.baseline) }),\n candidate: sealAgentCandidateBundle({ ...input, knowledge: withSnapshot(knowledge.candidate) }),\n })\n}\n\nasync function freezeKnowledgeCandidatePair(\n root: string,\n improvement: KnowledgeImprovementResult,\n artifacts: AgentCandidateOutputArtifactPort | undefined,\n signal: AbortSignal | undefined,\n): Promise<KnowledgeImprovementCandidatePair> {\n const candidate = knowledgeImprovementCandidateRef(improvement)\n const candidateRef = toAgentCandidateKnowledgeRef(candidate)\n return withKnowledgeImprovementComparison({ root, candidate }, async (comparison) => {\n const freeze = async (\n target: 'baseline' | 'candidate',\n ): Promise<AgentCandidateKnowledge['snapshot']> => {\n const executionId = `knowledge-${candidate.candidateId}-${target}`\n const captured = await captureAgentCandidateWorkspace(\n await realpath(comparison[target].root),\n {\n ...(artifacts\n ? {\n artifactPersistence: {\n executionId,\n outputArtifacts: artifacts,\n ...(signal ? { signal } : {}),\n },\n }\n : {}),\n },\n )\n return captured.snapshot\n }\n const evaluation = await captureKnowledgeEvidence(\n canonicalCandidateBytes({\n kind: 'agent-knowledge-candidate-evaluation',\n candidate: candidateRef,\n metric: comparison.evaluation,\n }),\n 'knowledge-evaluation',\n `knowledge-${candidate.candidateId}`,\n artifacts,\n signal,\n )\n const normalizedScope = normalizeKnowledgeStateScope(comparison.stateScope)\n const defaultScope = normalizeKnowledgeStateScope()\n const stateScope =\n normalizedScope.pagesDirectory === defaultScope.pagesDirectory &&\n normalizedScope.researchState === defaultScope.researchState\n ? undefined\n : Object.freeze(normalizedScope)\n const baseline = await freeze('baseline')\n const proposed = await freeze('candidate')\n return Object.freeze({\n reference: candidateRef,\n ...(stateScope ? { stateScope } : {}),\n evaluation,\n baseline,\n candidate: proposed,\n })\n })\n}\n\nasync function captureKnowledgeEvidence(\n bytes: Uint8Array,\n purpose: 'knowledge-evaluation',\n executionId: string,\n artifacts: AgentCandidateOutputArtifactPort | undefined,\n signal: AbortSignal | undefined,\n): Promise<AgentCandidateCapturedArtifact> {\n if (!artifacts) return embeddedCandidateArtifact(bytes)\n return persistCandidateOutputArtifact(artifacts, {\n executionId,\n purpose,\n bytes,\n ...(signal ? { signal } : {}),\n })\n}\n\n/** The starting accumulator, before any supervised run has been folded in. Zero iterations means\n * nothing ran, so a zero dollar total IS the measured amount; `addSpent` lowers `usdKnown` as\n * soon as it folds a run whose own dollars were not proven. */\nfunction emptySpent(): KnowledgeImprovementJobMeasurement['supervisedSpent'] {\n return { iterations: 0, inputTokens: 0, outputTokens: 0, usdKnown: true, usd: 0, ms: 0 }\n}\n\nfunction addSpent(\n target: KnowledgeImprovementJobMeasurement['supervisedSpent'],\n result: SupervisedResult<unknown>,\n): void {\n const spent = result.spentTotal\n target.iterations += spent.iterations\n target.inputTokens += spent.tokens.input\n target.outputTokens += spent.tokens.output\n target.usdKnown = target.usdKnown && spent.usdKnown !== false\n target.usd += spent.usd\n target.ms += spent.ms\n}\n","/**\n *\n * Chat-model resolution + catalog validation — the shared primitive every\n * product chat handler needs and was, until now, hand-rolling. Lifts the\n * router `/v1/models` fetch, the fail-closed id validation, and the\n * precedence resolver out of four near-identical per-repo copies.\n *\n * Policy-free by design: callers pass their own precedence order\n * (`resolveChatModel`) and their own known-good `allowlist`\n * (`validateChatModelId`), so each product keeps its resolution policy while\n * sharing the catalog fetch, the malformed-id guard, and the fail-closed\n * admission rule. No React, no `process.env` assumption — `env` is an\n * explicit narrow record so this runs unchanged in Node and in Workers.\n *\n * @stable\n */\n\n/**\n * A model entry as returned by the Tangle Router `/v1/models` endpoint.\n * Intentionally minimal — only the fields resolution + validation read.\n */\nexport interface ModelInfo {\n id: string\n name?: string\n description?: string\n /** Provider slug, when the router exposes it (`provider` or `_provider`). */\n provider?: string\n _provider?: string\n architecture?: {\n modality?: string\n input_modalities?: string[]\n output_modalities?: string[]\n }\n}\n\n/** Env keys the router base URL is resolved from. */\nexport interface RouterEnv {\n TANGLE_ROUTER_URL?: string\n TANGLE_ROUTER_BASE_URL?: string\n}\n\n/** Default Tangle Router base URL used when no env override is set. */\nexport const DEFAULT_ROUTER_BASE_URL = 'https://router.tangle.tools'\n\n/** Resolve the router base URL from env, normalised — no trailing `/v1` or `/`. */\nexport function resolveRouterBaseUrl(env: RouterEnv = {}): string {\n return (env.TANGLE_ROUTER_URL ?? env.TANGLE_ROUTER_BASE_URL ?? DEFAULT_ROUTER_BASE_URL)\n .replace(/\\/v1\\/?$/, '')\n .replace(/\\/$/, '')\n}\n\n/**\n * Fetch the model catalog from the router's `/v1/models`. Throws on a non-2xx\n * response — callers decide whether to fail open (empty catalog) or closed.\n */\nexport async function getModels(\n routerBaseUrl: string = DEFAULT_ROUTER_BASE_URL,\n): Promise<ModelInfo[]> {\n const res = await fetch(`${routerBaseUrl}/v1/models`, {\n headers: { Accept: 'application/json' },\n })\n if (!res.ok) throw new Error(`router /v1/models ${res.status}`)\n const body = (await res.json()) as { data?: ModelInfo[] }\n return Array.isArray(body.data) ? body.data : []\n}\n\n/** Trim a candidate model id; `undefined` for non-strings and blanks. */\nexport function cleanModelId(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nexport interface ChatModelCandidate {\n /** Stable label for telemetry — e.g. `request`, `workspace`, `env`. */\n source: string\n model: string | undefined\n}\n\nexport interface ResolvedChatModel {\n source: string\n model: string\n}\n\n/**\n * Resolve a chat model by precedence: the first candidate carrying a\n * non-blank model wins, else `fallback`. The caller owns the precedence\n * order, so each product keeps its own policy (request → workspace → env,\n * etc.) while the first-non-blank logic and the telemetry shape stay shared.\n */\nexport function resolveChatModel(\n candidates: ChatModelCandidate[],\n fallback: ResolvedChatModel,\n): ResolvedChatModel {\n for (const candidate of candidates) {\n const model = cleanModelId(candidate.model)\n if (model) return { source: candidate.source, model }\n }\n return fallback\n}\n\nexport type ChatModelValidation =\n | { succeeded: true; value: string }\n | { succeeded: false; error: string }\n\nconst WELL_FORMED_MODEL_ID = /^[A-Za-z0-9._/@:-]+$/\n\nfunction isWellFormedModelId(modelId: string): boolean {\n return modelId.length <= 200 && WELL_FORMED_MODEL_ID.test(modelId)\n}\n\n/**\n * Every id a catalog entry can be addressed by — its bare id, plus a\n * `provider/id` form when the router exposes a separate provider slug.\n */\nfunction catalogIdsForModel(model: ModelInfo): string[] {\n const ids = new Set<string>()\n const id = cleanModelId(model.id)\n if (id) ids.add(id)\n const provider = cleanModelId(model._provider) ?? cleanModelId(model.provider)\n if (provider && id && !id.includes('/')) ids.add(`${provider}/${id}`)\n return [...ids]\n}\n\n/**\n * Validate a caller-supplied chat-model id. Rejects non-strings, malformed\n * ids, and ids absent from both the caller's `allowlist` and the live router\n * catalog. Fails closed: when the catalog cannot be fetched, an unverifiable\n * id is rejected rather than admitted — a bad model never reaches the agent.\n */\nexport async function validateChatModelId(\n modelId: unknown,\n options: {\n /**\n * Known-good ids that skip the catalog round trip — e.g. the product's\n * default model plus any env-configured ids.\n */\n allowlist?: string[]\n routerBaseUrl?: string\n /** Injectable catalog loader — overridden in tests. */\n loadModels?: (routerBaseUrl: string) => Promise<ModelInfo[]>\n } = {},\n): Promise<ChatModelValidation> {\n const {\n allowlist = [],\n routerBaseUrl = DEFAULT_ROUTER_BASE_URL,\n loadModels = getModels,\n } = options\n\n const cleaned = cleanModelId(modelId)\n if (!cleaned) return { succeeded: false, error: 'Model id must be a non-empty string.' }\n if (!isWellFormedModelId(cleaned)) {\n return { succeeded: false, error: `Model id is malformed: ${cleaned}` }\n }\n if (allowlist.some((id) => cleanModelId(id) === cleaned)) {\n return { succeeded: true, value: cleaned }\n }\n\n let catalog: ModelInfo[]\n try {\n catalog = await loadModels(routerBaseUrl)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { succeeded: false, error: `Could not validate model catalog: ${message}` }\n }\n\n const ids = new Set(catalog.flatMap(catalogIdsForModel))\n if (!ids.has(cleaned)) return { succeeded: false, error: `Model is not available: ${cleaned}` }\n return { succeeded: true, value: cleaned }\n}\n","/**\n *\n * Pure readiness-decision helper. Maps a `KnowledgeReadinessReport` from\n * `@tangle-network/agent-eval` to a three-state branch (`ready` / `blocked` /\n * `caveat`) the runtime, route handlers, and UI shells can all switch on.\n *\n * Default `minimumScore` of 0.7 mirrors the readiness scoring scale in\n * agent-eval; callers tightening or loosening this should keep it consistent\n * across all entry points for the same product so the UI / metrics agree on\n * what \"caveat\" means.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { ValidationError } from './errors'\nimport type { KnowledgeReadinessDecision } from './types'\n\nconst DEFAULT_MINIMUM_READINESS_SCORE = 0.7\n\n/**\n * Map a `KnowledgeReadinessReport` to a three-state branch (`ready` / `blocked` / `caveat`) the runtime, route handlers, and UI shells all switch on.\n *\n * @stable\n */\nexport function decideKnowledgeReadiness(\n report: KnowledgeReadinessReport,\n options: { minimumScore?: number } = {},\n): KnowledgeReadinessDecision {\n const minimumScore = options.minimumScore ?? DEFAULT_MINIMUM_READINESS_SCORE\n if (!Number.isFinite(minimumScore) || minimumScore < 0 || minimumScore > 1) {\n throw new ValidationError(\n `minimumScore must be a finite number in [0, 1]; received ${String(minimumScore)}`,\n )\n }\n const blockingGapIds = report.blockingMissingRequirements.map((requirement) => requirement.id)\n const nonBlockingGapIds = report.nonBlockingGaps.map((requirement) => requirement.id)\n if (blockingGapIds.length > 0) {\n return {\n passed: false,\n status: 'blocked',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n if (report.readinessScore < minimumScore) {\n return {\n passed: false,\n status: 'caveat',\n reason: `Knowledge readiness score ${report.readinessScore.toFixed(3)} is below minimum ${minimumScore.toFixed(3)}.`,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n return {\n passed: true,\n status: 'ready',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n}\n","/**\n *\n * The two top-level entry points:\n *\n * - `runAgentTask` — single-shot lifecycle for adapter-driven tasks.\n * - `runAgentTaskStream` — streaming lifecycle that delegates execution to an\n * `AgentExecutionBackend` (model API, sandbox, or custom iterable).\n *\n * Both gate the run on `KnowledgeReadinessReport` from `agent-eval`, emit the\n * same lifecycle event vocabulary (under different shapes — see `types.ts`),\n * and route session lifecycle through a pluggable `RuntimeSessionStore`.\n *\n * @stable\n */\n\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n FAILURE_CLASSES,\n type FailureClass,\n type KnowledgeReadinessReport,\n type RunRecord,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nconst FAILURE_CLASS_SET = new Set<string>(FAILURE_CLASSES)\n\n/** True when a free-form control failure string is a canonical taxonomy\n * class — so only real taxonomy tags are promoted to the cross-agent\n * `RunRecord.failureClass` key; novel strings stay as `failureMode` detail. */\nfunction asFailureClass(value: string | undefined): FailureClass | undefined {\n return value && FAILURE_CLASS_SET.has(value) ? (value as FailureClass) : undefined\n}\n\n/** Stamp cross-cutting defaults onto adapter-projected RunRecords without\n * overriding anything the adapter set explicitly:\n * - `scenarioId` — the run's scenario, when the record omits one.\n * - `failureClass` — the control layer's failure classification promoted\n * onto the canonical cross-agent key, but ONLY when it's a real taxonomy\n * class. This is what lets the substrate aggregate failures across every\n * agent in one vocabulary instead of per-agent ad-hoc strings. */\nexport function applyRunRecordDefaults(\n records: RunRecord[],\n scenarioId: string,\n controlFailureClass: string | undefined,\n): RunRecord[] {\n const fc = asFailureClass(controlFailureClass)\n return records.map((record) => {\n let r = record\n if (r.scenarioId === undefined) r = { ...r, scenarioId }\n if (r.failureClass === undefined && fc) r = { ...r, failureClass: fc }\n return r\n })\n}\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { BackendTransportError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { nowIso, startOrResumeRuntimeSession, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskSpec,\n AgentTaskStatus,\n BackendErrorDetail,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeStreamEvent,\n} from './types'\n\n/**\n * Single-shot task lifecycle for adapter-driven tasks: readiness-gated, emits the runtime lifecycle event vocabulary, session-store pluggable.\n *\n * @stable\n */\nexport async function runAgentTask<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RunAgentTaskOptions<TState, TAction, TActionResult, TEval>,\n): Promise<AgentTaskRunResult<TState, TAction, TActionResult, TEval>> {\n const task = options.task\n await emit(options.onEvent, { type: 'task_start', task })\n await emit(options.onEvent, { type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflight(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n options.onEvent,\n )\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n await emit(options.onEvent, { type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n }\n\n await emit(options.onEvent, { type: 'control_start', task, knowledge })\n const scenarioId = options.scenarioId ?? task.id\n const control = await runAgentControlLoop<TState, TAction, TActionResult, TEval>({\n intent: task.intent,\n budget: task.budget,\n signal: options.signal,\n store: options.store,\n scenarioId,\n projectId: options.projectId,\n variantId: options.variantId,\n observe: ({ history, abortSignal }) =>\n options.adapter.observe({ task, knowledge, history, abortSignal }),\n validate: async ({ state, history, abortSignal }) => {\n const readinessEval = blockingKnowledgeEval(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n const evals = await options.adapter.validate({\n task,\n knowledge,\n state,\n history,\n abortSignal,\n })\n return [readinessEval as TEval, ...evals]\n },\n decide: (ctx) => {\n if (isKnowledgeBlocked(ctx.evals)) {\n return (\n options.adapter.onKnowledgeBlocked?.({\n task,\n knowledge,\n questions,\n acquisitionPlans,\n }) ?? {\n type: 'stop',\n pass: false,\n score: knowledge.readinessScore,\n reason: `knowledge readiness blocked: ${knowledge.reason}`,\n }\n )\n }\n return options.adapter.decide(toAgentContext(task, knowledge, ctx))\n },\n act: (action, ctx) => options.adapter.act(action, toAgentContext(task, knowledge, ctx)),\n shouldStop: options.adapter.shouldStop\n ? (ctx) => options.adapter.shouldStop!(toAgentContext(task, knowledge, ctx))\n : undefined,\n getActionCostUsd: options.adapter.getActionCostUsd\n ? ({ action, result, state, evals, history }) =>\n options.adapter.getActionCostUsd!({ action, result, task, state, evals, history })\n : undefined,\n onStep: (step) => emit(options.onEvent, { type: 'control_step', task, step }),\n })\n await emit(options.onEvent, { type: 'control_end', task, control })\n const status = statusFromControl(control)\n await emit(options.onEvent, { type: 'task_end', task, status, reason: control.reason })\n\n return {\n task,\n status,\n knowledge,\n questions,\n acquisitionPlans,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n control,\n runRecords: applyRunRecordDefaults(\n options.adapter.projectRunRecords?.(control, task) ?? [],\n scenarioId,\n control.failureClass,\n ),\n }\n}\n\n/**\n * Streaming task lifecycle: delegates execution to an `AgentExecutionBackend` (model API, sandbox, or custom iterable) and yields lifecycle events as they happen.\n *\n * @stable\n */\nexport async function* runAgentTaskStream<TInput extends AgentBackendInput = AgentBackendInput>(\n options: RunAgentTaskStreamOptions<TInput>,\n): AsyncIterable<RuntimeStreamEvent> {\n const task = options.task\n const input = { task, ...(options.input ?? {}) } as TInput\n yield streamEvent({ type: 'task_start', task })\n\n yield streamEvent({ type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflightStream(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n )\n for (const event of preflight.events) yield event\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n yield streamEvent({ type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n }\n const decision = decideKnowledgeReadiness(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n yield streamEvent({ type: 'readiness_end', task, knowledge, decision })\n if (!decision.passed && decision.status === 'blocked') {\n const reason = `knowledge readiness blocked: ${decision.reason}`\n yield streamEvent({ type: 'task_end', task, status: 'blocked', reason })\n yield streamEvent({ type: 'final', task, status: 'blocked', reason })\n return\n }\n\n const store = options.sessionStore\n const opened = await startOrResumeRuntimeSession({\n backend: options.backend,\n input,\n context: { task, knowledge, signal: options.signal },\n store,\n sessionId: options.sessionId,\n resume: options.resume,\n })\n let session = opened.session\n const shouldResume = opened.resumed\n const sessionEvent = streamEvent({\n type: shouldResume ? 'session_resumed' : 'session_created',\n task,\n session,\n })\n await store?.appendEvent?.(session.id, sessionEvent)\n yield sessionEvent\n\n const backendStart = streamEvent({\n type: 'backend_start',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendStart)\n yield backendStart\n\n let finalText = ''\n try {\n for await (const rawEvent of options.backend.stream(opened.input, {\n task,\n knowledge,\n session,\n signal: options.signal,\n })) {\n const event = normalizeBackendStreamEvent(rawEvent, task, session)\n if (event.type === 'text_delta') finalText += event.text\n await store?.appendEvent?.(session.id, event)\n yield event\n }\n const completedStatus: AgentTaskStatus = 'completed'\n session = touchSession({ ...session, status: completedStatus })\n await store?.put(session)\n const backendEnd = streamEvent({\n type: 'backend_end',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendEnd)\n yield backendEnd\n const reason = 'backend completed'\n const taskEnd = streamEvent({ type: 'task_end', task, status: completedStatus, reason })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status: completedStatus,\n reason,\n text: finalText || undefined,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n session = touchSession({ ...session, status: options.signal?.aborted ? 'aborted' : 'failed' })\n await store?.put(session)\n let stopErrorMessage: string | undefined\n try {\n await options.backend.stop?.(session, message)\n } catch (stopErr) {\n stopErrorMessage = stopErr instanceof Error ? stopErr.message : String(stopErr)\n }\n const combinedMessage = stopErrorMessage\n ? `${message}; backend stop failed: ${stopErrorMessage}`\n : message\n // Typed transport detail — preserves status code + truncated body so\n // consumers can map onto `RunRecord.error` without re-parsing the log\n // string. Required by the runtime's fail-loud contract: silent empty\n // output for a 402 / 401 / 5xx hides the real failure mode.\n const errorDetail: BackendErrorDetail =\n err instanceof BackendTransportError\n ? {\n kind: 'transport',\n message: combinedMessage,\n status: err.status,\n body: err.body,\n }\n : { kind: 'backend', message: combinedMessage }\n const backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: combinedMessage,\n recoverable: !options.signal?.aborted,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, backendError)\n yield backendError\n const status: AgentTaskStatus = options.signal?.aborted ? 'aborted' : 'failed'\n const taskEnd = streamEvent({ type: 'task_end', task, status, reason: message })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status,\n reason: message,\n text: finalText || undefined,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n }\n}\n\nasync function runKnowledgePreflight<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n onEvent: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n): Promise<{ userAnswers: Record<string, string>; acquiredEvidenceIds: string[] }> {\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n await emit(onEvent, { type: 'questions_start', task, questions })\n userAnswers = await provider.answerQuestions(questions, task)\n await emit(onEvent, { type: 'questions_end', task, questions, userAnswers })\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n await emit(onEvent, { type: 'acquisition_start', task, acquisitionPlans })\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n await emit(onEvent, {\n type: 'acquisition_end',\n task,\n acquisitionPlans,\n acquiredEvidenceIds,\n })\n }\n return { userAnswers, acquiredEvidenceIds }\n}\n\nasync function runKnowledgePreflightStream(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n): Promise<{\n userAnswers: Record<string, string>\n acquiredEvidenceIds: string[]\n events: RuntimeStreamEvent[]\n}> {\n const events: RuntimeStreamEvent[] = []\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n events.push(streamEvent({ type: 'questions_start', task, questions }))\n userAnswers = await provider.answerQuestions(questions, task)\n events.push(streamEvent({ type: 'questions_end', task, questions, userAnswers }))\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n events.push(streamEvent({ type: 'acquisition_start', task, acquisitionPlans }))\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n events.push(\n streamEvent({ type: 'acquisition_end', task, acquisitionPlans, acquiredEvidenceIds }),\n )\n }\n return { userAnswers, acquiredEvidenceIds, events }\n}\n\nfunction streamEvent<T extends Omit<RuntimeStreamEvent, 'timestamp'>>(\n event: T,\n): T & { timestamp: string } {\n return { ...event, timestamp: nowIso() }\n}\n\nfunction buildReadiness(\n task: AgentTaskSpec,\n provider: AgentKnowledgeProvider | undefined,\n): Promise<KnowledgeReadinessReport> | KnowledgeReadinessReport {\n if (provider?.buildReadiness) return provider.buildReadiness(task)\n return scoreKnowledgeReadiness({\n taskId: task.id,\n requirements: task.requiredKnowledge ?? [],\n metadata: { domain: task.domain, ...task.metadata },\n })\n}\n\nfunction isKnowledgeBlocked(evals: ControlEvalResult[]): boolean {\n return evals.some((evalResult) => evalResult.id === 'knowledge-ready' && !evalResult.passed)\n}\n\nfunction statusFromControl(\n control: ControlRunResult<unknown, unknown, unknown, ControlEvalResult>,\n): AgentTaskStatus {\n if (control.stoppedBy === 'abort') return 'aborted'\n if (control.reason.includes('knowledge readiness blocked')) return 'blocked'\n if (control.pass) return 'completed'\n return 'failed'\n}\n\nasync function emit<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n sink: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n event: Parameters<AgentRuntimeEventSink<TState, TAction, TActionResult, TEval>>[0],\n): Promise<void> {\n await sink?.(event)\n}\n\nfunction toAgentContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n task: AgentTaskSpec,\n knowledge: KnowledgeReadinessReport,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n): AgentTaskContext<TState, TAction, TActionResult, TEval> {\n return {\n task,\n knowledge,\n state: ctx.state,\n evals: ctx.evals,\n history: ctx.history,\n budget: ctx.budget,\n stepIndex: ctx.stepIndex,\n wallMs: ctx.wallMs,\n spentCostUsd: ctx.spentCostUsd,\n remainingCostUsd: ctx.remainingCostUsd,\n abortSignal: ctx.abortSignal,\n }\n}\n","/**\n *\n * Production-run lifecycle: record what the agent did on behalf of a customer,\n * what it cost, and how it ended.\n *\n * Three concerns live in this module:\n *\n * 1. **Lifecycle state machine** — `running` -> `completed | failed | cancelled`,\n * enforced by `RuntimeRunStateError`. Completion is idempotent for the same\n * status (a second `complete()` call is a no-op so retries / cleanup paths\n * don't double-fire side effects). A different terminal status is a state\n * error.\n *\n * 2. **Cost ledger** — every `llm_call` event the handle observes contributes\n * `tokensIn`, `tokensOut`, `costUsd`, and bumps `llmCalls`. Wall time is\n * measured from `startRuntimeRun()` to `complete()`. Surface via\n * `handle.cost()` for cost-per-task dashboards.\n *\n * 3. **Persistence adapter** — `RuntimeRunPersistenceAdapter` is the seam\n * consumers plug in to write a `RuntimeRunRow` to their D1 / postgres /\n * KV store. The adapter receives a sanitized row shape; no telemetry\n * payload bytes flow through it unless the consumer opts in via\n * `RuntimeRunOptions.telemetryEvents`.\n *\n * @stable\n */\n\nimport { RuntimeRunStateError, ValidationError } from './errors'\nimport type { AgentTaskSpec, RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport type RuntimeRunStatus = 'running' | 'completed' | 'failed' | 'cancelled'\n\n/** @stable */\nexport interface RuntimeRunCost {\n /** Cumulative input tokens across every observed `llm_call` event. */\n tokensIn: number\n /** Cumulative output tokens across every observed `llm_call` event. */\n tokensOut: number\n /** Sum of `costUsd` from every observed `llm_call` event. */\n costUsd: number\n /** Wall time from `startRuntimeRun()` to `complete()` (or `now()` if not yet completed). */\n wallMs: number\n /** Count of `llm_call` events observed during the run. */\n llmCalls: number\n}\n\n/** @stable */\nexport interface RuntimeRunCompleteInput {\n status: Exclude<RuntimeRunStatus, 'running'>\n resultSummary?: string\n /** Optional explicit cost override; if omitted, the accumulated ledger is used. */\n cost?: Partial<RuntimeRunCost>\n /** Stable error message when `status === 'failed'`. */\n error?: string\n /** Additional adapter-specific fields merged into the persisted row. */\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunRow {\n /** Stable runtime-side identifier. Adapters may translate to their own primary key. */\n id: string\n workspaceId: string\n sessionId?: string\n agentId?: string\n domain?: string\n taskId: string\n scenarioId?: string\n status: RuntimeRunStatus\n resultSummary?: string\n error?: string\n cost: RuntimeRunCost\n startedAt: string\n completedAt?: string\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunPersistenceAdapter {\n /**\n * Called once when `handle.persist()` runs. Implementations write `row` to\n * their durable store (D1, postgres, KV) and return whatever the consumer\n * wants the caller to see (often the storage-side row id). Errors thrown\n * here propagate out of `persist()` so the caller can decide whether to\n * retry or log-and-continue.\n */\n upsert(row: RuntimeRunRow): Promise<void> | void\n}\n\n/** @stable */\nexport interface RuntimeRunOptions {\n workspaceId: string\n sessionId?: string\n agentId?: string\n taskSpec: AgentTaskSpec\n scenarioId?: string\n /** Optional persistence adapter; if omitted, `persist()` is a no-op. */\n adapter?: RuntimeRunPersistenceAdapter\n /** Override the row id; default = `${taskSpec.id}:${random suffix}`. */\n id?: string\n /** Override the clock; default = `Date.now()`. Useful for deterministic tests. */\n now?: () => number\n}\n\n/** @stable */\nexport interface RuntimeRunHandle {\n /** Stable id assigned at start. */\n readonly id: string\n readonly workspaceId: string\n readonly sessionId: string | undefined\n readonly taskSpec: AgentTaskSpec\n readonly status: RuntimeRunStatus\n\n /**\n * Observe a single `RuntimeStreamEvent`. The handle ignores non-cost events\n * (text deltas, tool calls) silently so consumers can pipe the whole stream\n * through `handle.observe`. `llm_call` events update the ledger.\n */\n observe(event: RuntimeStreamEvent): void\n\n /** Snapshot of the current cost ledger. Safe to call at any time. */\n cost(): RuntimeRunCost\n\n /**\n * Transition to a terminal state. Idempotent for the same status; throws\n * `RuntimeRunStateError` for a different terminal status (state machines\n * don't time-travel).\n */\n complete(input: RuntimeRunCompleteInput): void\n\n /** Build the current row without writing it. Useful for tests + dry runs. */\n toRow(metadata?: Record<string, unknown>): RuntimeRunRow\n\n /**\n * Persist the current row via the configured adapter. Must be called after\n * `complete()`. Idempotent for the same terminal state (the adapter sees\n * the same row on retry).\n */\n persist(metadata?: Record<string, unknown>): Promise<void>\n}\n\n/**\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\n *\n * @stable\n */\nexport function startRuntimeRun(options: RuntimeRunOptions): RuntimeRunHandle {\n if (!options.workspaceId) {\n throw new ValidationError('startRuntimeRun: workspaceId is required')\n }\n if (!options.taskSpec?.id) {\n throw new ValidationError('startRuntimeRun: taskSpec.id is required')\n }\n const now = options.now ?? Date.now\n const startedAtMs = now()\n const startedAt = new Date(startedAtMs).toISOString()\n const id = options.id ?? `${options.taskSpec.id}:${randomSuffix()}`\n\n let status: RuntimeRunStatus = 'running'\n let completedAtMs: number | undefined\n let resultSummary: string | undefined\n let error: string | undefined\n let completionMetadata: Record<string, unknown> | undefined\n\n const ledger: RuntimeRunCost = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n wallMs: 0,\n llmCalls: 0,\n }\n\n const snapshotCost = (): RuntimeRunCost => ({\n tokensIn: ledger.tokensIn,\n tokensOut: ledger.tokensOut,\n costUsd: ledger.costUsd,\n wallMs: (completedAtMs ?? now()) - startedAtMs,\n llmCalls: ledger.llmCalls,\n })\n\n const buildRow = (extraMetadata?: Record<string, unknown>): RuntimeRunRow => ({\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n agentId: options.agentId,\n domain: options.taskSpec.domain,\n taskId: options.taskSpec.id,\n scenarioId: options.scenarioId,\n status,\n resultSummary,\n error,\n cost: snapshotCost(),\n startedAt,\n completedAt: completedAtMs !== undefined ? new Date(completedAtMs).toISOString() : undefined,\n metadata: mergeMetadata(completionMetadata, extraMetadata),\n })\n\n return {\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n taskSpec: options.taskSpec,\n get status() {\n return status\n },\n observe(event) {\n if (event.type !== 'llm_call') return\n ledger.llmCalls += 1\n if (typeof event.tokensIn === 'number' && Number.isFinite(event.tokensIn)) {\n ledger.tokensIn += event.tokensIn\n }\n if (typeof event.tokensOut === 'number' && Number.isFinite(event.tokensOut)) {\n ledger.tokensOut += event.tokensOut\n }\n if (typeof event.costUsd === 'number' && Number.isFinite(event.costUsd)) {\n ledger.costUsd += event.costUsd\n }\n },\n cost: snapshotCost,\n complete(input) {\n // JS callers can bypass the `Exclude<…, 'running'>` type; enforce the\n // state machine at runtime as well.\n if ((input.status as RuntimeRunStatus) === 'running') {\n throw new ValidationError('complete() requires a terminal status, got \"running\"')\n }\n if (status !== 'running') {\n if (status === input.status) return\n throw new RuntimeRunStateError(\n `Cannot transition runtime run from \"${status}\" to \"${input.status}\"`,\n )\n }\n status = input.status\n completedAtMs = now()\n resultSummary = input.resultSummary\n error = input.error\n completionMetadata = input.metadata\n if (input.cost) {\n if (typeof input.cost.tokensIn === 'number' && Number.isFinite(input.cost.tokensIn)) {\n ledger.tokensIn = input.cost.tokensIn\n }\n if (typeof input.cost.tokensOut === 'number' && Number.isFinite(input.cost.tokensOut)) {\n ledger.tokensOut = input.cost.tokensOut\n }\n if (typeof input.cost.costUsd === 'number' && Number.isFinite(input.cost.costUsd)) {\n ledger.costUsd = input.cost.costUsd\n }\n if (typeof input.cost.llmCalls === 'number' && Number.isFinite(input.cost.llmCalls)) {\n ledger.llmCalls = input.cost.llmCalls\n }\n }\n },\n toRow(metadata) {\n return buildRow(metadata)\n },\n async persist(metadata) {\n if (status === 'running') {\n throw new RuntimeRunStateError('Cannot persist a runtime run before complete() is called')\n }\n if (!options.adapter) return\n await options.adapter.upsert(buildRow(metadata))\n },\n }\n}\n\nfunction mergeMetadata(\n base: Record<string, unknown> | undefined,\n extra: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !extra) return undefined\n return { ...(base ?? {}), ...(extra ?? {}) }\n}\n\nfunction randomSuffix(): string {\n // 8 chars of base36 — sufficient for in-process uniqueness. Callers needing\n // stronger guarantees pass `options.id` explicitly.\n return Math.random().toString(36).slice(2, 10)\n}\n","/**\n *\n * Server-Sent Events serialization for runtime telemetry streams.\n *\n * Newline-safe by construction: any newline in `id` or `event` is collapsed to\n * a space (browsers terminate fields on newline), and multi-line `data`\n * payloads are split into one `data:` line per source line so JSON.stringify\n * output transports cleanly.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\nimport type { RuntimeTelemetryOptions } from './sanitize'\nimport { sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent } from './sanitize'\nimport type { RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport interface ServerSentEventOptions {\n event?: string\n id?: string\n retry?: number\n}\n\n/** @stable */\nexport function encodeServerSentEvent(data: unknown, options: ServerSentEventOptions = {}): string {\n const lines: string[] = []\n if (options.id) lines.push(`id: ${stripNewlines(options.id)}`)\n if (options.event) lines.push(`event: ${stripNewlines(options.event)}`)\n if (typeof options.retry === 'number' && Number.isFinite(options.retry) && options.retry >= 0) {\n lines.push(`retry: ${Math.floor(options.retry)}`)\n }\n\n const payload = typeof data === 'string' ? data : JSON.stringify(data)\n for (const line of payload.split(/\\r?\\n/)) {\n lines.push(`data: ${line}`)\n }\n return `${lines.join('\\n')}\\n\\n`\n}\n\n/** Serialize a `KnowledgeReadinessReport` as a Server-Sent Event string. @stable */\nexport function readinessServerSentEvent(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(\n {\n type: 'readiness',\n readiness: sanitizeKnowledgeReadinessReport(report, telemetryOptions),\n },\n { event, id, retry },\n )\n}\n\n/** Serialize a `RuntimeStreamEvent` as a Server-Sent Event string. @stable */\nexport function runtimeStreamServerSentEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event: sseEvent, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(sanitizeRuntimeStreamEvent(event, telemetryOptions), {\n event: sseEvent,\n id,\n retry,\n })\n}\n\nfunction stripNewlines(value: string): string {\n return value.replace(/[\\r\\n]/g, ' ')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["deriveTurnId","canonicalCandidateDigest","canonicalCandidateBytes"],"sources":["../src/runtime/profile-execution-backend.ts","../src/conversation/call-policy.ts","../src/conversation/headers.ts","../src/conversation/turn-id.ts","../src/conversation/run-conversation.ts","../src/conversation/conversation-backend.ts","../src/conversation/define-conversation.ts","../src/conversation/journal.ts","../src/conversation/journal-sql.ts","../src/conversation/run-persona.ts","../src/improvement/build-prompts.ts","../src/improvement/mcp-serve-verifier.ts","../src/improvement/official-optimizers.ts","../src/improvement/profile-improvement-harness.ts","../src/improvement/prompt-instructions-profile-components.ts","../src/improvement/reflective-generator.ts","../src/knowledge/activation.ts","../src/knowledge/supervised-update.ts","../src/knowledge/improvement-job.ts","../src/model-resolution.ts","../src/readiness.ts","../src/run.ts","../src/runtime-run.ts","../src/sse.ts"],"sourcesContent":["import type { AgentProfile } from '@tangle-network/agent-interface'\nimport type { AgentTurnInput } from '@tangle-network/agent-interface/environment-provider'\nimport { BackendTransportError, ValidationError } from '../errors'\nimport type {\n AgentBackendContext,\n AgentExecutionBackend,\n BackendErrorDetail,\n RuntimeStreamEvent,\n} from '../types'\nimport { streamAgentTurn } from './stream-agent-turn'\nimport { executableAgentProfileSnapshot } from './supervise/executable-spec'\nimport type { ExecutorFactory } from './supervise/types'\n\n/**\n * Bind one exact profile and Runtime executor to the stable `AgentExecutionBackend` contract used\n * by `runAgentTaskStream` and conversations.\n *\n * Runtime still owns the model call through `streamAgentTurn`.\n * The adapter only translates the two stream protocols and carries the caller's request headers\n * into `ExecutorContext` so an HTTP executor can preserve authorization, recursion depth, and\n * trace identity.\n *\n * @stable\n */\nexport function createProfileExecutionBackend(options: {\n profile: AgentProfile\n executor: ExecutorFactory<unknown>\n}): AgentExecutionBackend {\n const profile = executableAgentProfileSnapshot(options.profile, 'createProfileExecutionBackend')\n const executor = options.executor\n\n return {\n kind: 'runtime-profile',\n async *stream(input, context) {\n const propagatedHeaders = snapshotPropagatedHeaders(context.propagatedHeaders)\n const contextualExecutor: ExecutorFactory<unknown> = (spec, executorContext) =>\n executor(spec, {\n ...executorContext,\n ...(propagatedHeaders === undefined ? {} : { propagatedHeaders }),\n })\n const providerMessages = input.providerOptions?.messages\n const turnInput: AgentTurnInput =\n input.messages !== undefined\n ? { providerOptions: { messages: input.messages.map((message) => ({ ...message })) } }\n : Array.isArray(providerMessages)\n ? { providerOptions: { messages: structuredClone(providerMessages) } }\n : { prompt: input.message ?? context.task.intent }\n let terminal = false\n let emittedText = false\n\n for await (const event of streamAgentTurn(\n { kind: 'executor', profile, factory: contextualExecutor },\n turnInput,\n {\n signal: context.signal,\n ...(context.turnId ? { callId: context.turnId } : {}),\n ...(context.runId ? { correlationId: context.runId } : {}),\n },\n )) {\n if (event.type === 'backend_start') continue\n if (event.type === 'backend_error') throw backendError(event.error, event.message)\n if (event.type === 'final') {\n terminal = true\n if (event.status !== 'completed') {\n throw backendError(event.error, event.reason)\n }\n if (!emittedText && event.text) {\n yield {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text: event.text,\n timestamp: event.timestamp,\n }\n }\n continue\n }\n if (event.type === 'text_delta') emittedText = true\n yield rebindEvent(event, context)\n }\n\n if (!terminal) {\n throw new ValidationError(\n 'createProfileExecutionBackend: streamAgentTurn ended without a terminal event',\n )\n }\n },\n }\n}\n\nfunction snapshotPropagatedHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n): Readonly<Record<string, string>> | undefined {\n if (headers === undefined) return undefined\n const snapshot: Record<string, string> = {}\n for (const [name, value] of Object.entries(headers)) {\n if (typeof value !== 'string') {\n throw new ValidationError(\n `createProfileExecutionBackend: propagated header ${JSON.stringify(name)} must be a string`,\n )\n }\n snapshot[name] = value\n }\n return Object.freeze(snapshot)\n}\n\nfunction backendError(detail: BackendErrorDetail | undefined, message: string): Error {\n if (detail?.kind === 'transport') {\n return new BackendTransportError('runtime-profile', detail.message, {\n status: detail.status,\n body: detail.body,\n })\n }\n return new Error(detail?.message ?? message)\n}\n\nfunction rebindEvent(event: RuntimeStreamEvent, context: AgentBackendContext): RuntimeStreamEvent {\n return {\n ...event,\n task: context.task,\n session: context.session,\n } as RuntimeStreamEvent\n}\n","/**\n *\n * Per-call resilience policy for participant backends: deadline, retry with\n * backoff, and a circuit breaker. Each policy is applied *around* a single\n * turn's backend invocation, not across the whole conversation — the\n * conversation-level credit cap and `maxTurns` bound the broader run.\n *\n * Deadlines abort the underlying backend stream via `AbortSignal` linkage so\n * the OpenAI/SDK clients tear down their HTTP request cleanly instead of\n * leaking sockets. Retries replay the same logical turn (same `turnId`) so\n * any caching gateway can dedupe. Circuit breakers are *per participant*: A's\n * failures don't open B's breaker.\n *\n * @stable\n */\n\n/** Pure judgment of whether an error is worth retrying. Defaults: TimeoutError, AbortError, fetch-level network errors. */\nexport type RetryableErrorPredicate = (err: unknown) => boolean\n\n/** Backoff between attempts. Constant ms, or `(attempt: 1-indexed) => ms`. */\nexport type RetryBackoff = number | ((attempt: number) => number)\n\n/** Circuit-breaker tuning. `failuresToOpen` consecutive failures opens it; closed only after `cooldownMs`. */\nexport interface CircuitBreakerConfig {\n failuresToOpen: number\n cooldownMs: number\n}\n\nexport interface BackendCallPolicy {\n /** Per-attempt wall clock limit. Exceeding fires an AbortSignal and is treated as a retryable failure. */\n perAttemptDeadlineMs?: number\n /** Number of retries after the first attempt; total attempts = 1 + maxRetries. Default 0. */\n maxRetries?: number\n /** Backoff between attempts. Default 250ms with jitter. */\n retryBackoffMs?: RetryBackoff\n /** Custom retry classifier. Defaults to retrying transport failures and retryable HTTP statuses. */\n isRetryable?: RetryableErrorPredicate\n /** Circuit breaker that opens after N consecutive failures per participant. */\n circuitBreaker?: CircuitBreakerConfig\n}\n\n/** Thrown when the circuit breaker is open for a participant and no retry is allowed yet. */\nexport class CircuitOpenError extends Error {\n constructor(participant: string, retryAfterMs: number) {\n super(\n `circuit open for participant '${participant}'; ${retryAfterMs}ms remaining before retry allowed`,\n )\n this.name = 'CircuitOpenError'\n }\n}\n\n/** Thrown when a backend call exceeds its per-attempt deadline. */\nexport class DeadlineExceededError extends Error {\n constructor(deadlineMs: number) {\n super(`backend call exceeded per-attempt deadline of ${deadlineMs}ms`)\n this.name = 'DeadlineExceededError'\n }\n}\n\n/**\n * Default retryable classification — network/timeout class errors. Errors\n * a model deliberately throws (validation, refusal, 4xx) are not retried;\n * those represent real outcomes, not transient infrastructure faults.\n */\nexport const defaultIsRetryable: RetryableErrorPredicate = (err) => {\n if (err instanceof DeadlineExceededError) return true\n if (err instanceof Error) {\n const name = err.name\n const message = err.message.toLowerCase()\n if (name === 'AbortError' || name === 'TimeoutError') return true\n if (\n message.includes('econnreset') ||\n message.includes('etimedout') ||\n message.includes('econnrefused') ||\n message.includes('socket hang up') ||\n message.includes('network') ||\n message.includes('fetch failed')\n ) {\n return true\n }\n }\n return false\n}\n\n/** Live circuit-breaker state — one instance per (participant, conversation run). */\nexport class CircuitBreakerState {\n private consecutiveFailures = 0\n private openedAt: number | undefined\n\n constructor(private readonly config: CircuitBreakerConfig | undefined) {}\n\n /**\n * Check whether the next call is allowed. Throws `CircuitOpenError` when\n * the breaker is open and the cooldown hasn't elapsed.\n */\n preflight(participant: string, now: number = Date.now()): void {\n if (!this.config || this.openedAt === undefined) return\n const remaining = this.config.cooldownMs - (now - this.openedAt)\n if (remaining > 0) {\n throw new CircuitOpenError(participant, remaining)\n }\n this.openedAt = undefined\n this.consecutiveFailures = 0\n }\n\n recordSuccess(): void {\n this.consecutiveFailures = 0\n this.openedAt = undefined\n }\n\n recordFailure(now: number = Date.now()): void {\n if (!this.config) return\n this.consecutiveFailures += 1\n if (this.consecutiveFailures >= this.config.failuresToOpen) {\n this.openedAt = now\n }\n }\n}\n\n/**\n * Build a per-attempt AbortSignal linked to the parent signal AND fired when\n * the deadline elapses. The returned `dispose()` MUST be called in a\n * `finally` (clears the timer, detaches the listener) so we don't leak.\n *\n * When the deadline fires, the signal's `reason` is a `DeadlineExceededError`\n * — callers can detect timeout-vs-cancel by reading `signal.reason` after\n * the underlying operation throws.\n */\nexport function makePerAttemptSignal(\n parentSignal: AbortSignal | undefined,\n deadlineMs: number | undefined,\n): {\n signal: AbortSignal\n dispose: () => void\n getDeadlineError(): DeadlineExceededError | undefined\n} {\n const controller = new AbortController()\n let deadlineError: DeadlineExceededError | undefined\n const cleanups: Array<() => void> = []\n\n if (parentSignal) {\n if (parentSignal.aborted) controller.abort(parentSignal.reason)\n else {\n const onAbort = () => controller.abort(parentSignal.reason)\n parentSignal.addEventListener('abort', onAbort, { once: true })\n cleanups.push(() => parentSignal.removeEventListener('abort', onAbort))\n }\n }\n if (deadlineMs !== undefined) {\n const ms = deadlineMs\n const timer = setTimeout(() => {\n deadlineError = new DeadlineExceededError(ms)\n controller.abort(deadlineError)\n }, ms)\n cleanups.push(() => clearTimeout(timer))\n }\n return {\n signal: controller.signal,\n dispose() {\n for (const c of cleanups) c()\n },\n getDeadlineError() {\n return deadlineError\n },\n }\n}\n\n/** Compute the delay before the next attempt. Default: 250ms exponential with jitter. */\nexport function computeBackoff(spec: RetryBackoff | undefined, attempt: number): number {\n if (spec === undefined) {\n const base = 250\n const jitter = Math.floor(Math.random() * base)\n return base * 2 ** (attempt - 1) + jitter\n }\n if (typeof spec === 'function') return Math.max(0, spec(attempt))\n return Math.max(0, spec)\n}\n\n/** Resolve after `ms` milliseconds — used for retry backoff in conversation call policy. */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","/**\n *\n * Cross-gateway forwarding headers — the wire-level contract that makes\n * agent-to-agent communication composable across organizational boundaries.\n * Every header here is read on inbound and re-emitted on outbound, so a chain\n * `caller → A's gateway → A's runtime → B's gateway → B's runtime` ends with\n * B billing the original user, the depth counter monotonically incremented,\n * and the run/turn correlation IDs preserved end-to-end.\n *\n * The actual depth refusal (HTTP 413 at MAX_DEPTH) is enforced by\n * `agent-gateway`'s middleware; this module owns the names + the propagation\n * rules so both sides agree.\n *\n * Full protocol: `docs/agent-bus-protocol.md`.\n *\n * @stable\n */\n\n/** Standard names — lowercased so Headers maps interop on every runtime. */\nexport const FORWARD_HEADERS = {\n /** Forwarded original-user identity (`Bearer sk-tan-<user>`); downstream gateways bill against this. */\n authorization: 'x-tangle-forwarded-authorization',\n /** Monotonically incremented on every gateway hop. Refused at MAX_DEPTH. */\n depth: 'x-tangle-forwarded-depth',\n /** Top-level conversation run identifier, propagated through every nested call. */\n runId: 'x-tangle-runid',\n /** This call's turn within the run; deterministic + stable across retries. */\n turnId: 'x-tangle-turnid',\n /** When the call is *inside* another turn (recursion), the parent turn's id. */\n parentTurnId: 'x-tangle-parent-turnid',\n /** Logical conversation peer label at the sending side, for trace stitching. */\n speaker: 'x-tangle-speaker',\n} as const\n\nexport type ForwardHeaderName = (typeof FORWARD_HEADERS)[keyof typeof FORWARD_HEADERS]\n\n/** Hard cap on chained gateway hops; refused beyond this. Default keeps recursion bounded. */\nexport const DEFAULT_MAX_DEPTH = 4\n\n/**\n * Lowercase a header lookup so we read the same key regardless of source\n * casing (Hono, fetch's `Headers`, raw Node IncomingMessage, …).\n */\nfunction lc(name: string): string {\n return name.toLowerCase()\n}\n\n/**\n * Read the depth counter off an inbound request. Missing → 0 (caller is the\n * origin). Non-integer → throws — silent coercion would let a bad caller\n * reset depth and bypass the limit.\n */\nexport function readDepth(\n headers: Readonly<Record<string, string | string[] | undefined>>,\n): number {\n const raw = pickHeader(headers, FORWARD_HEADERS.depth)\n if (raw === undefined || raw === '') return 0\n const n = Number(raw)\n if (!Number.isInteger(n) || n < 0) {\n throw new Error(\n `invalid ${FORWARD_HEADERS.depth} header value '${raw}' — must be a non-negative integer`,\n )\n }\n return n\n}\n\n/**\n * Refuse further forwarding when the inbound depth has reached the limit.\n * Callers (the gateway middleware) translate the boolean to an HTTP 413.\n */\nexport function isDepthExceeded(inboundDepth: number, max: number = DEFAULT_MAX_DEPTH): boolean {\n return inboundDepth >= max\n}\n\n/**\n * Build the headers to emit on an outbound participant call, given the\n * conversation's propagation context. Depth is incremented from the inbound\n * value; runId / turnId / speaker stamp the current hop; the user's\n * `Authorization` is preserved verbatim so the downstream gateway bills the\n * right wallet.\n */\nexport function buildForwardHeaders(input: {\n inboundDepth: number\n forwardedAuthorization?: string\n runId: string\n turnId: string\n parentTurnId?: string\n speaker: string\n}): Record<string, string> {\n const out: Record<string, string> = {\n [FORWARD_HEADERS.depth]: String(input.inboundDepth + 1),\n [FORWARD_HEADERS.runId]: input.runId,\n [FORWARD_HEADERS.turnId]: input.turnId,\n [FORWARD_HEADERS.speaker]: input.speaker,\n }\n if (input.forwardedAuthorization !== undefined) {\n out[FORWARD_HEADERS.authorization] = input.forwardedAuthorization\n }\n if (input.parentTurnId !== undefined) {\n out[FORWARD_HEADERS.parentTurnId] = input.parentTurnId\n }\n return out\n}\n\n/**\n * Header bag carried through `AgentBackendContext.propagatedHeaders` so\n * backends that opt in can merge them into their outbound HTTP requests.\n * Distinct from `buildForwardHeaders` so callers can attach extra\n * non-protocol headers (e.g. tracing) without colliding.\n */\nexport type PropagatedHeaders = Readonly<Record<string, string>>\n\nfunction pickHeader(\n headers: Readonly<Record<string, string | string[] | undefined>>,\n name: string,\n): string | undefined {\n const target = lc(name)\n for (const key of Object.keys(headers)) {\n if (lc(key) === target) {\n const value = headers[key]\n if (Array.isArray(value)) return value[0]\n return value\n }\n }\n return undefined\n}\n","/**\n *\n * Deterministic turn identifier. Stable across retries of the same logical\n * turn so backends (and any caching gateway in between) can dedupe on it.\n * A retry triggered by a network blip or deadline timeout MUST produce the\n * same `turn_id`; only the underlying attempt count differs.\n *\n * Shape: `${runId}.t${index}.${speakerSlug}` — readable in logs, sortable by\n * turn index, attributable to a speaker. Slugify keeps the speaker portion\n * URL-safe so it can ride in HTTP headers without escaping.\n *\n * @stable\n */\n\nexport function turnId(runId: string, index: number, speaker: string): string {\n return `${runId}.t${index}.${slugifySpeaker(speaker)}`\n}\n\n/**\n * Reduce a speaker name to ASCII alphanumerics + dashes. Preserves enough\n * substance to read in a log line; collisions between speakers within a\n * single Conversation are prevented by `defineConversation`'s\n * unique-name check, so the slug only needs to be deterministic, not unique.\n */\nexport function slugifySpeaker(speaker: string): string {\n const cleaned = speaker\n .normalize('NFKD')\n .replace(/[^\\w-]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .toLowerCase()\n return cleaned || 'anon'\n}\n","/**\n *\n * Conversation orchestrator. Drives N participants in turn through their own\n * `AgentExecutionBackend`s, aggregating per-turn text + usage, enforcing\n * `maxTurns` / `maxCreditsCents` / `haltOn`, and emitting per-event stream\n * markers so callers can plumb the run through SSE without buffering.\n *\n * `runConversation` returns the full result; `runConversationStream` returns\n * an `AsyncIterable<ConversationStreamEvent>` for callers that want to\n * forward events as they arrive. Both share one driving loop.\n *\n * Distributed-systems primitives layered on top of the loop:\n * - **Participant sessions**: one backend session per participant is resumed\n * between turns; stateless backends receive one reconstructed transcript.\n * - **Idempotent turn ids** — `turnId(runId, index, speaker)` stays stable\n * across retries so caching gateways can dedupe.\n * - **Durable journal** — optional `ConversationJournal` persists every\n * committed turn; reusing a runId against the same journal resumes\n * transparently from the last committed turn.\n * - **Per-turn call policy** — deadline, retry-with-backoff, and a\n * per-participant circuit breaker. Retries replay the same logical turn\n * (same `turnId`); the retry loop lives inside the outer generator so\n * deltas yield naturally without cross-coroutine buffering.\n * - **Header propagation** — run/turn/depth headers (+ forwarded user\n * authorization) stamped onto every outbound backend call so downstream\n * gateways can bill the right user and enforce `X-Tangle-Forwarded-Depth`.\n *\n * Credit cap is enforced *between turns*, not mid-stream: a turn that\n * overshoots the cap completes, the cap then halts the conversation before\n * the next turn.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { BackendTransportError } from '../errors'\nimport { InMemoryRuntimeSessionStore, nowIso, startOrResumeRuntimeSession } from '../sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentTaskSpec,\n RuntimeSessionStore,\n} from '../types'\nimport {\n type BackendCallPolicy,\n CircuitBreakerState,\n computeBackoff,\n defaultIsRetryable,\n makePerAttemptSignal,\n sleep,\n} from './call-policy'\nimport { buildForwardHeaders, FORWARD_HEADERS } from './headers'\nimport { turnId as deriveTurnId, slugifySpeaker } from './turn-id'\nimport type {\n Conversation,\n ConversationParticipant,\n ConversationResult,\n ConversationStreamEvent,\n ConversationTurn,\n HaltContext,\n HaltReason,\n RunConversationOptions,\n TurnOrder,\n} from './types'\n\n/** Run a conversation to completion and return its terminal result. */\nexport async function runConversation(\n conversation: Conversation,\n options: RunConversationOptions,\n): Promise<ConversationResult> {\n let result: ConversationResult | undefined\n for await (const event of runConversationStream(conversation, options)) {\n if (options.onEvent) await options.onEvent(event)\n if (event.type === 'conversation_end') result = event.result\n }\n if (!result) {\n throw new BackendTransportError(\n 'conversation',\n 'conversation stream ended without a conversation_end event',\n )\n }\n return result\n}\n\n/** Streaming conversation orchestrator: drives N participants in turn through their own backends, enforcing `maxTurns` / `maxCreditsCents` / `haltOn`, yielding per-event stream markers. */\nexport async function* runConversationStream(\n conversation: Conversation,\n options: RunConversationOptions,\n): AsyncIterable<ConversationStreamEvent> {\n const runId = options.runId ?? `conv_${crypto.randomUUID()}`\n const inboundDepth = options.inboundDepth ?? 0\n const callerHeaders = options.propagatedHeaders ?? {}\n const forwardedAuthorization = callerHeaders[FORWARD_HEADERS.authorization]\n\n const breakers = new Map<string, CircuitBreakerState>()\n for (const participant of conversation.participants) {\n const cfg =\n participant.callPolicy?.circuitBreaker ??\n conversation.policy.defaultCallPolicy?.circuitBreaker\n breakers.set(participant.name, new CircuitBreakerState(cfg))\n }\n\n let transcript: ConversationTurn[] = []\n let spentCreditsCents = 0\n let startedAt = nowIso()\n let resumed = false\n const sessionStore = options.sessionStore ?? new InMemoryRuntimeSessionStore()\n\n if (options.journal) {\n const prior = await options.journal.loadRun(runId)\n if (prior) {\n if (prior.halted) {\n // Run already terminated — surface its final state without re-running.\n const replayResult: ConversationResult = {\n runId,\n transcript: prior.turns,\n turns: prior.turns.length,\n spentCreditsCents: prior.turns.reduce(\n (sum, t) => sum + centsFromUsd(t.usage?.costUsd ?? 0),\n 0,\n ),\n halted: prior.halted,\n durationMs: 0,\n startedAt: prior.startedAt,\n endedAt: prior.endedAt ?? prior.startedAt,\n }\n yield {\n type: 'conversation_resumed',\n runId,\n participants: conversation.participants.map((p) => p.name),\n transcript: prior.turns,\n timestamp: nowIso(),\n }\n yield { type: 'conversation_end', runId, result: replayResult, timestamp: nowIso() }\n return\n }\n transcript = [...prior.turns]\n spentCreditsCents = transcript.reduce(\n (sum, t) => sum + centsFromUsd(t.usage?.costUsd ?? 0),\n 0,\n )\n startedAt = prior.startedAt\n resumed = true\n } else {\n await options.journal.beginRun(runId, startedAt)\n }\n }\n const startedAtMs = Date.now()\n const participantSessions = sessionIdsFrom(transcript)\n\n if (resumed) {\n yield {\n type: 'conversation_resumed',\n runId,\n participants: conversation.participants.map((p) => p.name),\n // Snapshot the resumed transcript — the live `transcript` array gets\n // pushed to as the run continues, so handing the bare reference to a\n // subscriber would leak future writes into a past event.\n transcript: [...transcript],\n timestamp: nowIso(),\n }\n } else {\n yield {\n type: 'conversation_start',\n runId,\n participants: conversation.participants.map((p) => p.name),\n seed: options.seed,\n timestamp: startedAt,\n }\n }\n\n // When resumed, the next user input is the last persisted turn's text;\n // for a fresh run, it's the caller's seed.\n let currentInput =\n transcript.length === 0\n ? options.seed\n : (transcript[transcript.length - 1]?.text ?? options.seed)\n let halt: HaltReason | undefined\n\n const initialOffset = transcript.length\n for (let turnIndex = initialOffset; turnIndex < conversation.policy.maxTurns; turnIndex++) {\n if (options.signal?.aborted) {\n halt = { kind: 'abort' }\n break\n }\n if (\n conversation.policy.maxCreditsCents !== undefined &&\n spentCreditsCents >= conversation.policy.maxCreditsCents\n ) {\n halt = {\n kind: 'max_credits',\n spentCents: spentCreditsCents,\n capCents: conversation.policy.maxCreditsCents,\n }\n break\n }\n\n const speakerIdx = selectSpeaker(\n conversation.policy.turnOrder,\n conversation.participants.length,\n { transcript, turnIndex, spentCreditsCents },\n )\n const speaker = conversation.participants[speakerIdx]\n if (!speaker) {\n throw new BackendTransportError(\n 'conversation',\n `turnOrder selector returned out-of-range index ${speakerIdx} for ${conversation.participants.length} participants`,\n )\n }\n\n const tid = deriveTurnId(runId, turnIndex, speaker.name)\n const callPolicy: BackendCallPolicy | undefined =\n speaker.callPolicy ?? conversation.policy.defaultCallPolicy\n const breaker = breakers.get(speaker.name)\n if (!breaker) {\n throw new BackendTransportError(\n 'conversation',\n `internal: no circuit-breaker state registered for participant '${speaker.name}'`,\n )\n }\n const isRetryable = callPolicy?.isRetryable ?? defaultIsRetryable\n const totalAttempts = 1 + (callPolicy?.maxRetries ?? 0)\n\n yield {\n type: 'turn_start',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n attempt: 1,\n timestamp: nowIso(),\n }\n\n let aggregator: TurnAggregator | undefined\n let attemptCount = 0\n let lastError: unknown\n let breakerOpenFailure: unknown\n\n for (let attempt = 1; attempt <= totalAttempts; attempt++) {\n attemptCount = attempt\n try {\n breaker.preflight(speaker.name)\n } catch (err) {\n // Breaker open — no point retrying; halt the conversation with this\n // participant's error rather than busy-looping until exhaustion.\n breakerOpenFailure = err\n break\n }\n\n if (attempt > 1) {\n yield {\n type: 'turn_retry',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n attempt,\n reason: lastError instanceof Error ? lastError.message : String(lastError),\n timestamp: nowIso(),\n }\n }\n\n const perAttempt = makePerAttemptSignal(options.signal, callPolicy?.perAttemptDeadlineMs)\n const localAgg = new TurnAggregator({\n index: turnIndex,\n speaker: speaker.name,\n startedAt: nowIso(),\n })\n\n try {\n for await (const delta of driveSingleAttempt({\n speaker,\n participants: conversation.participants,\n seed: options.seed,\n input: currentInput,\n turnIndex,\n runId,\n turnId: tid,\n transcript,\n participantSessions,\n sessionStore,\n signal: perAttempt.signal,\n aggregator: localAgg,\n propagatedHeaders: buildForwardHeaders({\n inboundDepth,\n // When the participant elects to pay for its own outbound calls,\n // drop the forwarded user identity so the downstream gateway\n // bills the participant's own credentials instead. The backend\n // brings its own credentials through its caller-owned backend or\n // profile-bound Runtime executor;\n // omitting the forwarded header is what flips the billing target.\n forwardedAuthorization: resolveAuthForwarding(speaker, {\n transcript,\n turnIndex,\n spentCreditsCents,\n })\n ? forwardedAuthorization\n : undefined,\n runId,\n turnId: tid,\n parentTurnId: options.parentTurnId,\n speaker: speaker.name,\n }),\n })) {\n yield {\n type: 'turn_text_delta',\n runId,\n index: turnIndex,\n speaker: speaker.name,\n turnId: tid,\n text: delta.text,\n timestamp: delta.timestamp,\n }\n }\n perAttempt.dispose()\n breaker.recordSuccess()\n aggregator = localAgg\n break\n } catch (err) {\n perAttempt.dispose()\n breaker.recordFailure()\n // Surface the deadline error explicitly when timeout was the cause —\n // otherwise the upstream may throw a generic AbortError that loses\n // diagnostic info.\n lastError = perAttempt.getDeadlineError() ?? err\n if (attempt >= totalAttempts || !isRetryable(lastError)) {\n break\n }\n await sleep(computeBackoff(callPolicy?.retryBackoffMs, attempt))\n }\n }\n\n if (!aggregator) {\n const failure = breakerOpenFailure ?? lastError\n const message = failure instanceof Error ? failure.message : String(failure)\n halt = { kind: 'participant_error', participant: speaker.name, message }\n break\n }\n\n const turn = aggregator.toTurn({ turnId: tid, attempts: attemptCount })\n if (turn.sessionId) {\n bindParticipantSession(participantSessions, turn.speaker, turn.sessionId)\n }\n transcript.push(turn)\n spentCreditsCents += centsFromUsd(turn.usage?.costUsd ?? 0)\n if (options.journal) {\n await options.journal.appendTurn(runId, turn)\n }\n\n yield { type: 'turn_end', runId, turn, timestamp: nowIso() }\n\n if (conversation.policy.haltOn) {\n const haltCtx: HaltContext = {\n transcript,\n lastTurn: turn,\n turnIndex,\n spentCreditsCents,\n }\n const decision = await conversation.policy.haltOn(haltCtx)\n if (decision === true) {\n halt = { kind: 'predicate', reason: 'predicate_true' }\n break\n }\n if (typeof decision === 'object' && decision !== null && decision.halted) {\n halt = { kind: 'predicate', reason: decision.reason }\n break\n }\n }\n\n currentInput = turn.text\n }\n\n if (!halt) halt = { kind: 'max_turns', turns: transcript.length }\n\n const endedAt = nowIso()\n const result: ConversationResult = {\n runId,\n transcript,\n turns: transcript.length,\n spentCreditsCents,\n halted: halt,\n durationMs: Date.now() - startedAtMs,\n startedAt,\n endedAt,\n }\n if (options.journal) {\n await options.journal.recordHalt(runId, halt, endedAt)\n }\n\n yield { type: 'conversation_end', runId, result, timestamp: endedAt }\n}\n\n// ── Single attempt ───────────────────────────────────────────────────────\n\ninterface SingleAttemptArgs {\n speaker: ConversationParticipant\n participants: readonly ConversationParticipant[]\n seed: string\n input: string\n turnIndex: number\n runId: string\n turnId: string\n transcript: readonly ConversationTurn[]\n participantSessions: Map<string, string>\n sessionStore: RuntimeSessionStore\n signal: AbortSignal\n aggregator: TurnAggregator\n propagatedHeaders: Record<string, string>\n}\n\nasync function* driveSingleAttempt(\n args: SingleAttemptArgs,\n): AsyncGenerator<{ text: string; timestamp?: string }> {\n const task: AgentTaskSpec = {\n id: args.turnId,\n intent: args.input,\n metadata: {\n runId: args.runId,\n turnId: args.turnId,\n turnIndex: args.turnIndex,\n speaker: args.speaker.name,\n participants: args.participants.map((p) => p.name),\n },\n }\n const knowledge = passingReadiness(task.id)\n\n const startCtx: Omit<AgentBackendContext, 'session'> = {\n task,\n knowledge,\n signal: args.signal,\n runId: args.runId,\n turnId: args.turnId,\n propagatedHeaders: args.propagatedHeaders,\n }\n const previousSessionId = args.participantSessions.get(args.speaker.name)\n const opened = await startOrResumeRuntimeSession({\n backend: args.speaker.backend,\n input: () => fullConversationInput(task, args.speaker.name, args.seed, args.transcript),\n continuationInput: () => continuedConversationInput(task, args.speaker.name, args.transcript),\n context: startCtx,\n store: args.sessionStore,\n sessionId:\n previousSessionId ?? participantSessionId(args.runId, args.speaker.name, args.participants),\n resume: previousSessionId !== undefined && args.speaker.backend.resume !== undefined,\n validateSession: (session) =>\n assertParticipantSessionAvailable(args.participantSessions, args.speaker.name, session.id),\n })\n const session = opened.session\n args.aggregator.recordSession(session.id)\n\n const streamCtx: AgentBackendContext = {\n task,\n knowledge,\n session,\n signal: args.signal,\n runId: args.runId,\n turnId: args.turnId,\n propagatedHeaders: args.propagatedHeaders,\n }\n\n for await (const event of args.speaker.backend.stream(opened.input, streamCtx)) {\n if (args.signal.aborted) {\n // Surface the abort so the outer retry/halt logic can react. The signal\n // either fires because of caller-cancel (propagate as-is) or because of\n // the per-attempt deadline timer (signal.reason is DeadlineExceededError).\n const reason = args.signal.reason\n throw reason instanceof Error ? reason : new Error('aborted')\n }\n if (event.type === 'text_delta') {\n args.aggregator.appendText(event.text)\n yield { text: event.text, timestamp: event.timestamp }\n } else if (event.type === 'llm_call') {\n args.aggregator.recordUsage(event)\n } else if (event.type === 'backend_error') {\n throw new BackendTransportError(args.speaker.backend.kind, event.message, {\n status: event.error?.status,\n body: event.error?.body,\n })\n } else if (event.type === 'final') {\n if (event.status !== 'completed') {\n throw new BackendTransportError(\n args.speaker.backend.kind,\n event.error?.message ?? event.reason,\n { status: event.error?.status, body: event.error?.body },\n )\n }\n args.aggregator.adoptFinalText(event.text)\n }\n }\n\n if (!args.aggregator.hasText()) {\n throw new BackendTransportError(\n args.speaker.backend.kind,\n `backend '${args.speaker.backend.kind}' completed without text`,\n )\n }\n}\n\nclass TurnAggregator {\n private text = ''\n private adoptedFinal = false\n private sessionId: string | undefined\n private usage:\n | {\n tokensIn?: number\n tokensOut?: number\n costUsd?: number\n latencyMs?: number\n model?: string\n }\n | undefined\n\n constructor(private readonly base: { index: number; speaker: string; startedAt: string }) {}\n\n appendText(text: string): void {\n if (this.adoptedFinal) return\n this.text += text\n }\n\n /**\n * Use the backend's `final.text` only when no streamed deltas were observed.\n * Some backends emit deltas AND a final summary; treating both as content\n * would double-count.\n */\n adoptFinalText(text: string | undefined): void {\n if (!text) return\n if (this.text.length > 0) return\n this.text = text\n this.adoptedFinal = true\n }\n\n hasText(): boolean {\n return this.text.trim().length > 0\n }\n\n recordSession(sessionId: string): void {\n this.sessionId = sessionId\n }\n\n recordUsage(event: {\n model?: string\n tokensIn?: number\n tokensOut?: number\n costUsd?: number\n latencyMs?: number\n }): void {\n const u = this.usage ?? {}\n if (event.tokensIn !== undefined) u.tokensIn = (u.tokensIn ?? 0) + event.tokensIn\n if (event.tokensOut !== undefined) u.tokensOut = (u.tokensOut ?? 0) + event.tokensOut\n if (event.costUsd !== undefined) u.costUsd = (u.costUsd ?? 0) + event.costUsd\n if (event.latencyMs !== undefined) u.latencyMs = event.latencyMs\n if (event.model !== undefined) u.model = event.model\n this.usage = u\n }\n\n toTurn(meta: { turnId: string; attempts: number }): ConversationTurn {\n return {\n index: this.base.index,\n speaker: this.base.speaker,\n turnId: meta.turnId,\n ...(this.sessionId ? { sessionId: this.sessionId } : {}),\n text: this.text.trim(),\n usage: this.usage,\n attempts: meta.attempts,\n startedAt: this.base.startedAt,\n endedAt: nowIso(),\n }\n }\n}\n\n/**\n * Build the participant's POV of the transcript so an OpenAI-compatible\n * backend sees its own turns as `assistant` and everyone else's as `user`,\n * with explicit speaker tags so 3+ party conversations stay disambiguated.\n */\nfunction buildMessagesFor(\n speakerName: string,\n seed: string,\n transcript: readonly ConversationTurn[],\n): Array<{ role: string; content: string }> {\n const messages: Array<{ role: string; content: string }> = seed\n ? [{ role: 'user', content: seed }]\n : []\n for (const turn of transcript) {\n if (turn.speaker === speakerName) {\n messages.push({ role: 'assistant', content: turn.text })\n } else {\n messages.push({ role: 'user', content: `[${turn.speaker}] ${turn.text}` })\n }\n }\n return messages\n}\n\nfunction fullConversationInput(\n task: AgentTaskSpec,\n speakerName: string,\n seed: string,\n transcript: readonly ConversationTurn[],\n): AgentBackendInput {\n const transcriptText = transcript.map((turn) => `[${turn.speaker}] ${turn.text}`)\n return {\n task,\n message: [seed, ...transcriptText].filter((part) => part.length > 0).join('\\n\\n'),\n messages: buildMessagesFor(speakerName, seed, transcript),\n }\n}\n\nfunction continuedConversationInput(\n task: AgentTaskSpec,\n speakerName: string,\n transcript: readonly ConversationTurn[],\n): AgentBackendInput {\n let lastOwnTurn = -1\n for (let index = transcript.length - 1; index >= 0; index -= 1) {\n if (transcript[index]?.speaker === speakerName) {\n lastOwnTurn = index\n break\n }\n }\n const unseen = transcript.slice(lastOwnTurn + 1)\n const message =\n unseen.length > 0\n ? unseen.map((turn) => `[${turn.speaker}] ${turn.text}`).join('\\n\\n')\n : 'Continue.'\n return { task, message, messages: [{ role: 'user', content: message }] }\n}\n\nfunction sessionIdsFrom(transcript: readonly ConversationTurn[]): Map<string, string> {\n const sessions = new Map<string, string>()\n for (const turn of transcript) {\n if (turn.sessionId) bindParticipantSession(sessions, turn.speaker, turn.sessionId)\n }\n return sessions\n}\n\nfunction bindParticipantSession(\n sessions: Map<string, string>,\n speakerName: string,\n sessionId: string,\n): void {\n assertParticipantSessionAvailable(sessions, speakerName, sessionId)\n sessions.set(speakerName, sessionId)\n}\n\nfunction assertParticipantSessionAvailable(\n sessions: ReadonlyMap<string, string>,\n speakerName: string,\n sessionId: string,\n): void {\n for (const [boundSpeaker, boundSessionId] of sessions) {\n if (boundSpeaker !== speakerName && boundSessionId === sessionId) {\n throw new BackendTransportError(\n 'conversation',\n `session '${sessionId}' is already bound to participant '${boundSpeaker}'`,\n )\n }\n }\n}\n\nfunction participantSessionId(\n runId: string,\n speakerName: string,\n participants: readonly ConversationParticipant[],\n): string {\n const participantIndex = participants.findIndex((participant) => participant.name === speakerName)\n if (participantIndex < 0) {\n throw new BackendTransportError(\n 'conversation',\n `participant '${speakerName}' is not registered in this conversation`,\n )\n }\n return `${runId}.participant.${participantIndex}.${slugifySpeaker(speakerName)}`\n}\n\n/**\n * True when this participant should forward the caller's\n * `X-Tangle-Forwarded-Authorization` on outbound calls (the \"pass-through\"\n * commercial mode). False when it elects to pay for its own outbound calls\n * (the \"reseller\" / \"bundle\" mode). See ConversationParticipant.authSource.\n */\nfunction resolveAuthForwarding(\n participant: ConversationParticipant,\n state: { transcript: readonly ConversationTurn[]; turnIndex: number; spentCreditsCents: number },\n): boolean {\n const decision =\n typeof participant.authSource === 'function'\n ? participant.authSource(state)\n : (participant.authSource ?? 'forward-user')\n return decision === 'forward-user'\n}\n\nfunction selectSpeaker(\n order: TurnOrder | undefined,\n participantCount: number,\n state: { transcript: readonly ConversationTurn[]; turnIndex: number; spentCreditsCents: number },\n): number {\n const resolved = order ?? (participantCount === 2 ? 'alternate' : 'round-robin')\n if (resolved === 'alternate' || resolved === 'round-robin') {\n return state.turnIndex % participantCount\n }\n if (typeof resolved === 'function') {\n const idx = resolved(state)\n if (!Number.isInteger(idx) || idx < 0 || idx >= participantCount) {\n throw new BackendTransportError(\n 'conversation',\n `turnOrder function returned invalid index ${String(idx)} for ${participantCount} participants`,\n )\n }\n return idx\n }\n throw new BackendTransportError('conversation', `unknown turnOrder: ${String(resolved)}`)\n}\n\nfunction centsFromUsd(usd: number): number {\n return Math.round(usd * 100)\n}\n\n/**\n * Synthesize a knowledge-readiness report that *passes* every gate, used to\n * satisfy `AgentBackendContext.knowledge` per turn. Conversations don't apply\n * task-level readiness gating per-turn — that's a `runAgentTask` concern.\n */\nfunction passingReadiness(taskId: string): KnowledgeReadinessReport {\n return {\n taskId,\n readinessScore: 1,\n blockingMissingRequirements: [],\n nonBlockingGaps: [],\n recommendedAction: 'run_agent',\n bundle: {\n taskId,\n requirements: [],\n evidenceIds: [],\n claimIds: [],\n wikiPageIds: [],\n userAnswers: {},\n missing: [],\n readinessScore: 1,\n },\n severity: 'info',\n reason: 'conversation-mode: readiness gating not applied per-turn',\n }\n}\n","/**\n *\n * Wrap a `Conversation` so it satisfies `AgentExecutionBackend`. The result is\n * an addressable \"single agent\" whose internal behavior is an N-party\n * orchestrated conversation — the recursion primitive that lets a swarm be a\n * participant inside another swarm, or be published behind a single\n * agent-gateway endpoint.\n *\n * Stream events from inner participants are NOT forwarded verbatim. Outer\n * callers see one `text_delta` per inner turn (the turn's full text), tagged\n * with `[speaker] ` prefix so the outer transcript stays attributable. The\n * conversation's `conversation_end` halt reason rides on a `final` event.\n *\n * @stable\n */\n\nimport { providerMessageText } from '../runtime/turn-input'\nimport { newRuntimeSession, nowIso } from '../sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentExecutionBackend,\n RuntimeSession,\n RuntimeStreamEvent,\n} from '../types'\nimport { FORWARD_HEADERS, readDepth } from './headers'\nimport { runConversationStream } from './run-conversation'\nimport type { Conversation, HaltReason } from './types'\n\n/** Adapt a multi-participant conversation into the standard execution backend contract. */\nexport function createConversationBackend(options: {\n conversation: Conversation\n /** Optional backend kind label. Defaults to `'conversation'`. */\n kind?: string\n}): AgentExecutionBackend {\n const kind = options.kind ?? 'conversation'\n\n return {\n kind,\n start(_input, context): RuntimeSession {\n return newRuntimeSession(kind, context.requestedSessionId, {\n participants: options.conversation.participants.map((p) => p.name),\n })\n },\n async *stream(\n input: AgentBackendInput,\n context: AgentBackendContext,\n ): AsyncIterable<RuntimeStreamEvent> {\n const seed =\n input.message ??\n input.messages?.at(-1)?.content ??\n providerMessageText(input.providerOptions) ??\n context.task.intent\n const task = context.task\n const session = context.session\n\n yield { type: 'backend_start', task, session, backend: kind, timestamp: nowIso() }\n\n let finalText = ''\n let totalCostUsd = 0\n let totalTokensIn = 0\n let totalTokensOut = 0\n\n // Recursion: forward this call's propagation context into the nested\n // conversation. The nested run INHERITS the parent's runId (protocol\n // invariant: runId is immutable across nesting), continues the depth\n // counter from the headers, and stamps the enclosing turn as the\n // parentTurnId so trace stitching reaches across nesting levels.\n const inboundDepth = parseInboundDepth(context.propagatedHeaders)\n for await (const event of runConversationStream(options.conversation, {\n seed,\n signal: context.signal,\n runId: context.runId,\n propagatedHeaders: context.propagatedHeaders,\n inboundDepth,\n parentTurnId: context.turnId,\n })) {\n if (event.type === 'turn_end') {\n const tagged = `[${event.turn.speaker}] ${event.turn.text}\\n`\n finalText += tagged\n yield { type: 'text_delta', task, session, text: tagged, timestamp: event.timestamp }\n if (event.turn.usage) {\n const u = event.turn.usage\n if (u.costUsd !== undefined) totalCostUsd += u.costUsd\n if (u.tokensIn !== undefined) totalTokensIn += u.tokensIn\n if (u.tokensOut !== undefined) totalTokensOut += u.tokensOut\n yield {\n type: 'llm_call',\n task,\n session,\n model: u.model ?? `${kind}/${event.turn.speaker}`,\n tokensIn: u.tokensIn,\n tokensOut: u.tokensOut,\n costUsd: u.costUsd,\n latencyMs: u.latencyMs,\n timestamp: event.timestamp,\n }\n }\n } else if (event.type === 'conversation_end') {\n const halt = event.result.halted\n yield {\n type: 'final',\n task,\n session,\n status: halt.kind === 'participant_error' ? 'failed' : 'completed',\n reason: describeHalt(halt),\n text: finalText.trim(),\n metadata: {\n conversationRunId: event.result.runId,\n turns: event.result.turns,\n spentCreditsCents: event.result.spentCreditsCents,\n halted: halt,\n durationMs: event.result.durationMs,\n tokensIn: totalTokensIn,\n tokensOut: totalTokensOut,\n costUsd: totalCostUsd,\n },\n timestamp: event.timestamp,\n }\n }\n }\n\n yield { type: 'backend_end', task, session, backend: kind, timestamp: nowIso() }\n },\n }\n}\n\nfunction parseInboundDepth(headers: Readonly<Record<string, string>> | undefined): number {\n if (!headers) return 0\n // Accept either the canonical header key OR a lookup via the keyed name.\n const raw = headers[FORWARD_HEADERS.depth]\n if (raw === undefined) return 0\n try {\n return readDepth({ [FORWARD_HEADERS.depth]: raw })\n } catch {\n return 0\n }\n}\n\nfunction describeHalt(halt: HaltReason): string {\n switch (halt.kind) {\n case 'max_turns':\n return `max_turns (${halt.turns})`\n case 'max_credits':\n return `max_credits (${halt.spentCents}/${halt.capCents}¢)`\n case 'predicate':\n return `predicate: ${halt.reason}`\n case 'abort':\n return 'abort'\n case 'participant_error':\n return `participant_error[${halt.participant}]: ${halt.message}`\n }\n}\n","/**\n *\n * Declarative constructor for a multi-agent `Conversation`. Validates inputs\n * fail-loud at definition time (duplicate participant names, alternate order\n * with ≠2 participants, non-positive `maxTurns`) so misconfiguration is caught\n * before `runConversation` is called and not buried inside a streaming run.\n *\n * @stable\n */\n\nimport { ValidationError } from '../errors'\nimport type { Conversation, ConversationParticipant, ConversationPolicy, TurnOrder } from './types'\n\n/** Validate and define a conversation before execution. */\nexport function defineConversation(input: {\n participants: ConversationParticipant[]\n policy: ConversationPolicy\n}): Conversation {\n if (input.participants.length < 2) {\n throw new ValidationError(\n `Conversation requires at least 2 participants; received ${input.participants.length}.`,\n )\n }\n\n const seen = new Set<string>()\n for (const p of input.participants) {\n if (!p.name || p.name.trim() === '') {\n throw new ValidationError('Conversation participant.name must be a non-empty string.')\n }\n if (seen.has(p.name)) {\n throw new ValidationError(\n `Conversation participant names must be unique within a Conversation; '${p.name}' appears more than once.`,\n )\n }\n seen.add(p.name)\n if (!p.backend || typeof p.backend.stream !== 'function') {\n throw new ValidationError(\n `Conversation participant '${p.name}' is missing a backend with a stream() method.`,\n )\n }\n }\n\n const policy = normalizePolicy(input.policy, input.participants.length)\n\n return {\n participants: input.participants,\n policy,\n }\n}\n\nfunction normalizePolicy(policy: ConversationPolicy, participantCount: number): ConversationPolicy {\n if (!Number.isInteger(policy.maxTurns) || policy.maxTurns < 1) {\n throw new ValidationError(\n `ConversationPolicy.maxTurns must be a positive integer; received ${String(policy.maxTurns)}.`,\n )\n }\n if (\n policy.maxCreditsCents !== undefined &&\n (!Number.isFinite(policy.maxCreditsCents) || policy.maxCreditsCents < 0)\n ) {\n throw new ValidationError(\n `ConversationPolicy.maxCreditsCents must be a non-negative finite number when set; received ${String(\n policy.maxCreditsCents,\n )}.`,\n )\n }\n const turnOrder = policy.turnOrder ?? (participantCount === 2 ? 'alternate' : 'round-robin')\n if (turnOrder === 'alternate' && participantCount !== 2) {\n throw new ValidationError(\n `ConversationPolicy.turnOrder 'alternate' requires exactly 2 participants; received ${participantCount}. Use 'round-robin' or a custom selector for N-party conversations.`,\n )\n }\n return { ...policy, turnOrder: turnOrder as TurnOrder }\n}\n","/**\n *\n * Durable conversation transcript — survives a driver process crash mid-run.\n * The runner journals every committed turn before yielding `turn_end`, so a\n * resumed run replays the same `runId` against the same journal and picks up\n * from the first un-recorded turn. Combined with the deterministic\n * `turnId(runId, index, speaker)`, a retried turn collides with the prior\n * attempt's id and any caching gateway can dedupe.\n *\n * The interface is small enough that a Cloudflare D1 / R2 / postgres adapter\n * is ~30 lines. The in-memory adapter is the default for tests and scratch.\n * The file adapter (JSONL on disk) is the default-durable choice when no\n * upstream store is wired.\n *\n * @stable\n */\n\nimport { prepareJsonlAppend, readCommittedJsonLines, writeAllBytes } from '../durable/jsonl-file'\nimport type { ConversationTurn, HaltReason } from './types'\n\nexport interface ConversationJournalEntry {\n runId: string\n startedAt: string\n /** Set when the run reaches a terminal state. */\n halted?: HaltReason\n endedAt?: string\n turns: ConversationTurn[]\n}\n\nexport interface ConversationJournal {\n /**\n * Load any prior state for `runId`. Returns `undefined` for a fresh run.\n * Implementations MUST NOT mutate the returned object — the runner clones\n * before continuing — but the runtime treats absence and emptiness\n * identically, so a journal with zero turns is equivalent to \"fresh.\"\n */\n loadRun(runId: string): Promise<ConversationJournalEntry | undefined>\n\n /**\n * Initialise journal state for a fresh run. Called once per run, before any\n * `appendTurn`. Idempotent: calling with an existing runId is a no-op if\n * the entry already exists with the same `startedAt`.\n */\n beginRun(runId: string, startedAt: string): Promise<void>\n\n /**\n * Append a committed turn. The runner only calls this AFTER the turn's\n * backend stream completed and the credit total has been updated, so an\n * appended turn is observed-committed and never speculative.\n */\n appendTurn(runId: string, turn: ConversationTurn): Promise<void>\n\n /**\n * Record the run's terminal halt reason + end time. Once called, the run\n * is observed-final; subsequent `loadRun` returns the same halt.\n */\n recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>\n}\n\n/** In-memory `ConversationJournal` — suitable for testing and single-process runs. */\nexport class InMemoryConversationJournal implements ConversationJournal {\n private readonly entries = new Map<string, ConversationJournalEntry>()\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n const entry = this.entries.get(runId)\n if (!entry) return undefined\n // Defensive copy — callers MUST NOT mutate journal-owned arrays.\n return {\n runId: entry.runId,\n startedAt: entry.startedAt,\n halted: entry.halted,\n endedAt: entry.endedAt,\n turns: [...entry.turns],\n }\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = this.entries.get(runId)\n if (existing) {\n if (existing.startedAt !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists with startedAt=${existing.startedAt}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n this.entries.set(runId, { runId, startedAt, turns: [] })\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n const entry = this.entries.get(runId)\n if (!entry) {\n throw new Error(\n `appendTurn called for unknown runId '${runId}'; call beginRun first or use the runner which handles it`,\n )\n }\n if (entry.halted) {\n throw new Error(\n `cannot append turn to halted run '${runId}' (halt reason: ${JSON.stringify(entry.halted)})`,\n )\n }\n entry.turns.push(turn)\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n const entry = this.entries.get(runId)\n if (!entry) {\n throw new Error(`recordHalt called for unknown runId '${runId}'`)\n }\n entry.halted = halt\n entry.endedAt = endedAt\n }\n}\n\n/**\n * JSONL on disk. One line per record; first line is the `begin`, subsequent\n * lines are `turn` records, terminal line is `halt`. Replays the whole file\n * on `loadRun` — cheap for the conversation sizes this is designed for\n * (thousands of turns, not millions). For huge runs, plug in a real DB\n * adapter; the interface is small.\n *\n * Reads and appends over the shared append-only spine (`durable/jsonl-file`): each\n * `appendTurn` / `recordHalt` finishes a short write and calls `fsync`, so a process\n * crash between writes never loses an acknowledged turn, and a crash DURING one leaves\n * an uncommitted final line that the next read skips and the next append truncates.\n */\nexport class FileConversationJournal implements ConversationJournal {\n constructor(private readonly path: string) {}\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n let entry: ConversationJournalEntry | undefined\n for await (const record of readCommittedJsonLines<JournalRecord>(this.path, {\n allowMissing: true,\n })) {\n if (record.runId !== runId) continue\n if (record.kind === 'begin') {\n entry = { runId, startedAt: record.startedAt, turns: [] }\n } else if (record.kind === 'turn') {\n if (!entry) {\n throw new Error(\n `journal corrupted: turn record for runId '${runId}' precedes its begin record`,\n )\n }\n entry.turns.push(record.turn)\n } else if (record.kind === 'halt') {\n if (!entry) {\n throw new Error(\n `journal corrupted: halt record for runId '${runId}' precedes its begin record`,\n )\n }\n entry.halted = record.halted\n entry.endedAt = record.endedAt\n }\n }\n return entry\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = await this.loadRun(runId)\n if (existing) {\n if (existing.startedAt !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists in ${this.path} with startedAt=${existing.startedAt}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n await this.appendRecord({ kind: 'begin', runId, startedAt })\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n await this.appendRecord({ kind: 'turn', runId, turn })\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n await this.appendRecord({ kind: 'halt', runId, halted: halt, endedAt })\n }\n\n private async appendRecord(record: JournalRecord): Promise<void> {\n const fs = await import('node:fs/promises')\n const path = await import('node:path')\n await fs.mkdir(path.dirname(this.path), { recursive: true })\n const needsSeparator = await prepareJsonlAppend(this.path)\n const fh = await fs.open(this.path, 'a')\n try {\n await writeAllBytes(fh, `${needsSeparator ? '\\n' : ''}${JSON.stringify(record)}\\n`)\n await fh.sync()\n } finally {\n await fh.close()\n }\n }\n}\n\ntype JournalRecord =\n | { kind: 'begin'; runId: string; startedAt: string }\n | { kind: 'turn'; runId: string; turn: ConversationTurn }\n | { kind: 'halt'; runId: string; halted: HaltReason; endedAt: string }\n","/**\n *\n * Durable conversation journal backed by any SQL store. Adapter-agnostic by\n * design: callers wire a `SqlAdapter` against their driver of choice (D1,\n * postgres, sqlite, libSQL…) and the same journal implementation persists\n * conversation runs durably across process restarts. The schema is two\n * tables — runs (latest state) + events (append-only log) — so a partial\n * crash in the middle of a turn leaves an unambiguous \"last committed turn\"\n * to resume from.\n *\n * Why not bake in a specific driver? agent-runtime ships against multiple\n * runtimes (Cloudflare Workers, Node, Bun, Deno) and consumers' fleets have\n * already standardized on one of D1 / postgres / sqlite / libSQL. Adapter\n * indirection costs ~5 lines per driver in the consumer's code and keeps the\n * SDK free of native deps.\n *\n * @example D1 (Cloudflare Workers)\n * import { SqlConversationJournal, d1ToSqlAdapter } from '@tangle-network/agent-runtime'\n * const journal = new SqlConversationJournal(d1ToSqlAdapter(env.DB))\n * await journal.migrate() // once at deploy\n * await runConversation(conv, { seed, journal, runId: 'run_abc' })\n *\n * @example node-postgres\n * import { Pool } from 'pg'\n * const pool = new Pool({ connectionString: process.env.DATABASE_URL })\n * const pg: SqlAdapter = {\n * exec: async (sql, params = []) => {\n * const r = await pool.query(sql, params as never)\n * return { rowsAffected: r.rowCount ?? 0 }\n * },\n * query: async (sql, params = []) => (await pool.query(sql, params as never)).rows,\n * }\n * const journal = new SqlConversationJournal(pg)\n * await journal.migrate()\n *\n * @stable\n */\n\nimport type { ConversationJournal, ConversationJournalEntry } from './journal'\nimport type { ConversationTurn, HaltReason } from './types'\n\n/**\n * Minimal SQL driver shape. Implementations forward to whichever client the\n * deployment already uses; agent-runtime takes no opinion on which.\n *\n * Parameter placeholders MUST be `?` (positional). All adapters listed in the\n * file header accept this convention.\n */\nexport interface SqlAdapter {\n /** Execute a write statement (INSERT/UPDATE/DELETE/DDL). */\n exec(sql: string, params?: readonly unknown[]): Promise<{ rowsAffected: number }>\n /** Execute a read statement (SELECT). Returns rows as plain objects. */\n query<TRow = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<TRow[]>\n}\n\n/**\n * Adapt a Cloudflare D1 binding to the SqlAdapter shape. Lives here so D1\n * consumers don't have to write the wrapper themselves; the runtime never\n * imports `@cloudflare/workers-types` directly (peer-style typing).\n */\nexport function d1ToSqlAdapter(db: D1DatabaseLike): SqlAdapter {\n return {\n async exec(sql, params = []) {\n const stmt = db.prepare(sql)\n const bound = params.length > 0 ? stmt.bind(...params) : stmt\n const result = await bound.run()\n const meta = (result as { meta?: { rows_written?: number; changes?: number } }).meta\n return { rowsAffected: meta?.rows_written ?? meta?.changes ?? 0 }\n },\n async query<TRow>(sql: string, params: readonly unknown[] = []): Promise<TRow[]> {\n const stmt = db.prepare(sql)\n const bound = params.length > 0 ? stmt.bind(...params) : stmt\n const result = await bound.all<TRow>()\n return result.results ?? []\n },\n }\n}\n\n/**\n * Structural type matching the surface of `D1Database` we depend on, so the\n * SDK never imports `@cloudflare/workers-types`. Consumers pass their real\n * `D1Database` from `env.DB` and TS structural compatibility lines it up.\n */\nexport interface D1DatabaseLike {\n prepare(sql: string): D1StmtLike\n}\nexport interface D1StmtLike {\n bind(...params: unknown[]): D1StmtLike\n run(): Promise<unknown>\n all<TRow = unknown>(): Promise<{ results?: TRow[] }>\n}\n\nconst RUNS_TABLE_DDL = (table: string) => `\n CREATE TABLE IF NOT EXISTS ${table}_runs (\n run_id TEXT PRIMARY KEY,\n started_at TEXT NOT NULL,\n halted_kind TEXT,\n halted_payload TEXT,\n ended_at TEXT\n )\n`\nconst TURNS_TABLE_DDL = (table: string) => `\n CREATE TABLE IF NOT EXISTS ${table}_turns (\n run_id TEXT NOT NULL,\n turn_index INTEGER NOT NULL,\n payload TEXT NOT NULL,\n PRIMARY KEY (run_id, turn_index)\n )\n`\nconst TURNS_INDEX_DDL = (table: string) => `\n CREATE INDEX IF NOT EXISTS idx_${table}_turns_run ON ${table}_turns (run_id, turn_index)\n`\n\n/**\n * SQL-backed ConversationJournal. Two tables — runs (one row per runId, holds\n * start/halt timestamps + halt reason) and turns (one row per committed turn,\n * payload is the ConversationTurn JSON). Replays the turns table on\n * `loadRun` and writes append-only per `appendTurn`.\n */\nexport class SqlConversationJournal implements ConversationJournal {\n /**\n * @param db SQL adapter (D1, postgres, sqlite, libSQL — all work)\n * @param table Table-name prefix; the journal creates `${table}_runs` and\n * `${table}_turns`. Lets multiple journals share a database\n * without colliding (e.g. one per product surface).\n */\n constructor(\n private readonly db: SqlAdapter,\n private readonly table: string = 'agent_runtime_journal',\n ) {}\n\n /**\n * Create the journal's tables if absent. Idempotent. Call once at deploy\n * (or at app boot) — running on every request is harmless but adds latency.\n */\n async migrate(): Promise<void> {\n await this.db.exec(RUNS_TABLE_DDL(this.table))\n await this.db.exec(TURNS_TABLE_DDL(this.table))\n await this.db.exec(TURNS_INDEX_DDL(this.table))\n }\n\n async loadRun(runId: string): Promise<ConversationJournalEntry | undefined> {\n const runs = await this.db.query<{\n run_id: string\n started_at: string\n halted_kind: string | null\n halted_payload: string | null\n ended_at: string | null\n }>(\n `SELECT run_id, started_at, halted_kind, halted_payload, ended_at FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n const row = runs[0]\n if (!row) return undefined\n const turns = await this.db.query<{ payload: string; turn_index: number }>(\n `SELECT payload, turn_index FROM ${this.table}_turns WHERE run_id = ? ORDER BY turn_index ASC`,\n [runId],\n )\n return {\n runId: row.run_id,\n startedAt: row.started_at,\n halted: row.halted_payload ? (JSON.parse(row.halted_payload) as HaltReason) : undefined,\n endedAt: row.ended_at ?? undefined,\n turns: turns.map((t) => JSON.parse(t.payload) as ConversationTurn),\n }\n }\n\n async beginRun(runId: string, startedAt: string): Promise<void> {\n const existing = await this.db.query<{ started_at: string }>(\n `SELECT started_at FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n if (existing.length > 0) {\n if (existing[0]?.started_at !== startedAt) {\n throw new Error(\n `runId '${runId}' already exists with startedAt=${existing[0]?.started_at}; refusing to overwrite with ${startedAt}`,\n )\n }\n return\n }\n await this.db.exec(`INSERT INTO ${this.table}_runs (run_id, started_at) VALUES (?, ?)`, [\n runId,\n startedAt,\n ])\n }\n\n async appendTurn(runId: string, turn: ConversationTurn): Promise<void> {\n const halted = await this.db.query<{ halted_kind: string | null }>(\n `SELECT halted_kind FROM ${this.table}_runs WHERE run_id = ?`,\n [runId],\n )\n if (halted.length === 0) {\n throw new Error(\n `appendTurn called for unknown runId '${runId}'; call beginRun first or use the runner which handles it`,\n )\n }\n if (halted[0]?.halted_kind) {\n throw new Error(\n `cannot append turn to halted run '${runId}' (halt kind: ${halted[0]?.halted_kind})`,\n )\n }\n await this.db.exec(\n `INSERT INTO ${this.table}_turns (run_id, turn_index, payload) VALUES (?, ?, ?)`,\n [runId, turn.index, JSON.stringify(turn)],\n )\n }\n\n async recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void> {\n const rs = await this.db.exec(\n `UPDATE ${this.table}_runs SET halted_kind = ?, halted_payload = ?, ended_at = ? WHERE run_id = ?`,\n [halt.kind, JSON.stringify(halt), endedAt, runId],\n )\n if (rs.rowsAffected === 0) {\n throw new Error(`recordHalt called for unknown runId '${runId}'`)\n }\n }\n}\n","/**\n * `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`\n * (the agent under test) as a multi-round conversation driven by a PERSONA (the\n * simulated user), over the persistent conversation transcript.\n *\n * It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an\n * LLM role-playing the user from its facts) — `runConversation` runs the two\n * against each other. Scripted persona turns are kept as a deterministic\n * fast-path. Only the WORKER is metered (it is the side under test); the\n * persona-driver is the test harness, not billed against the agent.\n *\n * `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops\n * straight into `runProfileMatrix({ dispatch })` — the same loop serves a single\n * cell and the whole matrix, replacing the per-agent hand-rolled\n * `dispatchWithSurface` bridges.\n */\n\nimport type { AgentProfile, MaximumCharge } from '@tangle-network/agent-eval'\nimport type {\n DispatchContext,\n ProfileDispatchFn,\n Scenario,\n} from '@tangle-network/agent-eval/campaign'\nimport { createIterableBackend } from '../backends'\nimport { createProfileExecutionBackend } from '../runtime/profile-execution-backend'\nimport type { ExecutorFactory } from '../runtime/supervise/types'\nimport type { AgentExecutionBackend, RuntimeStreamEvent } from '../types'\nimport { defineConversation } from './define-conversation'\nimport { runConversation } from './run-conversation'\nimport type { ConversationTurn, HaltPredicate, HaltReason } from './types'\n\n/** A persona that drives the conversation: either a full driver `AgentProfile`\n * (an LLM user-sim) or a deterministic script of user turns (the fast-path). */\nexport type PersonaDriver =\n | { kind: 'profile'; profile: AgentProfile }\n | { kind: 'scripted'; turns: string[] }\n\nexport interface RunPersonaConversationOptions {\n /** The agent under test. Metered; its rendered prompt leads its turns. */\n worker: AgentProfile\n /** The simulated user driving the dialogue. */\n persona: PersonaDriver\n /** Resolve transport/executable ports for the exact profile. Runtime still materializes the\n * profile and owns every model call. Applied to the worker and a profile-driven persona. */\n executorFor: (profile: AgentProfile, role: 'worker' | 'persona') => ExecutorFactory<unknown>\n /** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`\n * (worker answers each user turn). REQUIRED for a `profile` persona. */\n maxTurns?: number\n /** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */\n seed?: string\n /** Content-based \"until satisfied\" halt, called after every turn. `maxTurns` is the\n * hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */\n haltOn?: HaltPredicate\n signal?: AbortSignal\n /** Worker participant / transcript speaker label. Default 'agent'. */\n workerName?: string\n}\n\nexport interface PersonaConversationResult {\n transcript: ConversationTurn[]\n turns: number\n halted: HaltReason\n /** Worker-only spend (the side under test). */\n costUsd: number\n tokensIn: number\n tokensOut: number\n /** Absent means every worker call reported complete token usage. */\n tokensKnown?: false\n /** Absent means every worker call reported provider-billed cost, including a known zero. */\n costUsdKnown?: false\n}\n\ninterface UsageCounter {\n tokensIn: number\n tokensOut: number\n costUsd: number\n sawLlmCall: boolean\n tokensKnown: boolean\n usdKnown: boolean\n}\n\n/** Adapt one exact profile + Runtime executor into the conversation stream protocol. */\nfunction profileRuntimeBackend(\n profile: AgentProfile,\n factory: ExecutorFactory<unknown>,\n counter?: UsageCounter,\n): AgentExecutionBackend {\n const backend = createProfileExecutionBackend({ profile, executor: factory })\n if (!counter) return backend\n return {\n ...backend,\n async *stream(input, context) {\n for await (const event of backend.stream(input, context)) {\n if (event.type === 'llm_call') {\n counter.sawLlmCall = true\n counter.tokensIn += event.tokensIn ?? 0\n counter.tokensOut += event.tokensOut ?? 0\n counter.costUsd += event.costUsd ?? 0\n if (\n event.tokensKnown === false ||\n event.tokensIn === undefined ||\n event.tokensOut === undefined\n ) {\n counter.tokensKnown = false\n }\n if (event.usdKnown === false || event.costUsd === undefined) {\n counter.usdKnown = false\n }\n }\n yield event\n }\n },\n }\n}\n\n/** A persona participant that replays scripted user turns in order. */\nfunction scriptedPersonaBackend(turns: readonly string[]): AgentExecutionBackend {\n let idx = 0\n return createIterableBackend({\n kind: 'persona-user',\n async *stream(_input, context) {\n const text = turns[idx]\n if (text === undefined) {\n throw new Error(\n `persona-user: ran out of scripted turns at index ${idx} (had ${turns.length})`,\n )\n }\n idx += 1\n yield {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: new Date().toISOString(),\n } satisfies RuntimeStreamEvent\n },\n })\n}\n\n/**\n * Run one worker profile against one persona as a multi-round conversation.\n * The persona leads (participant 0): it speaks, the worker answers, repeat,\n * until `maxTurns`. Returns the persistent transcript + worker-only usage.\n */\nexport async function runPersonaConversation(\n opts: RunPersonaConversationOptions,\n): Promise<PersonaConversationResult> {\n const counter: UsageCounter = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n sawLlmCall: false,\n // Both flags start true and are lowered by the first unproven reading. They only reach a\n // result when `sawLlmCall` is true (see the terminal read below), so an unmetered\n // conversation never publishes them as a measured zero.\n tokensKnown: true,\n usdKnown: true,\n }\n const workerName = opts.workerName ?? 'agent'\n const worker = profileRuntimeBackend(\n opts.worker,\n opts.executorFor(opts.worker, 'worker'),\n counter,\n )\n\n let persona: AgentExecutionBackend\n let maxTurns: number\n if (opts.persona.kind === 'scripted') {\n if (opts.persona.turns.length === 0) {\n throw new Error('runPersonaConversation: scripted persona has no turns')\n }\n persona = scriptedPersonaBackend(opts.persona.turns)\n maxTurns = opts.maxTurns ?? 2 * opts.persona.turns.length\n } else {\n persona = profileRuntimeBackend(\n opts.persona.profile,\n opts.executorFor(opts.persona.profile, 'persona'),\n )\n if (opts.maxTurns === undefined) {\n throw new Error('runPersonaConversation: maxTurns is required for a profile-driven persona')\n }\n maxTurns = opts.maxTurns\n }\n\n const conversation = defineConversation({\n // Persona leads (participant 0): the seed routes to it, it produces the\n // user turn, the worker answers, alternate.\n participants: [\n { name: 'user', backend: persona },\n { name: workerName, backend: worker },\n ],\n policy: { maxTurns, turnOrder: 'alternate', ...(opts.haltOn ? { haltOn: opts.haltOn } : {}) },\n })\n const result = await runConversation(conversation, {\n seed: opts.seed ?? 'Begin.',\n signal: opts.signal,\n })\n // Worker-only cost. Prefer the worker's own metered llm_call spend. Fall back\n // to the engine's aggregate spend ONLY for a scripted persona — there the\n // harness has no LLM cost so the aggregate IS the worker's. For a\n // profile-driven persona the aggregate also includes the persona-driver's\n // spend, so attributing it to the worker would over-count; report the\n // worker's metered spend (0 if its backend reported none) instead.\n const fallbackCostKnown =\n !counter.sawLlmCall && opts.persona.kind === 'scripted' && result.spentCreditsCents > 0\n const costUsd = fallbackCostKnown ? result.spentCreditsCents / 100 : counter.costUsd\n const tokensKnown = counter.sawLlmCall && counter.tokensKnown\n const costUsdKnown = counter.sawLlmCall ? counter.usdKnown : fallbackCostKnown\n return {\n transcript: result.transcript,\n turns: result.turns,\n halted: result.halted,\n costUsd,\n tokensIn: counter.tokensIn,\n tokensOut: counter.tokensOut,\n ...(tokensKnown ? {} : { tokensKnown: false }),\n ...(costUsdKnown ? {} : { costUsdKnown: false }),\n }\n}\n\nexport interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {\n /** Resolve transport/executable ports for each exact profile. */\n executorFor: (profile: AgentProfile, role: 'worker' | 'persona') => ExecutorFactory<unknown>\n /** The persona driving each scenario — a driver profile or scripted turns. */\n personaOf: (scenario: TScenario) => PersonaDriver\n /** Build the scored artifact from the finished transcript. */\n artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact\n /** Speaker-turn cap (required when a persona is profile-driven). */\n maxTurns?: (scenario: TScenario) => number\n seed?: (scenario: TScenario) => string\n workerName?: string\n /** Provider- or executor-enforced maximum for the whole worker conversation.\n * Required before execution when the enclosing campaign is cost-capped. */\n maximumCharge?:\n | MaximumCharge\n | ((worker: AgentProfile, scenario: TScenario) => MaximumCharge | undefined)\n}\n\n/**\n * Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for\n * `runProfileMatrix`: the profile axis is the worker-under-test, the scenario\n * axis is the persona, and the runner is the cell. Meters the worker through\n * `ctx.cost` so the matrix's backend-integrity guard sees real usage.\n */\nexport function runPersonaDispatch<TScenario extends Scenario, TArtifact>(\n config: RunPersonaConfig<TScenario, TArtifact>,\n): ProfileDispatchFn<TScenario, TArtifact> {\n return async (\n worker: AgentProfile,\n scenario: TScenario,\n ctx: DispatchContext,\n ): Promise<TArtifact> => {\n const model = worker.model?.default ?? 'unknown'\n const maximumCharge =\n typeof config.maximumCharge === 'function'\n ? config.maximumCharge(worker, scenario)\n : config.maximumCharge\n const paid = await ctx.cost.runPaidCall({\n channel: 'agent',\n actor: 'persona-conversation',\n model,\n signal: ctx.signal,\n ...(maximumCharge ? { maximumCharge } : {}),\n execute: (executionSignal) =>\n runPersonaConversation({\n worker,\n persona: config.personaOf(scenario),\n executorFor: config.executorFor,\n maxTurns: config.maxTurns?.(scenario),\n seed: config.seed?.(scenario),\n signal: executionSignal,\n workerName: config.workerName,\n }),\n receipt: (result) => ({\n model,\n inputTokens: result.tokensIn,\n outputTokens: result.tokensOut,\n ...(result.tokensKnown === false ? { usageUnknown: true } : {}),\n ...(result.costUsdKnown === false\n ? { costUnknown: true }\n : { actualCostUsd: result.costUsd }),\n }),\n })\n if (!paid.succeeded) throw paid.error\n const result = paid.value\n return config.artifactOf(result.transcript, scenario)\n }\n}\n","/**\n * Build-prompt starting points for the two buildable artifact types. There is\n * NO `toolGenerator`/`mcpGenerator` wrapper — the factory is `agenticGenerator`\n * + a verifier (docs/artifact-lifecycle-frontier.md), so a tool or an MCP\n * server is built by composing the pieces directly:\n *\n * // a tool:\n * agenticGenerator({ profile, executorForWorktree, buildPrompt: toolBuildPrompt,\n * verify: commandVerifier('pnpm', ['test']) })\n * // an MCP server:\n * agenticGenerator({ profile, executorForWorktree, buildPrompt: mcpBuildPrompt,\n * verify: mcpServeVerifier({ command: 'node', args: ['server.mjs'] }) })\n *\n * These are the only type-specific bit (the phrasing that points the agent at a\n * tool vs. an MCP); the worktree, resume-on-failure loop, and improvement-loop\n * wrapper are shared. MCP is the load-bearing target — it is how a harness\n * acquires tools; raw tools matter where we control the loader.\n */\n\nimport type { ProposalFinding } from '@tangle-network/agent-eval'\nimport { optimizerMethod } from './optimizer-prompt'\n\n/** Evidence supplied to a generated tool or MCP build instruction. */\nexport interface BuildPromptFindingsInput {\n findings: ReadonlyArray<ProposalFinding>\n}\n\n/** Render findings as the ranked-evidence block every build prompt ends with. */\nexport function findingLines(findings: ReadonlyArray<ProposalFinding>): string[] {\n return findings.map((f) => {\n const where = f.subject ? ` [${f.subject}]` : ''\n const action = f.recommended_action ? ` → ${f.recommended_action}` : ''\n return `- (${f.severity})${where} ${f.claim}${action}`\n })\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new tool. */\nexport function toolBuildPrompt(args: BuildPromptFindingsInput): string {\n return [\n 'You are building a new TOOL for this codebase — a capability the agent measurably lacks,',\n 'evidenced by the failure findings at the bottom. The tool is an experiment: after it is',\n 'built and verified, its marginal lift is measured on held-out tasks, and only a real lift',\n 'promotes it.',\n '',\n optimizerMethod,\n '',\n 'THE SURFACE — what a deliverable tool looks like here:',\n '- ONE small, self-contained module PLUS tests that exercise its contract (what callers rely',\n ' on), not its internals. The tests are the experiment for sub-goal correctness — write the',\n ' test that would fail if your hypothesis about the gap were wrong.',\n '- It must compile and its tests must pass — they run automatically; on failure you get the',\n ' verifier output and another attempt, resuming on top of your own edits (fix in place, do',\n ' not start over).',\n '- Match the codebase grain: reuse its existing helpers, style, and test framework; a tool',\n ' that fights the codebase is the wrong tool even if it passes.',\n '- Do not commit; leave the changes in the working tree.',\n '',\n 'FINDINGS — ranked evidence from real failed runs (the gaps the tool must close):',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new MCP server. */\nexport function mcpBuildPrompt(args: BuildPromptFindingsInput): string {\n return [\n 'You are building a new MCP SERVER (Model Context Protocol) exposing tool(s) that close the',\n 'capability gaps evidenced by the failure findings at the bottom, so any harness can mount',\n 'them. The server is an experiment: after it is built and boot-verified, its marginal lift is',\n 'measured on held-out tasks, and only a real lift promotes it.',\n '',\n optimizerMethod,\n '',\n 'RESEARCH FIRST — ADOPT BEFORE BUILD: you may discover and ADOPT an existing external MCP',\n 'server if it fits the gaps better than building one. Registries and vendor docs list',\n 'maintained servers for most common capabilities (web search, fetch, GitHub, filesystems,',\n 'databases). To adopt, deliver a short adoption note instead of an implementation: the',\n \"server's launch command or HTTP endpoint, and the API key it needs BY NAME (e.g.\",\n 'EXA_API_KEY) — never a key value; provisioning injects the value at materialize time. If',\n 'your environment has no web access, decide from what you already know and say so.',\n '',\n 'THE SURFACE — what a deliverable MCP server looks like here (checked by BOOTING it):',\n '- it starts over stdio and answers the MCP `initialize` handshake,',\n '- `tools/list` returns at least one tool with a valid input schema,',\n '- newline-delimited JSON-RPC 2.0, protocol version 2024-11-05,',\n '- a clear start command (a package.json `start` script or an obvious entrypoint).',\n 'Design the tool surface for the FINDINGS, not for generality: each exposed tool should map to',\n 'a named failure mechanism, with a description that tells the agent when to reach for it (a',\n 'tool the agent never calls measures zero). If the boot-and-probe fails you get the error and',\n 'another attempt, resuming on top of your own edits. Do not commit; leave the changes in the',\n 'working tree.',\n '',\n 'FINDINGS — ranked evidence from real failed runs (the capabilities the server must provide):',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n","/**\n * `mcpServeVerifier` — the intrinsic verifier for a built MCP server: the\n * boot-and-probe checker named in docs/artifact-lifecycle-frontier.md. A\n * generated MCP server is only a candidate if it actually *serves* — so this\n * boots it over stdio (the default local MCP transport) and runs the real\n * handshake: `initialize` → `notifications/initialized` → `tools/list`, and\n * asserts the server answers with at least `minTools` tools.\n *\n * The spawn + handshake is the SHARED same-host stdio connection\n * (`connectStdioMcp`) — the same code path that later serves the built server\n * LIVE to a scored run (`materializeLocalMcp`), so \"verified it serves\" and\n * \"served while scored\" can never drift apart.\n *\n * Outcomes follow the `Verifier` contract: a server that fails to start, exits\n * early, errors the handshake, times out, or exposes no tools is a FAILED\n * candidate (`{ok:false}`, fed back into the next generation shot); a missing\n * start binary or spawn fault THROWS (a setup bug, never a silent fallback).\n */\n\nimport {\n connectStdioMcp,\n McpSpawnFault,\n type StdioMcpConnection,\n} from '../runtime/stdio-mcp-client'\nimport type { Verifier, VerifyResult } from './agentic-generator'\n\nexport interface McpServeSpec {\n /** Command that starts the built MCP server in the worktree (stdio transport). */\n command: string\n args?: string[]\n /** Extra env for the server process (merged over `process.env`). */\n env?: Record<string, string>\n /** Handshake timeout (ms). Default 30s. */\n timeoutMs?: number\n /** Minimum tools the server must expose to pass. Default 1. */\n minTools?: number\n}\n\n/** Build a `Verifier` that boots a generated MCP server over stdio and checks it exposes tools. */\nexport function mcpServeVerifier(spec: McpServeSpec): Verifier {\n const minTools = spec.minTools ?? 1\n\n return async (worktreePath: string): Promise<VerifyResult> => {\n let conn: StdioMcpConnection\n try {\n conn = await connectStdioMcp({\n command: spec.command,\n ...(spec.args ? { args: spec.args } : {}),\n cwd: worktreePath,\n ...(spec.env ? { env: spec.env } : {}),\n ...(spec.timeoutMs !== undefined ? { timeoutMs: spec.timeoutMs } : {}),\n })\n } catch (err) {\n if (err instanceof McpSpawnFault) {\n throw new Error(`mcpServeVerifier: ${err.message}`)\n }\n // Crash-on-boot / handshake error / timeout: a failed candidate, with the\n // connection's stderr-tailed message as the feedback for the next shot.\n return { ok: false, feedback: err instanceof Error ? err.message : String(err) }\n }\n try {\n if (conn.tools.length < minTools) {\n return {\n ok: false,\n feedback: `tools/list returned ${conn.tools.length} tool(s), need >= ${minTools}`,\n }\n }\n return { ok: true }\n } finally {\n await conn.close()\n }\n }\n}\n","import { isDeepStrictEqual } from 'node:util'\nimport { canonicalJson } from '@tangle-network/agent-eval'\nimport {\n type GepaOptimizationMethodConfig,\n gepaOptimizationMethod,\n type JudgeScore,\n type OptimizationMethod,\n type SkillOptOptimizationMethodConfig,\n skillOptOptimizationMethod,\n} from '@tangle-network/agent-eval/campaign'\nimport { canonicalCandidateDigest } from '../candidate-execution/digest'\nimport { ConfigError } from '../errors'\nimport {\n defaultRedactor,\n defaultRedactorIdentityMaterial,\n type Redactor,\n resolveRedactor,\n} from '../redact'\nimport type {\n ImproveCandidateValidationInput,\n ImproveMethodContext,\n ImproveMethodFactory,\n} from './improve'\nimport { withMethodRuntimeControls } from './method-controls'\n\nconst defaultMaxFindingsChars = 50_000\nconst pythonClientDocs = 'https://github.com/tangle-network/agent-eval/tree/main/clients/python'\nconst bridgeInstall = '`python -m pip install \"agent-eval-rpc==0.145.0\"`'\nconst gepaWheelInstall = '`python -m pip install \"gepa[full]==0.1.4\"`'\nconst gepaSourceInstall =\n '`python -m pip install \"gepa[full] @ git+https://github.com/gepa-ai/gepa.git@f919db0a622e2e9f9204779b81fe00cc1b2d808f\"`'\nconst skillOptInstall =\n `${bridgeInstall}, then ` +\n '`python -m pip install \"skillopt @ git+https://github.com/microsoft/SkillOpt.git@61735e3922efc2b90c6d6cab561e62e98452ca90\"`'\n\n/** Runtime context appended to an official optimizer's own configuration. */\nexport interface OfficialOptimizerContextOptions {\n /** Context supplied to the optimizer before Runtime appends the profile surface and findings. */\n background?: string\n /** Include current trace or analyst findings in the optimizer background. Default true. */\n includeFindings?: boolean\n /** Reject oversized serialized findings before starting Python. Default 50,000 characters. */\n maxFindingsChars?: number\n /**\n * Redact caller-supplied context and descriptors before they leave Runtime.\n * The built-in redactor is the default. Pass `false` only for public data\n * that has already been reviewed.\n */\n redact?: Redactor | false\n /** Authorize one exact candidate containing structurally sensitive fields.\n * The callback must return true for every accepted baseline and candidate. */\n authorizeSensitiveCandidate?: (input: OfficialSensitiveCandidateInput) => boolean\n}\n\nexport interface OfficialSensitiveCandidateInput extends ImproveCandidateValidationInput {\n sensitivePaths: readonly string[]\n}\n\n/** Official GEPA configuration plus bounded Runtime findings context. */\nexport type OfficialGepaOptions<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n> = Omit<GepaOptimizationMethodConfig<TScenario, TArtifact>, 'background' | 'evaluationId'> &\n OfficialOptimizerContextOptions\n\n/** Official SkillOpt configuration plus bounded Runtime findings context. */\nexport type OfficialSkillOptOptions<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n> = Omit<SkillOptOptimizationMethodConfig<TScenario, TArtifact>, 'background' | 'evaluationId'> &\n OfficialOptimizerContextOptions\n\n/** Missing optional Python dependencies for an official optimizer. */\nexport class OfficialOptimizerUnavailableError extends ConfigError {\n readonly optimizer: 'gepa' | 'skillopt'\n\n constructor(optimizer: 'gepa' | 'skillopt', cause: unknown) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n const install =\n optimizer === 'gepa'\n ? [\n `Install the Python bridge: ${bridgeInstall}.`,\n `The direct GEPA engine uses the published wheel: ${gepaWheelInstall}.`,\n `Composed recipes and source-only engines use the tested source revision: ${gepaSourceInstall}.`,\n ].join(' ')\n : `Install Microsoft SkillOpt: ${skillOptInstall}.`\n super(\n [\n `Official ${optimizer === 'gepa' ? 'GEPA' : 'SkillOpt'} could not start.`,\n 'Runtime did not use a local fallback.',\n install,\n `Setup: ${pythonClientDocs}.`,\n `Cause: ${detail}`,\n ].join(' '),\n { cause },\n )\n this.optimizer = optimizer\n }\n}\n\n/**\n * Build a complete method backed by GEPA's official Optimize Anything API.\n *\n * The recipe is passed through unchanged. Use `engine`, `sequential`,\n * `adaptive-sequential`, `best-of`, `vote`, or `omni` explicitly.\n */\nexport function officialGepa<TScenario extends { id: string; kind: string }, TArtifact = unknown>(\n options: OfficialGepaOptions<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n return officialOptimizer<TScenario, TArtifact, OfficialGepaOptions<TScenario, TArtifact>>(\n 'gepa',\n options,\n (config) => gepaOptimizationMethod(config),\n )\n}\n\n/** Build a complete method backed by Microsoft's official SkillOpt trainer. */\nexport function officialSkillOpt<\n TScenario extends { id: string; kind: string },\n TArtifact = unknown,\n>(\n options: OfficialSkillOptOptions<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n return officialOptimizer<TScenario, TArtifact, OfficialSkillOptOptions<TScenario, TArtifact>>(\n 'skillopt',\n options,\n (config) => skillOptOptimizationMethod(config),\n )\n}\n\ntype PreparedOptimizerContext<TScenario extends { id: string; kind: string }, TArtifact> = Pick<\n GepaOptimizationMethodConfig<TScenario, TArtifact>,\n 'objective' | 'evaluationId' | 'background' | 'describeScenario' | 'describeArtifact'\n>\n\n/** Keep evidence redaction, identity, dependency errors, and candidate controls identical for both wrappers. */\nfunction officialOptimizer<\n TScenario extends { id: string; kind: string },\n TArtifact,\n TOptions extends\n | OfficialGepaOptions<TScenario, TArtifact>\n | OfficialSkillOptOptions<TScenario, TArtifact>,\n>(\n optimizer: 'gepa' | 'skillopt',\n options: TOptions,\n create: (\n config: Omit<\n TOptions,\n keyof OfficialOptimizerContextOptions | 'describeScenario' | 'describeArtifact'\n > &\n PreparedOptimizerContext<TScenario, TArtifact>,\n ) => OptimizationMethod<TScenario, TArtifact>,\n): ImproveMethodFactory<TScenario, TArtifact> {\n const label = optimizer === 'gepa' ? 'officialGepa' : 'officialSkillOpt'\n const {\n background,\n includeFindings = true,\n maxFindingsChars,\n describeScenario,\n describeArtifact,\n redact,\n authorizeSensitiveCandidate,\n ...config\n } = options\n const redactor = resolveRedactor(redact)\n const redactionPolicyRef = optimizerRedactionPolicyRef(redact)\n assertMaxFindingsChars(label, maxFindingsChars)\n const objective = redactOptimizerText(label, 'objective', config.objective, redactor)\n return (context) => {\n const externalEvaluationRef = optimizerEvidencePolicyRef({\n runtimeEvaluationRef: context.evaluationRef,\n redactionPolicyRef,\n describeScenario,\n describeArtifact,\n authorizeSensitiveCandidate,\n })\n const method = withDependencyHelp(\n optimizer,\n externalEvaluationRef,\n redactor,\n redactionPolicyRef,\n create({\n ...config,\n objective,\n evaluationId: externalEvaluationRef,\n background: methodBackground({\n context,\n background,\n includeFindings,\n maxFindingsChars,\n label,\n redactor,\n }),\n ...(describeScenario\n ? {\n describeScenario: (scenario) =>\n redactOptimizerEvidence(\n label,\n 'scenario descriptor',\n describeScenario(scenario),\n redactor,\n ),\n }\n : {}),\n ...(describeArtifact\n ? {\n describeArtifact: (artifact, scenario) =>\n redactOptimizerEvidence(\n label,\n 'artifact descriptor',\n describeArtifact(artifact, scenario),\n redactor,\n ),\n }\n : {}),\n }),\n )\n return withMethodRuntimeControls(method, {\n costAttribution: 'optimizer-run',\n validateCandidate: (input) =>\n assertSafeOptimizerCandidate(label, input, authorizeSensitiveCandidate),\n })\n }\n}\n\nfunction assertMaxFindingsChars(label: string, value: number | undefined): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new ConfigError(`${label}: maxFindingsChars must be a positive safe integer`)\n }\n}\n\nfunction methodBackground(options: {\n context: ImproveMethodContext\n background: string | undefined\n includeFindings: boolean\n maxFindingsChars: number | undefined\n label: string\n redactor: Redactor\n}): string {\n const {\n context,\n background,\n includeFindings,\n maxFindingsChars = defaultMaxFindingsChars,\n label,\n redactor,\n } = options\n const safeBackground =\n background === undefined\n ? undefined\n : redactOptimizerText(label, 'background', background, redactor)\n const safeProfileName =\n context.profile.name === undefined\n ? undefined\n : redactOptimizerText(label, 'profile name', context.profile.name, redactor)\n const sections = [\n safeBackground?.trim(),\n safeProfileName\n ? `Agent profile: ${safeProfileName}. Surface: ${context.surface}.`\n : `Agent surface: ${context.surface}.`,\n ].filter((value): value is string => Boolean(value))\n if (includeFindings && context.findings.length > 0) {\n let serialized: string\n try {\n serialized = canonicalJson(\n redactOptimizerEvidence(label, 'findings', context.findings, redactor),\n )\n } catch (cause) {\n throw new ConfigError(`${label}: findings must be JSON-serializable`, { cause })\n }\n if (serialized.length > maxFindingsChars) {\n throw new ConfigError(\n `${label}: serialized findings exceed maxFindingsChars (${serialized.length} > ${maxFindingsChars})`,\n )\n }\n sections.push(`Observed failures:\\n${serialized}`)\n }\n return sections.join('\\n\\n')\n}\n\nfunction assertSafeOptimizerCandidate(\n label: string,\n input: ImproveCandidateValidationInput,\n authorizeSensitiveCandidate: ((input: OfficialSensitiveCandidateInput) => boolean) | undefined,\n): void {\n const redactedValue = defaultRedactor(input.value)\n const redactedSurface = defaultRedactor(input.candidateSurface)\n if (\n !isDeepStrictEqual(input.value, redactedValue) ||\n !isDeepStrictEqual(input.candidateSurface, redactedSurface)\n ) {\n throw new ConfigError(\n `${label}: the selected profile surface contains a common credential or private value. ` +\n 'Store live credentials as provider references, or remove private data before starting an external optimizer.',\n )\n }\n const sensitivePaths = sensitiveProfileSurfacePaths(input)\n if (sensitivePaths.length === 0) return\n let authorized = false\n if (authorizeSensitiveCandidate) {\n try {\n authorized =\n authorizeSensitiveCandidate(\n Object.freeze({\n ...input,\n sensitivePaths: Object.freeze([...sensitivePaths]),\n }),\n ) === true\n } catch (cause) {\n throw new ConfigError(`${label}: sensitive candidate authorization failed`, { cause })\n }\n }\n if (!authorized) {\n throw new ConfigError(\n `${label}: the selected profile surface contains fields that may carry private values: ` +\n `${sensitivePaths.slice(0, 8).join(', ')}. Remove them, replace values with safe references, ` +\n 'or authorize the exact profile with authorizeSensitiveCandidate.',\n )\n }\n}\n\nfunction sensitiveProfileSurfacePaths(input: ImproveCandidateValidationInput): string[] {\n const paths = new Set<string>()\n if (\n input.surface === 'tools' ||\n input.surface === 'mcp' ||\n input.surface === 'hooks' ||\n input.surface === 'subagents' ||\n input.surface === 'agent-profile'\n ) {\n paths.add('$')\n }\n const seen = new WeakSet<object>()\n const visit = (current: unknown, path: string): void => {\n if (current === null || typeof current !== 'object') return\n if (seen.has(current)) return\n seen.add(current)\n if (Array.isArray(current)) {\n current.forEach((child, index) => {\n visit(child, `${path}[${index}]`)\n })\n return\n }\n for (const [key, child] of Object.entries(current as Record<string, unknown>)) {\n const childPath = `${path}.${key}`\n if (['env', 'headers', 'url', 'metadata', 'extensions'].includes(key.toLowerCase())) {\n paths.add(childPath)\n continue\n }\n visit(child, childPath)\n }\n }\n visit(input.value, '$')\n return [...paths]\n}\n\nfunction redactOptimizerEvidence(\n label: string,\n field: string,\n value: unknown,\n redactor: Redactor,\n): unknown {\n try {\n return redactor(value)\n } catch (cause) {\n throw new ConfigError(`${label}: ${field} redaction failed`, { cause })\n }\n}\n\nfunction redactOptimizerText(\n label: string,\n field: string,\n value: string,\n redactor: Redactor,\n): string {\n const redacted = redactOptimizerEvidence(label, field, value, redactor)\n if (typeof redacted !== 'string' || !redacted.trim()) {\n throw new ConfigError(`${label}: ${field} redaction must return a non-empty string`)\n }\n return redacted\n}\n\nfunction redactJudgeScore(score: JudgeScore, redactor: Redactor): JudgeScore {\n const notes = redactOptimizerEvidence('official optimizer', 'judge notes', score.notes, redactor)\n return {\n ...score,\n notes: typeof notes === 'string' ? notes : '[redacted]',\n }\n}\n\nexport function optimizerRedactionPolicyRef(\n redact: Redactor | false | undefined,\n builtInIdentity: unknown = defaultRedactorIdentityMaterial(),\n): string {\n if (redact === false) return 'caller-approved-raw'\n return canonicalCandidateDigest({\n kind: redact === undefined ? 'default-redactor' : 'caller-redactor-with-default',\n builtIn: builtInIdentity,\n ...(redact === undefined\n ? {}\n : {\n callerSource: Function.prototype.toString.call(redact),\n composition: Function.prototype.toString.call(resolveRedactor),\n }),\n })\n}\n\nfunction optimizerEvidencePolicyRef(input: {\n runtimeEvaluationRef: ImproveMethodContext['evaluationRef']\n redactionPolicyRef: string\n describeScenario: unknown\n describeArtifact: unknown\n authorizeSensitiveCandidate: unknown\n}): ReturnType<typeof canonicalCandidateDigest> {\n return canonicalCandidateDigest({\n runtimeEvaluationRef: input.runtimeEvaluationRef,\n redactionPolicyRef: input.redactionPolicyRef,\n describeScenario: callbackSource(input.describeScenario),\n describeArtifact: callbackSource(input.describeArtifact),\n authorizeSensitiveCandidate: callbackSource(input.authorizeSensitiveCandidate),\n })\n}\n\nfunction callbackSource(callback: unknown): string | null {\n return typeof callback === 'function' ? Function.prototype.toString.call(callback) : null\n}\n\nfunction withDependencyHelp<TScenario extends { id: string; kind: string }, TArtifact>(\n optimizer: 'gepa' | 'skillopt',\n evaluationRef: ImproveMethodContext['evaluationRef'],\n redactor: Redactor,\n redactionPolicyRef: string,\n method: OptimizationMethod<TScenario, TArtifact>,\n): OptimizationMethod<TScenario, TArtifact> {\n return {\n ...method,\n async optimize(input) {\n try {\n const judges = input.judges.map((judge) =>\n Object.freeze({\n ...judge,\n judgeVersion: canonicalCandidateDigest({\n evaluationRef,\n name: judge.name,\n dimensions: judge.dimensions,\n judgeVersion: judge.judgeVersion ?? null,\n outwardEvidence: redactionPolicyRef,\n }),\n async score(scoreInput: Parameters<typeof judge.score>[0]) {\n return redactJudgeScore(await judge.score(scoreInput), redactor)\n },\n }),\n )\n return await method.optimize({\n ...input,\n judges: Object.freeze(judges),\n })\n } catch (cause) {\n if (isMissingDependency(optimizer, cause)) {\n throw new OfficialOptimizerUnavailableError(optimizer, cause)\n }\n throw cause\n }\n },\n }\n}\n\nfunction isMissingDependency(optimizer: 'gepa' | 'skillopt', cause: unknown): boolean {\n const message = cause instanceof Error ? cause.message : String(cause)\n const common = [\n `${optimizer === 'gepa' ? 'GEPA' : 'SkillOpt'} bridge could not start`,\n 'source inspection could not start',\n \"No module named 'agent_eval_rpc'\",\n `No module named 'agent_eval_rpc.${optimizer === 'gepa' ? 'gepa_bridge' : 'skillopt_bridge'}'`,\n ]\n const specific =\n optimizer === 'gepa'\n ? [\n 'requires GEPA',\n \"requires GEPA's Optimize Anything\",\n \"No module named 'gepa'\",\n 'gepa is importable but its package metadata is unavailable',\n ]\n : [\n 'requires skillopt',\n 'requires SkillOpt',\n \"No module named 'skillopt'\",\n 'skillopt is importable but its package metadata is unavailable',\n ]\n return [...common, ...specific].some((fragment) => message.includes(fragment))\n}\n","import type { Scenario } from '@tangle-network/agent-eval/contract'\nimport {\n agentProfileSchema,\n canonicalAgentProfileDigest,\n type Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { immutableCandidateValue } from '../candidate-execution/digest'\nimport { ConfigError } from '../errors'\nimport { assertCandidateValidator, parseExecutionRef } from './candidate-validation'\nimport { improve } from './improve'\nimport type {\n ImproveCandidateValidator,\n ImproveMethodOptions,\n ImproveMethodResult,\n ImproveProfileAgent,\n} from './improve-types'\nimport type { ReadonlyAgentProfile } from './profile-types'\nimport type { ImproveTrainingOptions, ImproveTrainingResult } from './training'\n\nexport type ProfileImprovementHarnessTrainOptions = Omit<ImproveTrainingOptions, 'mode'>\n\nexport interface CreateProfileImprovementHarnessOptions<TScenario extends Scenario, TArtifact> {\n /** Exact baseline profile. It is parsed, detached, and frozen at construction. */\n profile: ReadonlyAgentProfile\n /**\n * Immutable identity of the bound executor, models, tools, component mapping,\n * and every closure or external setting that can change measured behavior.\n */\n executionRef: Sha256Digest\n /** Execute one exact materialized profile on one scenario. */\n agent: ImproveProfileAgent<TScenario, TArtifact>\n /** Optional validator shared by every run from this harness. */\n validateCandidate?: ImproveCandidateValidator\n}\n\nexport type ProfileImprovementHarnessRunOptions<TScenario extends Scenario, TArtifact> = Omit<\n ImproveMethodOptions<TScenario, TArtifact>,\n 'executionRef' | 'agent' | 'validateCandidate'\n> & {\n /** Override the harness-level validator for this run. */\n validateCandidate?: ImproveCandidateValidator\n}\n\n/**\n * A small, reusable front door over `improve(profile, options)`.\n *\n * The harness freezes the baseline and binds execution identity once, which\n * removes the two easiest sources of accidental experiment drift when a\n * developer runs several methods, surfaces, or held-out suites against the\n * same agent. It does not replace or narrow `improve`; callers retain every\n * method option and may still use the lower-level API directly.\n */\nexport interface ProfileImprovementHarness<TScenario extends Scenario, TArtifact> {\n /** Detached immutable baseline actually used by every run. */\n readonly profile: ReadonlyAgentProfile\n /** Canonical digest of the bound baseline profile. */\n readonly profileDigest: Sha256Digest\n /** Exact execution identity bound at construction. */\n readonly executionRef: Sha256Digest\n /** Train the bound profile with a separately pinned trainer and serving execution identity. */\n train(options: ProfileImprovementHarnessTrainOptions): Promise<ImproveTrainingResult>\n run(\n options: ProfileImprovementHarnessRunOptions<TScenario, TArtifact>,\n ): Promise<ImproveMethodResult>\n}\n\n/**\n * Bind one exact profile and executor into a repeatable self-improvement\n * harness. The returned `run` method remains generic over every existing\n * profile surface, optimization method, split, gate, and budget option.\n */\nexport function createProfileImprovementHarness<TScenario extends Scenario, TArtifact>(\n options: CreateProfileImprovementHarnessOptions<TScenario, TArtifact>,\n): ProfileImprovementHarness<TScenario, TArtifact> {\n const parsed = agentProfileSchema.safeParse(options.profile)\n if (!parsed.success) {\n throw new ConfigError(\n `createProfileImprovementHarness: invalid AgentProfile: ${parsed.error.message}`,\n )\n }\n if (typeof options.agent !== 'function') {\n throw new ConfigError('createProfileImprovementHarness: agent must be a function')\n }\n assertCandidateValidator(options.validateCandidate)\n\n const profile = immutableCandidateValue(parsed.data)\n const executionRef = parseExecutionRef(options.executionRef, 'createProfileImprovementHarness')\n const agent = options.agent\n const defaultValidator = options.validateCandidate\n const validatorFor = (validator: ImproveCandidateValidator | undefined) => {\n assertCandidateValidator(validator)\n return validator ?? defaultValidator\n }\n\n return Object.freeze({\n profile,\n profileDigest: canonicalAgentProfileDigest(profile),\n executionRef,\n train(trainOptions: ProfileImprovementHarnessTrainOptions) {\n const validateCandidate = validatorFor(trainOptions.validateCandidate)\n return improve(profile, {\n ...trainOptions,\n mode: 'training',\n ...(validateCandidate === undefined ? {} : { validateCandidate }),\n })\n },\n run(runOptions: ProfileImprovementHarnessRunOptions<TScenario, TArtifact>) {\n const validateCandidate = validatorFor(runOptions.validateCandidate)\n return improve(profile, {\n ...runOptions,\n executionRef,\n agent,\n ...(validateCandidate === undefined ? {} : { validateCandidate }),\n })\n },\n })\n}\n","import { agentProfileSchema } from '@tangle-network/agent-interface'\nimport { ConfigError } from '../errors'\nimport type { ImproveProfileComponents } from './improve-types'\nimport type { ReadonlyAgentProfile } from './profile-types'\n\n/** Stable component-name prefix used for `profile.prompt.instructions`. */\nexport const PROMPT_INSTRUCTION_COMPONENT_PREFIX = 'prompt.instruction:'\n\nconst COMPONENT_INDEX_WIDTH = 6\n\nfunction componentName(index: number): string {\n return `${PROMPT_INSTRUCTION_COMPONENT_PREFIX}${String(index).padStart(COMPONENT_INDEX_WIDTH, '0')}`\n}\n\nfunction orderedInstructionValues(components: Readonly<Record<string, string>>): string[] {\n const entries = Object.entries(components).sort(([left], [right]) => left.localeCompare(right))\n if (entries.length === 0) {\n throw new ConfigError(\n 'promptInstructionsProfileComponents: at least one prompt instruction is required',\n )\n }\n for (const [index, [name, value]] of entries.entries()) {\n const expected = componentName(index)\n if (name !== expected) {\n throw new ConfigError(\n `promptInstructionsProfileComponents: expected component ${JSON.stringify(expected)}, got ${JSON.stringify(name)}`,\n )\n }\n if (typeof value !== 'string') {\n throw new ConfigError(\n `promptInstructionsProfileComponents: component ${JSON.stringify(name)} must be a string`,\n )\n }\n }\n return entries.map(([, value]) => value)\n}\n\n/**\n * Canonical `ImproveProfileComponents` mapping for the ordered\n * `AgentProfile.prompt.instructions` list.\n *\n * Use it with `surface: 'agent-profile'` when an optimizer should rewrite the\n * exact instruction texts without being allowed to change their count, order,\n * labels, or any unrelated profile field:\n *\n * ```ts\n * await improve(profile, {\n * surface: 'agent-profile',\n * profileComponents: promptInstructionsProfileComponents,\n * // method, scenarios, judge, executionRef, agent, ...\n * })\n * ```\n *\n * Component names are zero-padded and stable. Runtime's existing component\n * materializer requires every candidate to preserve the exact key set and\n * verifies that `apply(read(profile))` reproduces the baseline profile. A\n * profile with no prompt instructions is refused rather than inventing a\n * sentinel instruction that could accidentally ship.\n */\nexport const promptInstructionsProfileComponents: ImproveProfileComponents = Object.freeze({\n read(profile: ReadonlyAgentProfile) {\n const instructions = profile.prompt?.instructions ?? []\n if (instructions.length === 0) {\n throw new ConfigError(\n 'promptInstructionsProfileComponents: profile.prompt.instructions must contain at least one instruction',\n )\n }\n return Object.fromEntries(\n instructions.map((instruction: string, index: number) => [componentName(index), instruction]),\n )\n },\n apply(\n profile: ReadonlyAgentProfile,\n components: Readonly<Record<string, string>>,\n ): ReadonlyAgentProfile {\n const instructions = orderedInstructionValues(components)\n return agentProfileSchema.parse({\n ...profile,\n prompt: {\n ...profile.prompt,\n instructions,\n },\n })\n },\n})\n","/**\n *\n * `reflectiveGenerator` — the cheap, no-sandbox `CandidateGenerator`. It drafts\n * surface edits via the existing improvement proposer (`proposeFromFindings`,\n * one LLM patch per finding) and applies them as ONE coherent improvement into\n * the candidate worktree. `maxShots` is ignored — reflection is single-shot by\n * construction (the patches are already drafted).\n *\n * This is the `shots=1, sandbox=off` code-candidate setting.\n * `agenticGenerator` supplies the multi-shot verify-in-session setting.\n *\n * @stable\n */\n\nimport { spawnSync } from 'node:child_process'\nimport { createHash } from 'node:crypto'\nimport { readFileSync, realpathSync } from 'node:fs'\nimport { isAbsolute, relative, resolve, sep } from 'node:path'\nimport type { SurfaceImprovementEdit } from '../agent/improvement-adapter'\nimport type { ImprovementProposalSource } from '../analyst-loop/types'\nimport type { CandidateGenerator } from './improvement-driver'\n\nexport interface ReflectiveGeneratorOptions {\n /** Bind proposal reads and paid calls to this candidate's worktree and account. */\n createImprovementProposalSource(\n context: Parameters<CandidateGenerator['generate']>[0],\n ): ImprovementProposalSource<SurfaceImprovementEdit>\n}\n\n/** Cheap no-sandbox `CandidateGenerator` (the `shots=1` setting): draft surface edits via the improvement adapter and apply them as one coherent candidate. */\nexport function reflectiveGenerator(opts: ReflectiveGeneratorOptions): CandidateGenerator {\n return {\n kind: 'reflective',\n async generate(context) {\n const { worktreePath, findings, signal } = context\n signal.throwIfAborted()\n const source = opts.createImprovementProposalSource(context)\n const batch = await source.proposeFromFindings(findings)\n signal.throwIfAborted()\n if (batch.errors.length > 0) {\n throw new AggregateError(\n batch.errors.map((error) => new Error(`${error.findingId}: ${error.message}`)),\n `reflectiveGenerator: proposal failed: ${batch.errors.map((error) => error.message).join('; ')}`,\n )\n }\n if (batch.edits.length === 0) return { applied: false, summary: '' }\n\n for (const edit of batch.edits) {\n assertPatchTarget(edit, worktreePath)\n assertCurrentBase(edit, worktreePath)\n }\n applyPatches(batch.edits, worktreePath)\n signal.throwIfAborted()\n\n const summary =\n batch.edits.length === 1\n ? batch.edits[0]!.summary\n : `analyst: ${batch.edits.length} surface edits`\n return { applied: true, summary }\n },\n }\n}\n\nfunction assertPatchTarget(edit: SurfaceImprovementEdit, cwd: string): void {\n // Reverse statistics include the source path of a rename or copy.\n for (const reverse of [false, true]) {\n const result = spawnSync(\n 'git',\n ['apply', '--numstat', '-z', '-p0', ...(reverse ? ['--reverse'] : []), '-'],\n { cwd, input: edit.patch, encoding: 'utf8' },\n )\n if (result.error) throw result.error\n if (result.status !== 0) {\n throw new Error(`reflectiveGenerator: invalid patch: ${result.stderr.trim()}`)\n }\n const paths = result.stdout\n .split('\\0')\n .filter(Boolean)\n .map((entry) => entry.slice(entry.indexOf('\\t', entry.indexOf('\\t') + 1) + 1))\n const target = resolve(cwd, edit.target.repoRelativePath)\n if (paths.length === 0 || paths.some((path) => resolve(cwd, path) !== target)) {\n throw new Error('reflectiveGenerator: patch paths do not match the declared target')\n }\n }\n}\n\nfunction assertCurrentBase(edit: SurfaceImprovementEdit, cwd: string): void {\n const root = realpathSync(cwd)\n const path = resolve(root, edit.target.repoRelativePath)\n assertWithinWorktree(root, path)\n let content: string\n try {\n assertWithinWorktree(root, realpathSync(path))\n content = readFileSync(path, 'utf8')\n } catch (error) {\n if (\n edit.target.intent !== 'create-new' ||\n !(error instanceof Error && 'code' in error && error.code === 'ENOENT')\n ) {\n throw error\n }\n content = ''\n }\n const actual = createHash('sha256').update(content, 'utf8').digest('hex')\n if (actual !== edit.baseSha256) {\n throw new Error(`reflectiveGenerator: stale proposal base for ${edit.target.repoRelativePath}`)\n }\n}\n\nfunction assertWithinWorktree(root: string, path: string): void {\n const local = relative(root, path)\n if (local === '..' || local.startsWith(`..${sep}`) || isAbsolute(local)) {\n throw new Error('reflectiveGenerator: proposal target is outside the candidate worktree')\n }\n}\n\nfunction applyPatches(edits: SurfaceImprovementEdit[], cwd: string): void {\n // Git applies the complete batch atomically unless --reject is requested.\n const result = spawnSync('git', ['apply', '-p0', '-'], {\n cwd,\n input: edits.map((edit) => `${edit.patch.trimEnd()}\\n`).join(''),\n encoding: 'utf-8',\n })\n if (result.error) throw result.error\n if (result.status !== 0) {\n throw new Error(`reflectiveGenerator: patch batch failed: ${result.stderr.trim()}`)\n }\n}\n","import type {\n AgentImprovementActivationOutcome,\n AgentImprovementActivationResult,\n AgentImprovementActivationTarget,\n Sha256Digest,\n} from '@tangle-network/agent-interface'\nimport { sha256DigestSchema } from '@tangle-network/agent-interface'\nimport {\n fromAgentCandidateKnowledgeRef,\n type KnowledgeImprovementMutationReceipt,\n loadKnowledgeImprovementActivationResult,\n type PromoteKnowledgeCandidateOptions,\n promoteKnowledgeCandidate,\n restoreKnowledgeCandidateBaseline,\n} from '@tangle-network/agent-knowledge'\n\nimport {\n type AgentImprovementActivationReconciliation,\n type AgentImprovementActivationResultStore,\n type AgentImprovementActivationTransition,\n type AgentImprovementActivationTransitionInput,\n createAgentImprovementActivationResult,\n} from '../intelligence/activation'\n\nexport interface CreateKnowledgeImprovementActivationExecutorOptions\n extends Omit<PromoteKnowledgeCandidateOptions, 'root' | 'candidate'> {\n root: string\n identity: string\n results: AgentImprovementActivationResultStore\n}\n\nexport interface KnowledgeImprovementActivationExecutor {\n transition: AgentImprovementActivationTransition\n reconcile: AgentImprovementActivationReconciliation\n}\n\n/** Apply or restore one local knowledge candidate through the shared activation contract. */\nexport function createKnowledgeImprovementActivationExecutor(\n options: CreateKnowledgeImprovementActivationExecutorOptions,\n): KnowledgeImprovementActivationExecutor {\n if (!options.identity.trim()) throw new Error('knowledge activation identity is required')\n return {\n reconcile: async (transition) => {\n const inspected = await inspectKnowledgeActivation(options, transition)\n return inspected.settled ? inspected.result : undefined\n },\n transition: async (transition) => {\n if (transition.expired) {\n throw new Error('knowledge write transition cannot run after authorization expires')\n }\n const inspected = await inspectKnowledgeActivation(options, transition)\n if (inspected.settled) return inspected.result\n\n const mutationOptions = {\n root: options.root,\n candidate: inspected.candidate,\n activation: {\n activation: transition.activation,\n attemptedAt: transition.attemptedAt,\n identity: options.identity,\n createResult: (receipt: KnowledgeImprovementMutationReceipt) =>\n inspected.create(\n knowledgeMutationOutcome(receipt, inspected, transition.activation.intent),\n ),\n },\n ...(options.ownerId ? { ownerId: options.ownerId } : {}),\n ...(options.leaseTtlMs === undefined ? {} : { leaseTtlMs: options.leaseTtlMs }),\n ...(options.now ? { now: options.now } : {}),\n ...(options.onState ? { onState: options.onState } : {}),\n }\n const improvement =\n transition.activation.intent === 'activate-candidate'\n ? await promoteKnowledgeCandidate(mutationOptions)\n : await restoreKnowledgeCandidateBaseline(mutationOptions)\n if (!improvement.activationResult) {\n throw new Error('knowledge mutation did not persist its shared activation result')\n }\n return options.results.putIfAbsent(improvement.activationResult)\n },\n }\n}\n\ntype CreateKnowledgeActivation = (\n outcome: AgentImprovementActivationOutcome,\n) => AgentImprovementActivationResult\n\ntype InspectedKnowledgeActivation =\n | { settled: true; result: unknown | undefined }\n | {\n settled: false\n target: AgentImprovementActivationTransitionInput['targets'][number]\n candidate: PromoteKnowledgeCandidateOptions['candidate']\n expectedDigest: Sha256Digest\n desiredDigest: Sha256Digest\n create: CreateKnowledgeActivation\n }\n\nasync function inspectKnowledgeActivation(\n options: CreateKnowledgeImprovementActivationExecutorOptions,\n transition: AgentImprovementActivationTransitionInput,\n): Promise<InspectedKnowledgeActivation> {\n const stored = await options.results.load(transition.activation.digest)\n if (stored !== undefined) return { settled: true, result: stored }\n\n const create: CreateKnowledgeActivation = (outcome) =>\n createAgentImprovementActivationResult(transition, {\n completedAt: completionTime(transition, options.now),\n outcome,\n })\n const store = (outcome: AgentImprovementActivationOutcome) =>\n options.results.putIfAbsent(create(outcome))\n if (transition.kind !== 'sealed-candidate') {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_PROFILE_TRANSITION_UNSUPPORTED',\n message: 'The knowledge adapter accepts only sealed knowledge candidates.',\n }),\n }\n }\n const target = supportedKnowledgeTarget(transition, options.identity)\n if (!target) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_TARGET_SET_UNSUPPORTED',\n message: 'The knowledge adapter requires exactly one matching knowledge target.',\n }),\n }\n }\n const knowledge = transition.candidateBundle.knowledge\n if (!knowledge) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'unsupported',\n code: 'KNOWLEDGE_CANDIDATE_MISSING',\n message: 'The measured candidate bundle does not contain a knowledge candidate.',\n }),\n }\n }\n const candidate = fromAgentCandidateKnowledgeRef(knowledge.candidate)\n const expectedDigest =\n transition.activation.intent === 'activate-candidate'\n ? knowledge.candidate.baseHash\n : knowledge.candidate.candidateHash\n const desiredDigest =\n transition.activation.intent === 'activate-candidate'\n ? knowledge.candidate.candidateHash\n : knowledge.candidate.baseHash\n if (target.expectedBaseDigest !== expectedDigest || target.desiredDigest !== desiredDigest) {\n if (transition.expired) return { settled: true, result: undefined }\n return {\n settled: true,\n result: await store({\n status: 'failed',\n code: 'KNOWLEDGE_TARGET_MISMATCH',\n message: 'The activation target does not match the measured knowledge candidate.',\n }),\n }\n }\n\n const durable = await loadKnowledgeImprovementActivationResult({\n root: options.root,\n candidate,\n activation: transition.activation,\n identity: options.identity,\n })\n if (durable) {\n return {\n settled: true,\n result: await options.results.putIfAbsent(durable),\n }\n }\n if (transition.expired) return { settled: true, result: undefined }\n return { settled: false, target, candidate, expectedDigest, desiredDigest, create }\n}\n\nfunction supportedKnowledgeTarget(\n transition: AgentImprovementActivationTransitionInput,\n identity: string,\n): AgentImprovementActivationTransitionInput['targets'][number] | undefined {\n if (transition.targets.length !== 1) return undefined\n const target = transition.targets[0]\n return target.surface === 'knowledge' && target.identity === identity ? target : undefined\n}\n\nfunction knowledgeMutationOutcome(\n receipt: KnowledgeImprovementMutationReceipt,\n inspected: Extract<InspectedKnowledgeActivation, { settled: false }>,\n intent: AgentImprovementActivationTransitionInput['activation']['intent'],\n): AgentImprovementActivationOutcome {\n const expectedTarget = intent === 'activate-candidate' ? 'candidate' : 'baseline'\n const beforeDigest = prefixedDigest(receipt.beforeHash)\n const afterDigest = prefixedDigest(receipt.afterHash)\n if (\n receipt.target !== expectedTarget ||\n receipt.changed !== (beforeDigest !== afterDigest) ||\n (!receipt.changed && (receipt.transactionId !== null || receipt.recovered))\n ) {\n throw new Error('knowledge mutation returned inconsistent state evidence')\n }\n if (receipt.changed) {\n if (\n receipt.transactionId === null ||\n beforeDigest !== inspected.expectedDigest ||\n afterDigest !== inspected.desiredDigest\n ) {\n throw new Error('knowledge activation did not apply its authorized content transition')\n }\n return {\n status: 'applied',\n transactionId: receipt.transactionId,\n targets: [\n {\n surface: inspected.target.surface,\n identity: inspected.target.identity,\n beforeDigest,\n afterDigest,\n },\n ],\n }\n }\n if (afterDigest === inspected.desiredDigest) {\n return {\n status: 'already-applied',\n targets: [targetState(inspected.target, afterDigest)],\n }\n }\n if (afterDigest === inspected.expectedDigest) {\n throw new Error('knowledge activation did not attempt its authorized content transition')\n }\n return {\n status: 'conflict',\n targets: [targetState(inspected.target, afterDigest)],\n }\n}\n\nfunction targetState(target: AgentImprovementActivationTarget, currentDigest: Sha256Digest) {\n return {\n surface: target.surface,\n identity: target.identity,\n currentDigest,\n }\n}\n\nfunction prefixedDigest(hash: string): Sha256Digest {\n return sha256DigestSchema.parse(`sha256:${hash}`)\n}\n\nfunction completionTime(\n transition: AgentImprovementActivationTransitionInput,\n now: (() => Date) | undefined,\n): string {\n const completedAt = (now ?? (() => new Date()))().toISOString()\n return Date.parse(completedAt) < Date.parse(transition.attemptedAt)\n ? transition.attemptedAt\n : completedAt\n}\n","import { agentProfileSchema } from '@tangle-network/agent-interface'\nimport type { RagKnowledgeUpdateResult } from '@tangle-network/agent-knowledge'\nimport type { DeliverableSpec } from '../runtime/supervise/completion-gate'\nimport { assertExecutableAgentProfile } from '../runtime/supervise/model-policy'\nimport type { ExecutorConfig } from '../runtime/supervise/runtime'\nimport { type SuperviseOptions, supervise } from '../runtime/supervise/supervise'\nimport type { SupervisorProfile } from '../runtime/supervise/supervisor-agent'\nimport type { Budget, SupervisedResult } from '../runtime/supervise/types'\n\n/** Standing prompt for a supervisor that grows a shared knowledge base through spawned researchers. */\nexport const RESEARCH_SUPERVISOR_SYSTEM_PROMPT = [\n 'You are a research supervisor. You do not answer the research question yourself.',\n 'You create and manage researcher workers that improve one shared knowledge base until it is ready.',\n '',\n 'Each round:',\n '1. Read the goal and the gaps the readiness check still reports.',\n '2. Decompose the open work into independent sub-topics.',\n '3. Spawn one researcher per sub-topic; split by sub-topic, never duplicate work.',\n '4. Wait for researchers to settle, steer or re-spawn thin sub-topics, then stop when the check passes.',\n '',\n 'Conserve the shared budget. Prefer a small number of well-scoped researchers over a large fanout that re-covers the same ground.',\n].join('\\n')\n\nexport interface KnowledgeReadinessCheckInput {\n root: string\n goal: string\n readinessSpecs?: readonly unknown[]\n readinessTaskId?: string\n readiness?: unknown\n}\n\nexport type KnowledgeReadinessCheckResult =\n | boolean\n | {\n ready: boolean\n summary?: string\n metadata?: Record<string, unknown>\n }\n\nexport type KnowledgeReadinessCheck = (\n input: KnowledgeReadinessCheckInput,\n) => Promise<KnowledgeReadinessCheckResult> | KnowledgeReadinessCheckResult\n\nexport interface SupervisedKnowledgeUpdateInput {\n goal?: string\n root?: string\n candidateRoot?: string\n findings?: readonly unknown[]\n metadata?: Record<string, unknown>\n}\n\nexport interface SupervisedKnowledgeUpdateResult {\n applied: boolean\n summary: string\n supervised: SupervisedResult<unknown>\n metadata: NonNullable<RagKnowledgeUpdateResult['metadata']>\n}\n\nexport interface SupervisedKnowledgeUpdateOptions {\n root: string\n goal: string\n readiness: KnowledgeReadinessCheck\n readinessSpecs?: readonly unknown[]\n readinessTaskId?: string\n readinessOptions?: unknown\n findings?: readonly unknown[]\n metadata?: Record<string, unknown>\n budget: Budget\n backend?: ExecutorConfig\n makeWorkerAgent?: SuperviseOptions['makeWorkerAgent']\n /** Caller-owned exact supervisor harness/provider/model identity. */\n supervisorProfile: SupervisorProfile\n superviseOptions?: Partial<\n Omit<\n SuperviseOptions,\n 'budget' | 'backend' | 'deliverable' | 'makeWorkerAgent' | 'allowedModels'\n >\n >\n allowedModels?: readonly string[]\n runSupervised?: (\n profile: SupervisorProfile,\n task: unknown,\n opts: SuperviseOptions,\n ) => Promise<SupervisedResult<unknown>>\n}\n\nexport type SupervisedKnowledgeUpdater = (\n input: SupervisedKnowledgeUpdateInput,\n) => Promise<SupervisedKnowledgeUpdateResult>\n\n/** Build the completion check a supervised KB update uses to stop only when the KB is ready. */\nexport function knowledgeReadinessDeliverable(\n options: Pick<\n SupervisedKnowledgeUpdateOptions,\n 'root' | 'goal' | 'readiness' | 'readinessSpecs' | 'readinessTaskId' | 'readinessOptions'\n >,\n): DeliverableSpec<unknown> {\n return {\n describe: `knowledge base at ${options.root} is ready for: ${options.goal}`,\n async check() {\n const result = await options.readiness({\n root: options.root,\n goal: options.goal,\n readinessSpecs: options.readinessSpecs,\n readinessTaskId: options.readinessTaskId,\n readiness: options.readinessOptions,\n })\n return typeof result === 'boolean' ? result : result.ready\n },\n }\n}\n\n/** Create an `improveKnowledgeBase` update callback backed by runtime supervision. */\nexport function createSupervisedKnowledgeUpdater(\n options: SupervisedKnowledgeUpdateOptions,\n): SupervisedKnowledgeUpdater {\n return (input) =>\n runSupervisedKnowledgeUpdate({\n ...options,\n root: input.candidateRoot ?? input.root ?? options.root,\n goal: input.goal ?? options.goal,\n findings: input.findings ?? options.findings,\n metadata: { ...options.metadata, ...input.metadata },\n })\n}\n\n/** Run a runtime supervisor that updates one candidate knowledge base and stops on readiness. */\nexport async function runSupervisedKnowledgeUpdate(\n options: SupervisedKnowledgeUpdateOptions,\n): Promise<SupervisedKnowledgeUpdateResult> {\n const exactSupervisor = agentProfileSchema.parse(options.supervisorProfile) as SupervisorProfile\n assertExecutableAgentProfile(exactSupervisor, 'runSupervisedKnowledgeUpdate')\n const run = options.runSupervised ?? supervise\n const task = formatSupervisedKnowledgeTask(options)\n const supervised = await run(exactSupervisor, task, {\n ...options.superviseOptions,\n budget: options.budget,\n backend: options.backend,\n deliverable: knowledgeReadinessDeliverable(options),\n makeWorkerAgent: options.makeWorkerAgent,\n allowedModels: options.allowedModels,\n })\n return {\n applied: supervised.kind === 'winner',\n summary:\n supervised.kind === 'winner'\n ? 'research supervisor completed and the knowledge base passed readiness'\n : `research supervisor stopped without a ready knowledge base: ${supervised.reason}`,\n supervised,\n metadata: {\n supervised: true,\n root: options.root,\n goal: options.goal,\n result: supervised.kind,\n },\n }\n}\n\n/** Format the supervisor task with the KB root, readiness requirements, current findings, and metadata. */\nexport function formatSupervisedKnowledgeTask(\n options: Pick<\n SupervisedKnowledgeUpdateOptions,\n 'root' | 'goal' | 'readinessSpecs' | 'readinessTaskId' | 'findings' | 'metadata'\n >,\n): string {\n const sections = [\n `Goal: ${options.goal}`,\n `Knowledge base root: ${options.root}`,\n options.readinessTaskId ? `Readiness task id: ${options.readinessTaskId}` : undefined,\n options.readinessSpecs?.length\n ? `Readiness specs:\\n${JSON.stringify(options.readinessSpecs, null, 2)}`\n : undefined,\n options.findings?.length\n ? `Current findings:\\n${JSON.stringify(options.findings, null, 2)}`\n : undefined,\n options.metadata && Object.keys(options.metadata).length > 0\n ? `Metadata:\\n${JSON.stringify(options.metadata, null, 2)}`\n : undefined,\n ].filter((section): section is string => Boolean(section))\n return `${sections.join('\\n\\n')}\\n\\nUpdate files under the knowledge base root only. Stop when the readiness check passes.`\n}\n","import { realpath } from 'node:fs/promises'\nimport {\n type AgentCandidateBundle,\n type AgentCandidateCapturedArtifact,\n type AgentCandidateKnowledge,\n agentCandidateKnowledgeSchema,\n} from '@tangle-network/agent-interface'\nimport {\n type BuildEvalKnowledgeBundleOptions,\n evaluateKnowledgeBaseReadiness,\n improveKnowledgeBase,\n type KnowledgeBaseQualityOptions,\n type KnowledgeImprovementOptions,\n type KnowledgeImprovementResult,\n type KnowledgeReadinessSpec,\n knowledgeImprovementCandidateRef,\n normalizeKnowledgeStateScope,\n toAgentCandidateKnowledgeRef,\n withKnowledgeImprovementComparison,\n} from '@tangle-network/agent-knowledge'\nimport { sealAgentCandidateBundle } from '../candidate-execution/bundle'\nimport {\n canonicalCandidateBytes,\n embeddedCandidateArtifact,\n omitTopLevelDigest,\n} from '../candidate-execution/digest'\nimport { persistCandidateOutputArtifact } from '../candidate-execution/output-artifacts'\nimport type { AgentCandidateOutputArtifactPort } from '../candidate-execution/types'\nimport { captureAgentCandidateWorkspace } from '../candidate-execution/workspace-archive'\nimport type { ExecutorConfig } from '../runtime/supervise/runtime'\nimport type { SuperviseOptions } from '../runtime/supervise/supervise'\nimport type { SupervisorProfile } from '../runtime/supervise/supervisor-agent'\nimport type { Budget, SupervisedResult } from '../runtime/supervise/types'\nimport {\n createSupervisedKnowledgeUpdater,\n type KnowledgeReadinessCheck,\n type KnowledgeReadinessCheckResult,\n type SupervisedKnowledgeUpdateOptions,\n} from './supervised-update'\n\nexport interface RunKnowledgeImprovementJobOptions\n extends Omit<KnowledgeImprovementOptions, 'updateKnowledge'> {\n budget: Budget\n readinessCheck?: KnowledgeReadinessCheck\n backend?: ExecutorConfig\n makeWorkerAgent?: SuperviseOptions['makeWorkerAgent']\n supervisorProfile: SupervisorProfile\n superviseOptions?: Partial<\n Omit<\n SuperviseOptions,\n 'budget' | 'backend' | 'deliverable' | 'makeWorkerAgent' | 'allowedModels'\n >\n >\n allowedModels?: readonly string[]\n runSupervised?: (\n profile: SupervisorProfile,\n task: unknown,\n opts: SuperviseOptions,\n ) => Promise<SupervisedResult<unknown>>\n candidateArtifacts?: AgentCandidateOutputArtifactPort\n onMeasurement?: (measurement: KnowledgeImprovementJobMeasurement) => Promise<void> | void\n}\n\nexport interface KnowledgeImprovementJobMeasurement {\n startedAt: string\n finishedAt: string\n durationMs: number\n updateCalls: number\n updateDurationMs: number\n supervisedSpent: {\n iterations: number\n inputTokens: number\n outputTokens: number\n usdKnown: boolean\n usd: number\n ms: number\n }\n}\n\nexport interface KnowledgeImprovementJobResult {\n improvement: KnowledgeImprovementResult\n knowledge?: KnowledgeImprovementCandidatePair\n measurement: KnowledgeImprovementJobMeasurement\n blocked: boolean\n}\n\nexport interface KnowledgeImprovementCandidatePair {\n reference: AgentCandidateKnowledge['candidate']\n stateScope?: AgentCandidateKnowledge['stateScope']\n evaluation: AgentCandidateCapturedArtifact\n baseline: AgentCandidateKnowledge['snapshot']\n candidate: AgentCandidateKnowledge['snapshot']\n}\n\nexport interface KnowledgeImprovementExperimentBundles {\n baseline: AgentCandidateBundle\n candidate: AgentCandidateBundle\n}\n\nexport interface AgentKnowledgeReadinessCheckOptions {\n goal: string\n readinessSpecs?: readonly KnowledgeReadinessSpec[]\n readinessTaskId?: string\n readiness?: Omit<BuildEvalKnowledgeBundleOptions, 'taskId' | 'index' | 'specs'>\n strict?: boolean\n kbQuality?: KnowledgeBaseQualityOptions\n}\n\n/** Build the default readiness check backed by `@tangle-network/agent-knowledge` validation and scoring. */\nexport function createAgentKnowledgeReadinessCheck(\n options: AgentKnowledgeReadinessCheckOptions,\n): KnowledgeReadinessCheck {\n return async (input): Promise<KnowledgeReadinessCheckResult> => {\n const readiness = await evaluateKnowledgeBaseReadiness({\n root: input.root,\n goal: input.goal ?? options.goal,\n readinessSpecs:\n (input.readinessSpecs as readonly KnowledgeReadinessSpec[] | undefined) ??\n options.readinessSpecs,\n readinessTaskId: input.readinessTaskId ?? options.readinessTaskId,\n readiness:\n (input.readiness as AgentKnowledgeReadinessCheckOptions['readiness'] | undefined) ??\n options.readiness,\n strict: options.strict,\n kbQuality: options.kbQuality,\n })\n return {\n ready: readiness.ready,\n summary: readiness.summary,\n metadata: {\n dimensions: readiness.dimensions,\n validationOk: readiness.validation.ok,\n kbQualityOk: readiness.kbQuality.ok,\n blockingMissing: readiness.readiness?.report.blockingMissingRequirements.length ?? 0,\n },\n }\n }\n}\n\n/** Produce a frozen KB candidate while leaving live knowledge content unchanged. */\nexport async function runKnowledgeImprovementJob(\n options: RunKnowledgeImprovementJobOptions,\n): Promise<KnowledgeImprovementJobResult> {\n const {\n allowedModels,\n backend,\n budget,\n candidateArtifacts,\n makeWorkerAgent,\n onMeasurement,\n readinessCheck,\n runSupervised,\n supervisorProfile,\n superviseOptions,\n ...knowledgeOptions\n } = options\n const startedAtMs = Date.now()\n const startedAt = new Date(startedAtMs).toISOString()\n const supervisedSpent = emptySpent()\n let updateCalls = 0\n let updateDurationMs = 0\n\n const readiness = readinessCheck ?? createAgentKnowledgeReadinessCheck(options)\n const updateKnowledge = createSupervisedKnowledgeUpdater({\n root: options.root,\n goal: options.goal,\n readiness,\n readinessSpecs: options.readinessSpecs,\n readinessTaskId: options.readinessTaskId,\n readinessOptions: options.readiness,\n budget,\n backend,\n makeWorkerAgent,\n supervisorProfile,\n superviseOptions,\n allowedModels,\n runSupervised,\n } satisfies SupervisedKnowledgeUpdateOptions)\n\n const instrumentedUpdateKnowledge: KnowledgeImprovementOptions['updateKnowledge'] = async (\n input,\n ) => {\n const updateStartedAt = Date.now()\n updateCalls += 1\n const result = await updateKnowledge(input)\n updateDurationMs += Date.now() - updateStartedAt\n addSpent(supervisedSpent, result.supervised)\n return result\n }\n const resolvedImprovement = await improveKnowledgeBase({\n ...knowledgeOptions,\n updateKnowledge: instrumentedUpdateKnowledge,\n })\n let knowledge: KnowledgeImprovementCandidatePair | undefined\n if (\n resolvedImprovement.candidate?.status === 'candidate-ready' ||\n resolvedImprovement.candidate?.status === 'promoted'\n ) {\n knowledge = await freezeKnowledgeCandidatePair(\n options.root,\n resolvedImprovement,\n candidateArtifacts,\n knowledgeOptions.signal,\n )\n }\n const finishedAtMs = Date.now()\n const measurement: KnowledgeImprovementJobMeasurement = {\n startedAt,\n finishedAt: new Date(finishedAtMs).toISOString(),\n durationMs: finishedAtMs - startedAtMs,\n updateCalls,\n updateDurationMs,\n supervisedSpent,\n }\n await onMeasurement?.(measurement)\n return {\n improvement: resolvedImprovement,\n ...(knowledge ? { knowledge } : {}),\n measurement,\n blocked: resolvedImprovement.blocked,\n }\n}\n\n/** Attach both frozen knowledge inputs to one otherwise-identical bundle pair. */\nexport function buildKnowledgeImprovementExperimentBundles(\n bundle: AgentCandidateBundle,\n knowledge: KnowledgeImprovementCandidatePair,\n): KnowledgeImprovementExperimentBundles {\n const input = omitTopLevelDigest(bundle)\n const withSnapshot = (snapshot: AgentCandidateKnowledge['snapshot']) =>\n agentCandidateKnowledgeSchema.parse({\n candidate: knowledge.reference,\n ...(knowledge.stateScope ? { stateScope: knowledge.stateScope } : {}),\n snapshot,\n evaluation: knowledge.evaluation,\n })\n return Object.freeze({\n baseline: sealAgentCandidateBundle({ ...input, knowledge: withSnapshot(knowledge.baseline) }),\n candidate: sealAgentCandidateBundle({ ...input, knowledge: withSnapshot(knowledge.candidate) }),\n })\n}\n\nasync function freezeKnowledgeCandidatePair(\n root: string,\n improvement: KnowledgeImprovementResult,\n artifacts: AgentCandidateOutputArtifactPort | undefined,\n signal: AbortSignal | undefined,\n): Promise<KnowledgeImprovementCandidatePair> {\n const candidate = knowledgeImprovementCandidateRef(improvement)\n const candidateRef = toAgentCandidateKnowledgeRef(candidate)\n return withKnowledgeImprovementComparison({ root, candidate }, async (comparison) => {\n const freeze = async (\n target: 'baseline' | 'candidate',\n ): Promise<AgentCandidateKnowledge['snapshot']> => {\n const executionId = `knowledge-${candidate.candidateId}-${target}`\n const captured = await captureAgentCandidateWorkspace(\n await realpath(comparison[target].root),\n {\n ...(artifacts\n ? {\n artifactPersistence: {\n executionId,\n outputArtifacts: artifacts,\n ...(signal ? { signal } : {}),\n },\n }\n : {}),\n },\n )\n return captured.snapshot\n }\n const evaluation = await captureKnowledgeEvidence(\n canonicalCandidateBytes({\n kind: 'agent-knowledge-candidate-evaluation',\n candidate: candidateRef,\n metric: comparison.evaluation,\n }),\n 'knowledge-evaluation',\n `knowledge-${candidate.candidateId}`,\n artifacts,\n signal,\n )\n const normalizedScope = normalizeKnowledgeStateScope(comparison.stateScope)\n const defaultScope = normalizeKnowledgeStateScope()\n const stateScope =\n normalizedScope.pagesDirectory === defaultScope.pagesDirectory &&\n normalizedScope.researchState === defaultScope.researchState\n ? undefined\n : Object.freeze(normalizedScope)\n const baseline = await freeze('baseline')\n const proposed = await freeze('candidate')\n return Object.freeze({\n reference: candidateRef,\n ...(stateScope ? { stateScope } : {}),\n evaluation,\n baseline,\n candidate: proposed,\n })\n })\n}\n\nasync function captureKnowledgeEvidence(\n bytes: Uint8Array,\n purpose: 'knowledge-evaluation',\n executionId: string,\n artifacts: AgentCandidateOutputArtifactPort | undefined,\n signal: AbortSignal | undefined,\n): Promise<AgentCandidateCapturedArtifact> {\n if (!artifacts) return embeddedCandidateArtifact(bytes)\n return persistCandidateOutputArtifact(artifacts, {\n executionId,\n purpose,\n bytes,\n ...(signal ? { signal } : {}),\n })\n}\n\n/** The starting accumulator, before any supervised run has been folded in. Zero iterations means\n * nothing ran, so a zero dollar total IS the measured amount; `addSpent` lowers `usdKnown` as\n * soon as it folds a run whose own dollars were not proven. */\nfunction emptySpent(): KnowledgeImprovementJobMeasurement['supervisedSpent'] {\n return { iterations: 0, inputTokens: 0, outputTokens: 0, usdKnown: true, usd: 0, ms: 0 }\n}\n\nfunction addSpent(\n target: KnowledgeImprovementJobMeasurement['supervisedSpent'],\n result: SupervisedResult<unknown>,\n): void {\n const spent = result.spentTotal\n target.iterations += spent.iterations\n target.inputTokens += spent.tokens.input\n target.outputTokens += spent.tokens.output\n target.usdKnown = target.usdKnown && spent.usdKnown !== false\n target.usd += spent.usd\n target.ms += spent.ms\n}\n","/**\n *\n * Chat-model resolution + catalog validation — the shared primitive every\n * product chat handler needs and was, until now, hand-rolling. Lifts the\n * router `/v1/models` fetch, the fail-closed id validation, and the\n * precedence resolver out of four near-identical per-repo copies.\n *\n * Policy-free by design: callers pass their own precedence order\n * (`resolveChatModel`) and their own known-good `allowlist`\n * (`validateChatModelId`), so each product keeps its resolution policy while\n * sharing the catalog fetch, the malformed-id guard, and the fail-closed\n * admission rule. No React, no `process.env` assumption — `env` is an\n * explicit narrow record so this runs unchanged in Node and in Workers.\n *\n * @stable\n */\n\n/**\n * A model entry as returned by the Tangle Router `/v1/models` endpoint.\n * Intentionally minimal — only the fields resolution + validation read.\n */\nexport interface ModelInfo {\n id: string\n name?: string\n description?: string\n /** Provider slug, when the router exposes it (`provider` or `_provider`). */\n provider?: string\n _provider?: string\n architecture?: {\n modality?: string\n input_modalities?: string[]\n output_modalities?: string[]\n }\n}\n\n/** Env keys the router base URL is resolved from. */\nexport interface RouterEnv {\n TANGLE_ROUTER_URL?: string\n TANGLE_ROUTER_BASE_URL?: string\n}\n\n/** Default Tangle Router base URL used when no env override is set. */\nexport const DEFAULT_ROUTER_BASE_URL = 'https://router.tangle.tools'\n\n/** Resolve the router base URL from env, normalised — no trailing `/v1` or `/`. */\nexport function resolveRouterBaseUrl(env: RouterEnv = {}): string {\n return (env.TANGLE_ROUTER_URL ?? env.TANGLE_ROUTER_BASE_URL ?? DEFAULT_ROUTER_BASE_URL)\n .replace(/\\/v1\\/?$/, '')\n .replace(/\\/$/, '')\n}\n\n/**\n * Fetch the model catalog from the router's `/v1/models`. Throws on a non-2xx\n * response — callers decide whether to fail open (empty catalog) or closed.\n */\nexport async function getModels(\n routerBaseUrl: string = DEFAULT_ROUTER_BASE_URL,\n): Promise<ModelInfo[]> {\n const res = await fetch(`${routerBaseUrl}/v1/models`, {\n headers: { Accept: 'application/json' },\n })\n if (!res.ok) throw new Error(`router /v1/models ${res.status}`)\n const body = (await res.json()) as { data?: ModelInfo[] }\n return Array.isArray(body.data) ? body.data : []\n}\n\n/** Trim a candidate model id; `undefined` for non-strings and blanks. */\nexport function cleanModelId(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nexport interface ChatModelCandidate {\n /** Stable label for telemetry — e.g. `request`, `workspace`, `env`. */\n source: string\n model: string | undefined\n}\n\nexport interface ResolvedChatModel {\n source: string\n model: string\n}\n\n/**\n * Resolve a chat model by precedence: the first candidate carrying a\n * non-blank model wins, else `fallback`. The caller owns the precedence\n * order, so each product keeps its own policy (request → workspace → env,\n * etc.) while the first-non-blank logic and the telemetry shape stay shared.\n */\nexport function resolveChatModel(\n candidates: ChatModelCandidate[],\n fallback: ResolvedChatModel,\n): ResolvedChatModel {\n for (const candidate of candidates) {\n const model = cleanModelId(candidate.model)\n if (model) return { source: candidate.source, model }\n }\n return fallback\n}\n\nexport type ChatModelValidation =\n | { succeeded: true; value: string }\n | { succeeded: false; error: string }\n\nconst WELL_FORMED_MODEL_ID = /^[A-Za-z0-9._/@:-]+$/\n\nfunction isWellFormedModelId(modelId: string): boolean {\n return modelId.length <= 200 && WELL_FORMED_MODEL_ID.test(modelId)\n}\n\n/**\n * Every id a catalog entry can be addressed by — its bare id, plus a\n * `provider/id` form when the router exposes a separate provider slug.\n */\nfunction catalogIdsForModel(model: ModelInfo): string[] {\n const ids = new Set<string>()\n const id = cleanModelId(model.id)\n if (id) ids.add(id)\n const provider = cleanModelId(model._provider) ?? cleanModelId(model.provider)\n if (provider && id && !id.includes('/')) ids.add(`${provider}/${id}`)\n return [...ids]\n}\n\n/**\n * Validate a caller-supplied chat-model id. Rejects non-strings, malformed\n * ids, and ids absent from both the caller's `allowlist` and the live router\n * catalog. Fails closed: when the catalog cannot be fetched, an unverifiable\n * id is rejected rather than admitted — a bad model never reaches the agent.\n */\nexport async function validateChatModelId(\n modelId: unknown,\n options: {\n /**\n * Known-good ids that skip the catalog round trip — e.g. the product's\n * default model plus any env-configured ids.\n */\n allowlist?: string[]\n routerBaseUrl?: string\n /** Injectable catalog loader — overridden in tests. */\n loadModels?: (routerBaseUrl: string) => Promise<ModelInfo[]>\n } = {},\n): Promise<ChatModelValidation> {\n const {\n allowlist = [],\n routerBaseUrl = DEFAULT_ROUTER_BASE_URL,\n loadModels = getModels,\n } = options\n\n const cleaned = cleanModelId(modelId)\n if (!cleaned) return { succeeded: false, error: 'Model id must be a non-empty string.' }\n if (!isWellFormedModelId(cleaned)) {\n return { succeeded: false, error: `Model id is malformed: ${cleaned}` }\n }\n if (allowlist.some((id) => cleanModelId(id) === cleaned)) {\n return { succeeded: true, value: cleaned }\n }\n\n let catalog: ModelInfo[]\n try {\n catalog = await loadModels(routerBaseUrl)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n return { succeeded: false, error: `Could not validate model catalog: ${message}` }\n }\n\n const ids = new Set(catalog.flatMap(catalogIdsForModel))\n if (!ids.has(cleaned)) return { succeeded: false, error: `Model is not available: ${cleaned}` }\n return { succeeded: true, value: cleaned }\n}\n","/**\n *\n * Pure readiness-decision helper. Maps a `KnowledgeReadinessReport` from\n * `@tangle-network/agent-eval` to a three-state branch (`ready` / `blocked` /\n * `caveat`) the runtime, route handlers, and UI shells can all switch on.\n *\n * Default `minimumScore` of 0.7 mirrors the readiness scoring scale in\n * agent-eval; callers tightening or loosening this should keep it consistent\n * across all entry points for the same product so the UI / metrics agree on\n * what \"caveat\" means.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { ValidationError } from './errors'\nimport type { KnowledgeReadinessDecision } from './types'\n\nconst DEFAULT_MINIMUM_READINESS_SCORE = 0.7\n\n/**\n * Map a `KnowledgeReadinessReport` to a three-state branch (`ready` / `blocked` / `caveat`) the runtime, route handlers, and UI shells all switch on.\n *\n * @stable\n */\nexport function decideKnowledgeReadiness(\n report: KnowledgeReadinessReport,\n options: { minimumScore?: number } = {},\n): KnowledgeReadinessDecision {\n const minimumScore = options.minimumScore ?? DEFAULT_MINIMUM_READINESS_SCORE\n if (!Number.isFinite(minimumScore) || minimumScore < 0 || minimumScore > 1) {\n throw new ValidationError(\n `minimumScore must be a finite number in [0, 1]; received ${String(minimumScore)}`,\n )\n }\n const blockingGapIds = report.blockingMissingRequirements.map((requirement) => requirement.id)\n const nonBlockingGapIds = report.nonBlockingGaps.map((requirement) => requirement.id)\n if (blockingGapIds.length > 0) {\n return {\n passed: false,\n status: 'blocked',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n if (report.readinessScore < minimumScore) {\n return {\n passed: false,\n status: 'caveat',\n reason: `Knowledge readiness score ${report.readinessScore.toFixed(3)} is below minimum ${minimumScore.toFixed(3)}.`,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n return {\n passed: true,\n status: 'ready',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n}\n","/**\n *\n * The two top-level entry points:\n *\n * - `runAgentTask` — single-shot lifecycle for adapter-driven tasks.\n * - `runAgentTaskStream` — streaming lifecycle that delegates execution to an\n * `AgentExecutionBackend` (model API, sandbox, or custom iterable).\n *\n * Both gate the run on `KnowledgeReadinessReport` from `agent-eval`, emit the\n * same lifecycle event vocabulary (under different shapes — see `types.ts`),\n * and route session lifecycle through a pluggable `RuntimeSessionStore`.\n *\n * @stable\n */\n\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n FAILURE_CLASSES,\n type FailureClass,\n type KnowledgeReadinessReport,\n type RunRecord,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nconst FAILURE_CLASS_SET = new Set<string>(FAILURE_CLASSES)\n\n/** True when a free-form control failure string is a canonical taxonomy\n * class — so only real taxonomy tags are promoted to the cross-agent\n * `RunRecord.failureClass` key; novel strings stay as `failureMode` detail. */\nfunction asFailureClass(value: string | undefined): FailureClass | undefined {\n return value && FAILURE_CLASS_SET.has(value) ? (value as FailureClass) : undefined\n}\n\n/** Stamp cross-cutting defaults onto adapter-projected RunRecords without\n * overriding anything the adapter set explicitly:\n * - `scenarioId` — the run's scenario, when the record omits one.\n * - `failureClass` — the control layer's failure classification promoted\n * onto the canonical cross-agent key, but ONLY when it's a real taxonomy\n * class. This is what lets the substrate aggregate failures across every\n * agent in one vocabulary instead of per-agent ad-hoc strings. */\nexport function applyRunRecordDefaults(\n records: RunRecord[],\n scenarioId: string,\n controlFailureClass: string | undefined,\n): RunRecord[] {\n const fc = asFailureClass(controlFailureClass)\n return records.map((record) => {\n let r = record\n if (r.scenarioId === undefined) r = { ...r, scenarioId }\n if (r.failureClass === undefined && fc) r = { ...r, failureClass: fc }\n return r\n })\n}\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { BackendTransportError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { nowIso, startOrResumeRuntimeSession, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskSpec,\n AgentTaskStatus,\n BackendErrorDetail,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeStreamEvent,\n} from './types'\n\n/**\n * Single-shot task lifecycle for adapter-driven tasks: readiness-gated, emits the runtime lifecycle event vocabulary, session-store pluggable.\n *\n * @stable\n */\nexport async function runAgentTask<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RunAgentTaskOptions<TState, TAction, TActionResult, TEval>,\n): Promise<AgentTaskRunResult<TState, TAction, TActionResult, TEval>> {\n const task = options.task\n await emit(options.onEvent, { type: 'task_start', task })\n await emit(options.onEvent, { type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflight(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n options.onEvent,\n )\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n await emit(options.onEvent, { type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n }\n\n await emit(options.onEvent, { type: 'control_start', task, knowledge })\n const scenarioId = options.scenarioId ?? task.id\n const control = await runAgentControlLoop<TState, TAction, TActionResult, TEval>({\n intent: task.intent,\n budget: task.budget,\n signal: options.signal,\n store: options.store,\n scenarioId,\n projectId: options.projectId,\n variantId: options.variantId,\n observe: ({ history, abortSignal }) =>\n options.adapter.observe({ task, knowledge, history, abortSignal }),\n validate: async ({ state, history, abortSignal }) => {\n const readinessEval = blockingKnowledgeEval(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n const evals = await options.adapter.validate({\n task,\n knowledge,\n state,\n history,\n abortSignal,\n })\n return [readinessEval as TEval, ...evals]\n },\n decide: (ctx) => {\n if (isKnowledgeBlocked(ctx.evals)) {\n return (\n options.adapter.onKnowledgeBlocked?.({\n task,\n knowledge,\n questions,\n acquisitionPlans,\n }) ?? {\n type: 'stop',\n pass: false,\n score: knowledge.readinessScore,\n reason: `knowledge readiness blocked: ${knowledge.reason}`,\n }\n )\n }\n return options.adapter.decide(toAgentContext(task, knowledge, ctx))\n },\n act: (action, ctx) => options.adapter.act(action, toAgentContext(task, knowledge, ctx)),\n shouldStop: options.adapter.shouldStop\n ? (ctx) => options.adapter.shouldStop!(toAgentContext(task, knowledge, ctx))\n : undefined,\n getActionCostUsd: options.adapter.getActionCostUsd\n ? ({ action, result, state, evals, history }) =>\n options.adapter.getActionCostUsd!({ action, result, task, state, evals, history })\n : undefined,\n onStep: (step) => emit(options.onEvent, { type: 'control_step', task, step }),\n })\n await emit(options.onEvent, { type: 'control_end', task, control })\n const status = statusFromControl(control)\n await emit(options.onEvent, { type: 'task_end', task, status, reason: control.reason })\n\n return {\n task,\n status,\n knowledge,\n questions,\n acquisitionPlans,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n control,\n runRecords: applyRunRecordDefaults(\n options.adapter.projectRunRecords?.(control, task) ?? [],\n scenarioId,\n control.failureClass,\n ),\n }\n}\n\n/**\n * Streaming task lifecycle: delegates execution to an `AgentExecutionBackend` (model API, sandbox, or custom iterable) and yields lifecycle events as they happen.\n *\n * @stable\n */\nexport async function* runAgentTaskStream<TInput extends AgentBackendInput = AgentBackendInput>(\n options: RunAgentTaskStreamOptions<TInput>,\n): AsyncIterable<RuntimeStreamEvent> {\n const task = options.task\n const input = { task, ...(options.input ?? {}) } as TInput\n yield streamEvent({ type: 'task_start', task })\n\n yield streamEvent({ type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflightStream(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n )\n for (const event of preflight.events) yield event\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n yield streamEvent({ type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n }\n const decision = decideKnowledgeReadiness(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n yield streamEvent({ type: 'readiness_end', task, knowledge, decision })\n if (!decision.passed && decision.status === 'blocked') {\n const reason = `knowledge readiness blocked: ${decision.reason}`\n yield streamEvent({ type: 'task_end', task, status: 'blocked', reason })\n yield streamEvent({ type: 'final', task, status: 'blocked', reason })\n return\n }\n\n const store = options.sessionStore\n const opened = await startOrResumeRuntimeSession({\n backend: options.backend,\n input,\n context: { task, knowledge, signal: options.signal },\n store,\n sessionId: options.sessionId,\n resume: options.resume,\n })\n let session = opened.session\n const shouldResume = opened.resumed\n const sessionEvent = streamEvent({\n type: shouldResume ? 'session_resumed' : 'session_created',\n task,\n session,\n })\n await store?.appendEvent?.(session.id, sessionEvent)\n yield sessionEvent\n\n const backendStart = streamEvent({\n type: 'backend_start',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendStart)\n yield backendStart\n\n let finalText = ''\n try {\n for await (const rawEvent of options.backend.stream(opened.input, {\n task,\n knowledge,\n session,\n signal: options.signal,\n })) {\n const event = normalizeBackendStreamEvent(rawEvent, task, session)\n if (event.type === 'text_delta') finalText += event.text\n await store?.appendEvent?.(session.id, event)\n yield event\n }\n const completedStatus: AgentTaskStatus = 'completed'\n session = touchSession({ ...session, status: completedStatus })\n await store?.put(session)\n const backendEnd = streamEvent({\n type: 'backend_end',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendEnd)\n yield backendEnd\n const reason = 'backend completed'\n const taskEnd = streamEvent({ type: 'task_end', task, status: completedStatus, reason })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status: completedStatus,\n reason,\n text: finalText || undefined,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n session = touchSession({ ...session, status: options.signal?.aborted ? 'aborted' : 'failed' })\n await store?.put(session)\n let stopErrorMessage: string | undefined\n try {\n await options.backend.stop?.(session, message)\n } catch (stopErr) {\n stopErrorMessage = stopErr instanceof Error ? stopErr.message : String(stopErr)\n }\n const combinedMessage = stopErrorMessage\n ? `${message}; backend stop failed: ${stopErrorMessage}`\n : message\n // Typed transport detail — preserves status code + truncated body so\n // consumers can map onto `RunRecord.error` without re-parsing the log\n // string. Required by the runtime's fail-loud contract: silent empty\n // output for a 402 / 401 / 5xx hides the real failure mode.\n const errorDetail: BackendErrorDetail =\n err instanceof BackendTransportError\n ? {\n kind: 'transport',\n message: combinedMessage,\n status: err.status,\n body: err.body,\n }\n : { kind: 'backend', message: combinedMessage }\n const backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: combinedMessage,\n recoverable: !options.signal?.aborted,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, backendError)\n yield backendError\n const status: AgentTaskStatus = options.signal?.aborted ? 'aborted' : 'failed'\n const taskEnd = streamEvent({ type: 'task_end', task, status, reason: message })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status,\n reason: message,\n text: finalText || undefined,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n }\n}\n\nasync function runKnowledgePreflight<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n onEvent: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n): Promise<{ userAnswers: Record<string, string>; acquiredEvidenceIds: string[] }> {\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n await emit(onEvent, { type: 'questions_start', task, questions })\n userAnswers = await provider.answerQuestions(questions, task)\n await emit(onEvent, { type: 'questions_end', task, questions, userAnswers })\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n await emit(onEvent, { type: 'acquisition_start', task, acquisitionPlans })\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n await emit(onEvent, {\n type: 'acquisition_end',\n task,\n acquisitionPlans,\n acquiredEvidenceIds,\n })\n }\n return { userAnswers, acquiredEvidenceIds }\n}\n\nasync function runKnowledgePreflightStream(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n): Promise<{\n userAnswers: Record<string, string>\n acquiredEvidenceIds: string[]\n events: RuntimeStreamEvent[]\n}> {\n const events: RuntimeStreamEvent[] = []\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n events.push(streamEvent({ type: 'questions_start', task, questions }))\n userAnswers = await provider.answerQuestions(questions, task)\n events.push(streamEvent({ type: 'questions_end', task, questions, userAnswers }))\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n events.push(streamEvent({ type: 'acquisition_start', task, acquisitionPlans }))\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n events.push(\n streamEvent({ type: 'acquisition_end', task, acquisitionPlans, acquiredEvidenceIds }),\n )\n }\n return { userAnswers, acquiredEvidenceIds, events }\n}\n\nfunction streamEvent<T extends Omit<RuntimeStreamEvent, 'timestamp'>>(\n event: T,\n): T & { timestamp: string } {\n return { ...event, timestamp: nowIso() }\n}\n\nfunction buildReadiness(\n task: AgentTaskSpec,\n provider: AgentKnowledgeProvider | undefined,\n): Promise<KnowledgeReadinessReport> | KnowledgeReadinessReport {\n if (provider?.buildReadiness) return provider.buildReadiness(task)\n return scoreKnowledgeReadiness({\n taskId: task.id,\n requirements: task.requiredKnowledge ?? [],\n metadata: { domain: task.domain, ...task.metadata },\n })\n}\n\nfunction isKnowledgeBlocked(evals: ControlEvalResult[]): boolean {\n return evals.some((evalResult) => evalResult.id === 'knowledge-ready' && !evalResult.passed)\n}\n\nfunction statusFromControl(\n control: ControlRunResult<unknown, unknown, unknown, ControlEvalResult>,\n): AgentTaskStatus {\n if (control.stoppedBy === 'abort') return 'aborted'\n if (control.reason.includes('knowledge readiness blocked')) return 'blocked'\n if (control.pass) return 'completed'\n return 'failed'\n}\n\nasync function emit<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n sink: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n event: Parameters<AgentRuntimeEventSink<TState, TAction, TActionResult, TEval>>[0],\n): Promise<void> {\n await sink?.(event)\n}\n\nfunction toAgentContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n task: AgentTaskSpec,\n knowledge: KnowledgeReadinessReport,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n): AgentTaskContext<TState, TAction, TActionResult, TEval> {\n return {\n task,\n knowledge,\n state: ctx.state,\n evals: ctx.evals,\n history: ctx.history,\n budget: ctx.budget,\n stepIndex: ctx.stepIndex,\n wallMs: ctx.wallMs,\n spentCostUsd: ctx.spentCostUsd,\n remainingCostUsd: ctx.remainingCostUsd,\n abortSignal: ctx.abortSignal,\n }\n}\n","/**\n *\n * Production-run lifecycle: record what the agent did on behalf of a customer,\n * what it cost, and how it ended.\n *\n * Three concerns live in this module:\n *\n * 1. **Lifecycle state machine** — `running` -> `completed | failed | cancelled`,\n * enforced by `RuntimeRunStateError`. Completion is idempotent for the same\n * status (a second `complete()` call is a no-op so retries / cleanup paths\n * don't double-fire side effects). A different terminal status is a state\n * error.\n *\n * 2. **Cost ledger** — every `llm_call` event the handle observes contributes\n * `tokensIn`, `tokensOut`, `costUsd`, and bumps `llmCalls`. Wall time is\n * measured from `startRuntimeRun()` to `complete()`. Surface via\n * `handle.cost()` for cost-per-task dashboards.\n *\n * 3. **Persistence adapter** — `RuntimeRunPersistenceAdapter` is the seam\n * consumers plug in to write a `RuntimeRunRow` to their D1 / postgres /\n * KV store. The adapter receives a sanitized row shape; no telemetry\n * payload bytes flow through it unless the consumer opts in via\n * `RuntimeRunOptions.telemetryEvents`.\n *\n * @stable\n */\n\nimport { RuntimeRunStateError, ValidationError } from './errors'\nimport type { AgentTaskSpec, RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport type RuntimeRunStatus = 'running' | 'completed' | 'failed' | 'cancelled'\n\n/** @stable */\nexport interface RuntimeRunCost {\n /** Cumulative input tokens across every observed `llm_call` event. */\n tokensIn: number\n /** Cumulative output tokens across every observed `llm_call` event. */\n tokensOut: number\n /** Sum of `costUsd` from every observed `llm_call` event. */\n costUsd: number\n /** Wall time from `startRuntimeRun()` to `complete()` (or `now()` if not yet completed). */\n wallMs: number\n /** Count of `llm_call` events observed during the run. */\n llmCalls: number\n}\n\n/** @stable */\nexport interface RuntimeRunCompleteInput {\n status: Exclude<RuntimeRunStatus, 'running'>\n resultSummary?: string\n /** Optional explicit cost override; if omitted, the accumulated ledger is used. */\n cost?: Partial<RuntimeRunCost>\n /** Stable error message when `status === 'failed'`. */\n error?: string\n /** Additional adapter-specific fields merged into the persisted row. */\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunRow {\n /** Stable runtime-side identifier. Adapters may translate to their own primary key. */\n id: string\n workspaceId: string\n sessionId?: string\n agentId?: string\n domain?: string\n taskId: string\n scenarioId?: string\n status: RuntimeRunStatus\n resultSummary?: string\n error?: string\n cost: RuntimeRunCost\n startedAt: string\n completedAt?: string\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunPersistenceAdapter {\n /**\n * Called once when `handle.persist()` runs. Implementations write `row` to\n * their durable store (D1, postgres, KV) and return whatever the consumer\n * wants the caller to see (often the storage-side row id). Errors thrown\n * here propagate out of `persist()` so the caller can decide whether to\n * retry or log-and-continue.\n */\n upsert(row: RuntimeRunRow): Promise<void> | void\n}\n\n/** @stable */\nexport interface RuntimeRunOptions {\n workspaceId: string\n sessionId?: string\n agentId?: string\n taskSpec: AgentTaskSpec\n scenarioId?: string\n /** Optional persistence adapter; if omitted, `persist()` is a no-op. */\n adapter?: RuntimeRunPersistenceAdapter\n /** Override the row id; default = `${taskSpec.id}:${random suffix}`. */\n id?: string\n /** Override the clock; default = `Date.now()`. Useful for deterministic tests. */\n now?: () => number\n}\n\n/** @stable */\nexport interface RuntimeRunHandle {\n /** Stable id assigned at start. */\n readonly id: string\n readonly workspaceId: string\n readonly sessionId: string | undefined\n readonly taskSpec: AgentTaskSpec\n readonly status: RuntimeRunStatus\n\n /**\n * Observe a single `RuntimeStreamEvent`. The handle ignores non-cost events\n * (text deltas, tool calls) silently so consumers can pipe the whole stream\n * through `handle.observe`. `llm_call` events update the ledger.\n */\n observe(event: RuntimeStreamEvent): void\n\n /** Snapshot of the current cost ledger. Safe to call at any time. */\n cost(): RuntimeRunCost\n\n /**\n * Transition to a terminal state. Idempotent for the same status; throws\n * `RuntimeRunStateError` for a different terminal status (state machines\n * don't time-travel).\n */\n complete(input: RuntimeRunCompleteInput): void\n\n /** Build the current row without writing it. Useful for tests + dry runs. */\n toRow(metadata?: Record<string, unknown>): RuntimeRunRow\n\n /**\n * Persist the current row via the configured adapter. Must be called after\n * `complete()`. Idempotent for the same terminal state (the adapter sees\n * the same row on retry).\n */\n persist(metadata?: Record<string, unknown>): Promise<void>\n}\n\n/**\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\n *\n * @stable\n */\nexport function startRuntimeRun(options: RuntimeRunOptions): RuntimeRunHandle {\n if (!options.workspaceId) {\n throw new ValidationError('startRuntimeRun: workspaceId is required')\n }\n if (!options.taskSpec?.id) {\n throw new ValidationError('startRuntimeRun: taskSpec.id is required')\n }\n const now = options.now ?? Date.now\n const startedAtMs = now()\n const startedAt = new Date(startedAtMs).toISOString()\n const id = options.id ?? `${options.taskSpec.id}:${randomSuffix()}`\n\n let status: RuntimeRunStatus = 'running'\n let completedAtMs: number | undefined\n let resultSummary: string | undefined\n let error: string | undefined\n let completionMetadata: Record<string, unknown> | undefined\n\n const ledger: RuntimeRunCost = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n wallMs: 0,\n llmCalls: 0,\n }\n\n const snapshotCost = (): RuntimeRunCost => ({\n tokensIn: ledger.tokensIn,\n tokensOut: ledger.tokensOut,\n costUsd: ledger.costUsd,\n wallMs: (completedAtMs ?? now()) - startedAtMs,\n llmCalls: ledger.llmCalls,\n })\n\n const buildRow = (extraMetadata?: Record<string, unknown>): RuntimeRunRow => ({\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n agentId: options.agentId,\n domain: options.taskSpec.domain,\n taskId: options.taskSpec.id,\n scenarioId: options.scenarioId,\n status,\n resultSummary,\n error,\n cost: snapshotCost(),\n startedAt,\n completedAt: completedAtMs !== undefined ? new Date(completedAtMs).toISOString() : undefined,\n metadata: mergeMetadata(completionMetadata, extraMetadata),\n })\n\n return {\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n taskSpec: options.taskSpec,\n get status() {\n return status\n },\n observe(event) {\n if (event.type !== 'llm_call') return\n ledger.llmCalls += 1\n if (typeof event.tokensIn === 'number' && Number.isFinite(event.tokensIn)) {\n ledger.tokensIn += event.tokensIn\n }\n if (typeof event.tokensOut === 'number' && Number.isFinite(event.tokensOut)) {\n ledger.tokensOut += event.tokensOut\n }\n if (typeof event.costUsd === 'number' && Number.isFinite(event.costUsd)) {\n ledger.costUsd += event.costUsd\n }\n },\n cost: snapshotCost,\n complete(input) {\n // JS callers can bypass the `Exclude<…, 'running'>` type; enforce the\n // state machine at runtime as well.\n if ((input.status as RuntimeRunStatus) === 'running') {\n throw new ValidationError('complete() requires a terminal status, got \"running\"')\n }\n if (status !== 'running') {\n if (status === input.status) return\n throw new RuntimeRunStateError(\n `Cannot transition runtime run from \"${status}\" to \"${input.status}\"`,\n )\n }\n status = input.status\n completedAtMs = now()\n resultSummary = input.resultSummary\n error = input.error\n completionMetadata = input.metadata\n if (input.cost) {\n if (typeof input.cost.tokensIn === 'number' && Number.isFinite(input.cost.tokensIn)) {\n ledger.tokensIn = input.cost.tokensIn\n }\n if (typeof input.cost.tokensOut === 'number' && Number.isFinite(input.cost.tokensOut)) {\n ledger.tokensOut = input.cost.tokensOut\n }\n if (typeof input.cost.costUsd === 'number' && Number.isFinite(input.cost.costUsd)) {\n ledger.costUsd = input.cost.costUsd\n }\n if (typeof input.cost.llmCalls === 'number' && Number.isFinite(input.cost.llmCalls)) {\n ledger.llmCalls = input.cost.llmCalls\n }\n }\n },\n toRow(metadata) {\n return buildRow(metadata)\n },\n async persist(metadata) {\n if (status === 'running') {\n throw new RuntimeRunStateError('Cannot persist a runtime run before complete() is called')\n }\n if (!options.adapter) return\n await options.adapter.upsert(buildRow(metadata))\n },\n }\n}\n\nfunction mergeMetadata(\n base: Record<string, unknown> | undefined,\n extra: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !extra) return undefined\n return { ...(base ?? {}), ...(extra ?? {}) }\n}\n\nfunction randomSuffix(): string {\n // 8 chars of base36 — sufficient for in-process uniqueness. Callers needing\n // stronger guarantees pass `options.id` explicitly.\n return Math.random().toString(36).slice(2, 10)\n}\n","/**\n *\n * Server-Sent Events serialization for runtime telemetry streams.\n *\n * Newline-safe by construction: any newline in `id` or `event` is collapsed to\n * a space (browsers terminate fields on newline), and multi-line `data`\n * payloads are split into one `data:` line per source line so JSON.stringify\n * output transports cleanly.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\nimport type { RuntimeTelemetryOptions } from './sanitize'\nimport { sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent } from './sanitize'\nimport type { RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport interface ServerSentEventOptions {\n event?: string\n id?: string\n retry?: number\n}\n\n/** @stable */\nexport function encodeServerSentEvent(data: unknown, options: ServerSentEventOptions = {}): string {\n const lines: string[] = []\n if (options.id) lines.push(`id: ${stripNewlines(options.id)}`)\n if (options.event) lines.push(`event: ${stripNewlines(options.event)}`)\n if (typeof options.retry === 'number' && Number.isFinite(options.retry) && options.retry >= 0) {\n lines.push(`retry: ${Math.floor(options.retry)}`)\n }\n\n const payload = typeof data === 'string' ? data : JSON.stringify(data)\n for (const line of payload.split(/\\r?\\n/)) {\n lines.push(`data: ${line}`)\n }\n return `${lines.join('\\n')}\\n\\n`\n}\n\n/** Serialize a `KnowledgeReadinessReport` as a Server-Sent Event string. @stable */\nexport function readinessServerSentEvent(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(\n {\n type: 'readiness',\n readiness: sanitizeKnowledgeReadinessReport(report, telemetryOptions),\n },\n { event, id, retry },\n )\n}\n\n/** Serialize a `RuntimeStreamEvent` as a Server-Sent Event string. @stable */\nexport function runtimeStreamServerSentEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event: sseEvent, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(sanitizeRuntimeStreamEvent(event, telemetryOptions), {\n event: sseEvent,\n id,\n retry,\n })\n}\n\nfunction stripNewlines(value: string): string {\n return value.replace(/[\\r\\n]/g, ' ')\n}\n"],"mappings":"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"}