@tangle-network/agent-runtime 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/sessions.ts","../src/backends.ts","../src/chat-turn.ts","../src/durable/execution-handle.ts","../src/durable/chat-engine.ts","../src/intent-router.ts","../src/model-resolution.ts","../src/profile-conformance.ts","../src/readiness.ts","../src/run.ts","../src/runtime-run.ts","../src/sanitize.ts","../src/sse.ts","../src/trace-bridge.ts"],"sourcesContent":["/**\n * @stable\n *\n * Error taxonomy for `@tangle-network/agent-runtime`.\n *\n * Public contract: every error this package throws as part of its consumer-\n * facing API either extends `AgentEvalError` (re-exported here for ergonomic\n * `instanceof` checks at the runtime boundary) or extends one of the\n * runtime-specific subclasses below.\n *\n * Internal invariant guards (`throw new Error('this should never happen')`)\n * remain plain `Error` — they are programmer-mistake assertions, not\n * consumer-catchable contract failures.\n *\n * Subclassing strategy: where a runtime-specific failure maps cleanly to an\n * agent-eval code (validation, config, not_found), we re-use the agent-eval\n * subclass. Runtime-only failure modes (session resume against the wrong\n * backend, backend transport errors) get fresh subclasses that still carry an\n * `AgentEvalErrorCode` so cross-package handlers can pattern-match without\n * importing the runtime.\n */\n\nimport { AgentEvalError } from '@tangle-network/agent-eval'\n\nexport {\n AgentEvalError,\n type AgentEvalErrorCode,\n CaptureIntegrityError,\n ConfigError,\n JudgeError,\n NotFoundError,\n ReplayError,\n ValidationError,\n VerificationError,\n} from '@tangle-network/agent-eval'\n\n/**\n * @stable\n *\n * Caller asked to resume a session against a backend whose `kind` does not\n * match the session's recorded backend. This is a routing bug — the same\n * session id was reused across two different backend implementations — and\n * is not retryable without picking the right backend.\n */\nexport class SessionMismatchError extends AgentEvalError {\n readonly sessionBackend: string\n readonly requestedBackend: string\n\n constructor(sessionBackend: string, requestedBackend: string, options?: { cause?: unknown }) {\n super(\n 'validation',\n `Cannot resume ${sessionBackend} session with ${requestedBackend} backend`,\n options,\n )\n this.sessionBackend = sessionBackend\n this.requestedBackend = requestedBackend\n }\n}\n\n/**\n * @stable\n *\n * A backend transport call (HTTP, gRPC, sidecar IPC) failed with a non-success\n * status. Distinct from `JudgeError` (which is structural / unrecoverable)\n * because backend failures are sometimes retryable and consumers may want to\n * branch on the upstream status code.\n */\nexport class BackendTransportError extends AgentEvalError {\n readonly backend: string\n readonly status?: number\n\n constructor(backend: string, message: string, options?: { cause?: unknown; status?: number }) {\n super('config', message, options)\n this.backend = backend\n this.status = options?.status\n }\n}\n\n/**\n * @stable\n *\n * A runtime-run lifecycle method was called in an order the state machine does\n * not allow: `persist()` before `complete()`, `complete()` twice, etc.\n */\nexport class RuntimeRunStateError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n","/**\n * @stable\n *\n * Session helpers + an in-memory `RuntimeSessionStore` implementation suitable\n * for tests, scratch processes, and per-request scratch storage in serverless\n * runtimes. Durable stores (D1, postgres, Durable Objects) implement the same\n * interface from `./types`.\n */\n\nimport type { RuntimeSession, RuntimeSessionStore, RuntimeStreamEvent } from './types'\n\n/** @internal */\nexport function newRuntimeSession(\n backend: string,\n requestedId?: string,\n metadata?: Record<string, unknown>,\n): RuntimeSession {\n const now = nowIso()\n return {\n id: requestedId || crypto.randomUUID(),\n backend,\n status: 'active',\n createdAt: now,\n updatedAt: now,\n metadata,\n }\n}\n\n/** @internal */\nexport function touchSession(session: RuntimeSession): RuntimeSession {\n return { ...session, updatedAt: nowIso() }\n}\n\n/** @internal */\nexport function nowIso(): string {\n return new Date().toISOString()\n}\n\n/** @stable */\nexport class InMemoryRuntimeSessionStore implements RuntimeSessionStore {\n private readonly sessions = new Map<string, RuntimeSession>()\n private readonly events = new Map<string, RuntimeStreamEvent[]>()\n\n get(sessionId: string): RuntimeSession | undefined {\n return this.sessions.get(sessionId)\n }\n\n put(session: RuntimeSession): void {\n this.sessions.set(session.id, session)\n }\n\n appendEvent(sessionId: string, event: RuntimeStreamEvent): void {\n const existing = this.events.get(sessionId) ?? []\n existing.push(event)\n this.events.set(sessionId, existing)\n }\n\n listEvents(sessionId: string): RuntimeStreamEvent[] {\n return [...(this.events.get(sessionId) ?? [])]\n }\n}\n","/**\n * @stable\n *\n * Backend factories for `runAgentTaskStream`. Three shapes ship in core:\n *\n * - `createIterableBackend` — wrap any custom async iterable into a backend\n * - `createSandboxPromptBackend` — sandbox / sidecar `streamPrompt` clients\n * - `createOpenAICompatibleBackend` — OpenAI-style chat completions endpoints\n *\n * Adapters stay thin: domain repos own auth, model selection, and the concrete\n * tool surface. The factories handle session creation, stream normalization,\n * and graceful end-of-stream signalling.\n */\n\nimport { BackendTransportError } from './errors'\nimport { newRuntimeSession, nowIso, touchSession } from './sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentExecutionBackend,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\nexport function createIterableBackend<TInput extends AgentBackendInput>(options: {\n kind: string\n start?: AgentExecutionBackend<TInput>['start']\n resume?: AgentExecutionBackend<TInput>['resume']\n stream: AgentExecutionBackend<TInput>['stream']\n stop?: AgentExecutionBackend<TInput>['stop']\n}): AgentExecutionBackend<TInput> {\n return options\n}\n\n/** @stable */\nexport function createSandboxPromptBackend<\n TBox,\n TInput extends AgentBackendInput = AgentBackendInput,\n>(options: {\n kind?: string\n getBox(input: TInput, context: Omit<AgentBackendContext, 'session'>): Promise<TBox> | TBox\n streamPrompt(box: TBox, message: string, context: AgentBackendContext): AsyncIterable<unknown>\n mapEvent?: (event: unknown, context: AgentBackendContext) => RuntimeStreamEvent | undefined\n getSessionId?: (box: TBox, input: TInput) => string | undefined\n}): AgentExecutionBackend<TInput> {\n const kind = options.kind ?? 'sandbox'\n return {\n kind,\n async start(input, context) {\n const box = await options.getBox(input, context)\n return newRuntimeSession(\n kind,\n options.getSessionId?.(box, input) ?? context.requestedSessionId,\n { resumable: true },\n )\n },\n resume(session) {\n return touchSession({ ...session, status: 'active' })\n },\n async *stream(input, context) {\n const box = await options.getBox(input, context)\n const message = input.message ?? input.messages?.at(-1)?.content ?? context.task.intent\n for await (const event of options.streamPrompt(box, message, context)) {\n const mapped = options.mapEvent?.(event, context) ?? mapCommonBackendEvent(event, context)\n if (mapped) yield mapped\n }\n },\n }\n}\n\n/** @stable */\n/**\n * Retry policy for transient transport errors (rate limits, upstream\n * timeouts). Defaults to 5 attempts with exponential backoff starting at\n * 1s, ±25% jitter, capped at 30s. Set `maxAttempts: 1` to disable retries.\n *\n * Retried status codes:\n * - 408 Request Timeout\n * - 425 Too Early\n * - 429 Too Many Requests\n * - 500 / 502 / 503 / 504 — upstream transient failures\n *\n * Hard failures (401, 403, 4xx other than the above) propagate immediately.\n */\nexport interface BackendRetryPolicy {\n /** Total attempts including the first try. Default 5. */\n maxAttempts?: number\n /** Initial backoff in ms before the second attempt. Default 1000. */\n initialBackoffMs?: number\n /** Hard ceiling on backoff in ms. Default 30000. */\n maxBackoffMs?: number\n /** Jitter fraction in [0, 1]. Default 0.25 (±25%). */\n jitter?: number\n /** Status codes that trigger a retry. Default: 408, 425, 429, 500, 502, 503, 504. */\n retryStatuses?: ReadonlyArray<number>\n /**\n * Per-attempt wall-clock deadline in ms. If a single fetch attempt does\n * not return headers within this window the attempt is aborted and\n * retried. Default 120000 (2 min). Without this a hung upstream blocks\n * the attempt indefinitely — observed in production as a 15-minute\n * `fetch failed` that burned an entire eval persona. Set to 0 to disable.\n */\n requestTimeoutMs?: number\n}\n\nconst DEFAULT_RETRY_STATUSES = [408, 425, 429, 500, 502, 503, 504] as const\n\nfunction pickRetryDelayMs(attempt: number, policy: Required<BackendRetryPolicy>): number {\n const exp = policy.initialBackoffMs * 2 ** (attempt - 1)\n const capped = Math.min(exp, policy.maxBackoffMs)\n const jitter = capped * policy.jitter * (Math.random() * 2 - 1)\n return Math.max(0, Math.round(capped + jitter))\n}\n\n/**\n * Derive a per-attempt AbortSignal that fires when EITHER the caller's\n * signal aborts OR `timeoutMs` elapses. `dispose()` clears the timer so a\n * completed attempt doesn't leak a pending timeout. `timeoutMs <= 0`\n * disables the deadline (caller signal still propagates).\n */\nfunction withTimeout(\n callerSignal: AbortSignal | undefined,\n timeoutMs: number,\n): { signal: AbortSignal; dispose: () => void } {\n if (timeoutMs <= 0) {\n return { signal: callerSignal ?? new AbortController().signal, dispose: () => undefined }\n }\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(new Error(`request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n )\n if (typeof (timer as { unref?: () => void }).unref === 'function') {\n ;(timer as { unref: () => void }).unref()\n }\n const onCallerAbort = () => controller.abort(callerSignal?.reason ?? new Error('aborted'))\n if (callerSignal) {\n if (callerSignal.aborted) onCallerAbort()\n else callerSignal.addEventListener('abort', onCallerAbort, { once: true })\n }\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer)\n callerSignal?.removeEventListener('abort', onCallerAbort)\n },\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error('aborted'))\n return\n }\n const t = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n const onAbort = () => {\n clearTimeout(t)\n reject(signal?.reason ?? new Error('aborted'))\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport function createOpenAICompatibleBackend<\n TInput extends AgentBackendInput = AgentBackendInput,\n>(options: {\n apiKey: string\n baseUrl: string\n model: string\n kind?: string\n fetchImpl?: typeof fetch\n retry?: BackendRetryPolicy\n}): AgentExecutionBackend<TInput> {\n const fetcher = options.fetchImpl ?? fetch\n const kind = options.kind ?? 'tcloud'\n const retryPolicy: Required<BackendRetryPolicy> = {\n maxAttempts: options.retry?.maxAttempts ?? 5,\n initialBackoffMs: options.retry?.initialBackoffMs ?? 1000,\n maxBackoffMs: options.retry?.maxBackoffMs ?? 30000,\n jitter: options.retry?.jitter ?? 0.25,\n retryStatuses: options.retry?.retryStatuses ?? DEFAULT_RETRY_STATUSES,\n requestTimeoutMs: options.retry?.requestTimeoutMs ?? 120_000,\n }\n return {\n kind,\n start(_input, context) {\n return newRuntimeSession(kind, context.requestedSessionId)\n },\n async *stream(input, context) {\n const url = `${options.baseUrl.replace(/\\/$/, '')}/chat/completions`\n const requestBody = JSON.stringify({\n model: options.model,\n stream: true,\n messages: input.messages ?? [\n { role: 'user', content: input.message ?? context.task.intent },\n ],\n })\n let response: Response | undefined\n let lastStatus = 0\n // The last thrown transport error (timeout abort, DNS / connection\n // failure). Network throws are retryable just like 5xx — without this\n // a `fetch failed` propagated immediately and burned the attempt.\n let lastThrown: unknown\n for (let attempt = 1; attempt <= retryPolicy.maxAttempts; attempt++) {\n lastThrown = undefined\n // Per-attempt deadline: abort a hung upstream instead of waiting\n // forever. Linked to context.signal so a caller cancel still wins.\n const attemptSignal = withTimeout(context.signal, retryPolicy.requestTimeoutMs)\n try {\n response = await fetcher(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: requestBody,\n signal: attemptSignal.signal,\n })\n } catch (err) {\n attemptSignal.dispose()\n // A caller-initiated abort is terminal — do not retry it.\n if (context.signal?.aborted) throw err\n lastThrown = err\n response = undefined\n if (attempt === retryPolicy.maxAttempts) break\n await sleep(pickRetryDelayMs(attempt, retryPolicy), context.signal)\n continue\n }\n attemptSignal.dispose()\n if (response.ok) break\n lastStatus = response.status\n if (!retryPolicy.retryStatuses.includes(response.status)) break\n if (attempt === retryPolicy.maxAttempts) break\n // Drain the failed body so the connection can be reused.\n try {\n await response.body?.cancel()\n } catch {\n // Best-effort — some runtimes don't expose cancel.\n }\n const delayMs = pickRetryDelayMs(attempt, retryPolicy)\n await sleep(delayMs, context.signal)\n }\n if (!response) {\n const reason = lastThrown instanceof Error ? lastThrown.message : String(lastThrown)\n throw new BackendTransportError(\n kind,\n `chat backend unreachable after ${retryPolicy.maxAttempts} attempts: ${reason}`,\n { status: 0 },\n )\n }\n if (!response.ok) {\n throw new BackendTransportError(kind, `chat backend returned ${lastStatus || 'unknown'}`, {\n status: lastStatus || 0,\n })\n }\n yield* streamResponseEvents(response, context)\n },\n }\n}\n\n/** @internal */\nexport function normalizeBackendStreamEvent(\n event: RuntimeStreamEvent,\n task: AgentBackendContext['task'],\n session: RuntimeSession,\n): RuntimeStreamEvent {\n if (\n 'task' in event &&\n event.task &&\n 'session' in event &&\n event.session &&\n 'timestamp' in event &&\n event.timestamp\n ) {\n return event\n }\n return {\n ...event,\n task: 'task' in event && event.task ? event.task : task,\n session: 'session' in event && event.session ? event.session : session,\n timestamp: 'timestamp' in event && event.timestamp ? event.timestamp : nowIso(),\n } as RuntimeStreamEvent\n}\n\nfunction mapCommonBackendEvent(\n event: unknown,\n context: AgentBackendContext,\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const record = event as Record<string, unknown>\n const type = String(record.type ?? '')\n const data =\n record.data && typeof record.data === 'object'\n ? (record.data as Record<string, unknown>)\n : record\n if (type === 'message.part.updated' || type === 'text_delta' || type === 'delta') {\n const text = stringValue(data.text) ?? stringValue(data.delta) ?? stringValue(record.text)\n return text\n ? {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n if (type === 'reasoning_delta') {\n const text = stringValue(data.text) ?? stringValue(record.text)\n return text\n ? {\n type: 'reasoning_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n if (type === 'tool_call') {\n return {\n type: 'tool_call',\n task: context.task,\n session: context.session,\n toolName: stringValue(data.name) ?? stringValue(record.toolName) ?? 'tool',\n toolCallId: stringValue(data.id) ?? stringValue(record.toolCallId),\n args: data.args ?? data.input ?? record.args,\n timestamp: nowIso(),\n }\n }\n if (type === 'tool_result') {\n return {\n type: 'tool_result',\n task: context.task,\n session: context.session,\n toolName: stringValue(data.name) ?? stringValue(record.toolName) ?? 'tool',\n toolCallId: stringValue(data.id) ?? stringValue(record.toolCallId),\n result: data.result ?? data.output ?? record.result,\n timestamp: nowIso(),\n }\n }\n if (type === 'artifact') {\n const artifactId =\n stringValue(data.artifactId) ?? stringValue(data.id) ?? stringValue(record.artifactId)\n if (!artifactId) return undefined\n return {\n type: 'artifact',\n task: context.task,\n session: context.session,\n artifactId,\n name: stringValue(data.name) ?? stringValue(record.name),\n mimeType: stringValue(data.mimeType) ?? stringValue(record.mimeType),\n uri: stringValue(data.uri) ?? stringValue(record.uri),\n content: stringValue(data.content) ?? stringValue(data.body) ?? stringValue(record.content),\n metadata:\n data.metadata && typeof data.metadata === 'object'\n ? (data.metadata as Record<string, unknown>)\n : undefined,\n timestamp: nowIso(),\n }\n }\n if (type === 'proposal_created' || type === 'proposal' || type === 'filing') {\n const proposalId =\n stringValue(data.proposalId) ?? stringValue(data.id) ?? stringValue(record.proposalId)\n if (!proposalId) return undefined\n const status = stringValue(data.status) ?? stringValue(record.status)\n return {\n type: 'proposal_created',\n task: context.task,\n session: context.session,\n proposalId,\n title: stringValue(data.title) ?? stringValue(record.title) ?? proposalId,\n status:\n status === 'pending' || status === 'approved' || status === 'rejected' ? status : undefined,\n timestamp: nowIso(),\n }\n }\n if (type === 'result' || type === 'final') {\n const text = stringValue(data.finalText) ?? stringValue(data.text) ?? stringValue(record.text)\n return text\n ? {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n return undefined\n}\n\nasync function* streamResponseEvents(\n response: Response,\n context: AgentBackendContext,\n): AsyncIterable<RuntimeStreamEvent> {\n const body = response.body\n if (!body) return\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, '\\n')\n for (const event of drainStreamBuffer(false)) yield event\n }\n buffer += decoder.decode().replace(/\\r\\n/g, '\\n')\n for (const event of drainStreamBuffer(true)) yield event\n if (buffer.trim()) {\n const event = parseStreamChunk(buffer, context)\n if (event) yield event\n }\n\n function* drainStreamBuffer(flush: boolean): Iterable<RuntimeStreamEvent> {\n for (;;) {\n const sseBoundary = buffer.indexOf('\\n\\n')\n if (sseBoundary >= 0) {\n const chunk = buffer.slice(0, sseBoundary)\n buffer = buffer.slice(sseBoundary + 2)\n const event = parseStreamChunk(chunk, context)\n if (event) yield event\n continue\n }\n\n const newline = buffer.indexOf('\\n')\n if (newline >= 0 && !buffer.slice(0, newline).startsWith('data:')) {\n const line = buffer.slice(0, newline)\n buffer = buffer.slice(newline + 1)\n const event = parseStreamChunk(line, context)\n if (event) yield event\n continue\n }\n\n if (flush && buffer.trim() && !buffer.trimStart().startsWith('data:')) {\n const line = buffer\n buffer = ''\n const event = parseStreamChunk(line, context)\n if (event) yield event\n continue\n }\n\n break\n }\n }\n}\n\nfunction parseStreamChunk(\n chunk: string,\n context: AgentBackendContext,\n): RuntimeStreamEvent | undefined {\n const lines = chunk.split(/\\r?\\n/)\n const dataLines = lines.filter((line) => line.startsWith('data:'))\n const data =\n dataLines.length > 0\n ? dataLines.map((line) => line.slice(5).trimStart()).join('\\n')\n : chunk.trim()\n if (!data || data === '[DONE]') return undefined\n try {\n const parsed = JSON.parse(data) as Record<string, unknown>\n const choices = parsed.choices\n const choice = Array.isArray(choices)\n ? (choices[0] as Record<string, unknown> | undefined)\n : undefined\n const delta = choice?.delta as Record<string, unknown> | undefined\n const message = choice?.message as Record<string, unknown> | undefined\n const text =\n stringValue(delta?.content) ?? stringValue(message?.content) ?? stringValue(parsed.text)\n if (text) {\n return {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n }\n return mapCommonBackendEvent(parsed, context)\n } catch {\n return {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text: data,\n timestamp: nowIso(),\n }\n }\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n","/**\n * Send an AgentProfile to a sandbox runtime for one chat turn. Composes\n * the per-turn overlay (user message, prior history, knowledge flags)\n * via `mergeAgentProfiles`, POSTs the full profile to the runtime's\n * `/runtime/agents/run/stream` endpoint, and yields `RuntimeStreamEvent`s\n * from the SSE response. The full profile — subagents, MCP servers,\n * permissions, file mounts — reaches the sandbox by construction.\n */\n\nimport type {\n AgentProfile,\n AgentProfilePrompt,\n AgentProfileResources,\n AgentSubagentProfile,\n SandboxInstance,\n} from '@tangle-network/sandbox'\nimport { mergeAgentProfiles } from '@tangle-network/sandbox'\nimport type { RuntimeStreamEvent } from './types'\n\n/** A message in the chat turn's prior context. Provider-neutral. */\nexport interface ChatTurnMessage {\n role: 'user' | 'assistant' | 'system'\n content: string\n /** Optional metadata the consumer wants threaded through (timestamps, msg id, etc). */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Per-turn profile overlay. The caller's profile is the durable contract;\n * the overlay carries volatile per-turn context (workspace facts, dynamic-\n * advisor instructions, RAG hits) that the runtime should see but that\n * doesn't belong in the canonical profile. Composed via `mergeAgentProfiles`.\n */\nexport interface ChatTurnOverlay {\n /** Volatile prompt additions: dynamic-advisor context, intake gate output, RAG citations. */\n promptOverlay?: AgentProfilePrompt\n /** Per-turn additional file mounts (vault docs, recent uploads). */\n resourcesOverlay?: AgentProfileResources\n /** Override or augment the subagent map for this turn (rare). */\n subagentsOverlay?: Record<string, AgentSubagentProfile>\n /** Free-form metadata threaded into the runtime call. */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Sandbox runtime contract — the subset of `SandboxInstance` `runChatTurn`\n * actually invokes. Defined as an interface so consumers can inject a\n * stub in tests without standing up a real sandbox.\n */\nexport interface ChatTurnSandbox {\n /** Sandbox identifier used in the runtime URL. */\n readonly id: string\n /** Base URL of the sandbox runtime, e.g. `https://sandbox.tangle.tools/v1/sandboxes/&lt;id&gt;`. */\n readonly runtimeUrl: string\n /** Optional bearer for the runtime call (sidecar auth). */\n readonly authHeader?: { name: string; value: string }\n}\n\nexport interface RunChatTurnOptions {\n /** Canonical agent profile — the durable contract. */\n profile: AgentProfile\n /** Volatile per-turn additions. */\n overlay?: ChatTurnOverlay\n /** Current user message. */\n message: string\n /** Prior conversation. */\n priorMessages: readonly ChatTurnMessage[]\n /** Sandbox the turn should run inside. */\n sandbox: ChatTurnSandbox\n /** Override model for this turn (otherwise profile.model.default is used). */\n modelOverride?: string\n /** AbortSignal for cancellation (timeouts, client disconnect, etc). */\n signal?: AbortSignal\n /** Override fetch (for tests). */\n fetch?: typeof fetch\n}\n\nconst RUNTIME_PATH = '/runtime/agents/run/stream'\n\n/**\n * Compose the per-turn profile via `mergeAgentProfiles(profile, overlay)`,\n * POST the FULL composed profile to the sandbox's runtime streaming endpoint,\n * and yield parsed `RuntimeStreamEvent`s. The runtime resolves prompt,\n * subagents, MCP servers, and permissions from the profile — callers do not\n * hand-craft a `backend.profile` shape.\n *\n * for await (const event of runChatTurn({ profile, overlay, message, priorMessages, sandbox })) {\n * // event.type === 'message' / 'tool_call' / 'task_complete' / etc.\n * }\n */\nexport async function* runChatTurn(options: RunChatTurnOptions): AsyncIterable<RuntimeStreamEvent> {\n const turnProfile = options.overlay\n ? composeTurnProfile(options.profile, options.overlay)\n : options.profile\n const url = `${options.sandbox.runtimeUrl}${RUNTIME_PATH}`\n // `backend.type` is a transport concern, not a profile field. Consumers can\n // override via `metadata.backend`; otherwise the runtime receives `claude-code`.\n const backendType =\n (turnProfile.metadata as { backend?: { type?: string } } | undefined)?.backend?.type ??\n 'claude-code'\n const body = JSON.stringify({\n backend: {\n type: backendType,\n profile: turnProfile,\n ...(options.modelOverride ? { model: { default: options.modelOverride } } : {}),\n },\n messages: [...options.priorMessages, { role: 'user', content: options.message }],\n })\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n }\n if (options.sandbox.authHeader) {\n headers[options.sandbox.authHeader.name] = options.sandbox.authHeader.value\n }\n const fetchImpl = options.fetch ?? fetch\n const response = await fetchImpl(url, {\n method: 'POST',\n headers,\n body,\n signal: options.signal,\n })\n if (!response.ok || !response.body) {\n const text = response.body ? await response.text() : ''\n throw new ChatTurnError(\n `runChatTurn: sandbox returned ${response.status} ${response.statusText}: ${text.slice(0, 500)}`,\n response.status,\n )\n }\n yield* parseSseStream(response.body)\n}\n\n/**\n * Compose the per-turn AgentProfile. Public-and-pure so consumers can\n * preview/log/persist the composed shape without firing a runtime call.\n */\nexport function composeTurnProfile(base: AgentProfile, overlay: ChatTurnOverlay): AgentProfile {\n const partial: Partial<AgentProfile> = {}\n if (overlay.promptOverlay) partial.prompt = overlay.promptOverlay\n if (overlay.resourcesOverlay) partial.resources = overlay.resourcesOverlay\n if (overlay.subagentsOverlay) partial.subagents = overlay.subagentsOverlay\n if (overlay.metadata) partial.metadata = overlay.metadata\n return mergeAgentProfiles(base, partial) ?? base\n}\n\n/** SSE/NDJSON line parser — handles the standard runtime stream shape. */\nasync function* parseSseStream(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<RuntimeStreamEvent> {\n const decoder = new TextDecoder()\n const reader = stream.getReader()\n let buffer = ''\n try {\n while (true) {\n const { value, done } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true })\n let idx = buffer.indexOf('\\n')\n while (idx >= 0) {\n const line = buffer.slice(0, idx).replace(/\\r$/, '').trim()\n buffer = buffer.slice(idx + 1)\n idx = buffer.indexOf('\\n')\n if (!line) continue\n // SSE: lines starting with `data:` carry the JSON payload.\n const payload = line.startsWith('data:') ? line.slice(5).trim() : line\n if (payload === '[DONE]' || payload === '') continue\n try {\n const parsed = JSON.parse(payload) as RuntimeStreamEvent\n yield parsed\n } catch {\n // Non-JSON sentinel line (heartbeats, comments, etc) — skip silently.\n }\n }\n }\n } finally {\n reader.releaseLock()\n }\n}\n\nexport class ChatTurnError extends Error {\n constructor(\n message: string,\n public readonly status?: number,\n ) {\n super(message)\n this.name = 'ChatTurnError'\n }\n}\n\n/**\n * Convenience: build a `ChatTurnSandbox` from a full `SandboxInstance`. Most\n * callers already have one of these from `client.create()`. The runtime URL\n * is derived from the instance's transport configuration.\n */\nexport function sandboxAsChatTurnTarget(\n instance: SandboxInstance,\n opts?: { authHeader?: { name: string; value: string } },\n): ChatTurnSandbox {\n // `SandboxInstance.url` is the live agent URL when set; fall back to the\n // connection's `runtimeUrl`. `runChatTurn` appends the runtime path itself,\n // so strip any trailing slash here.\n const base =\n (instance as unknown as { url?: string }).url ??\n (instance as unknown as { connection?: { runtimeUrl?: string } }).connection?.runtimeUrl ??\n ''\n if (!base) {\n throw new ChatTurnError(\n `sandboxAsChatTurnTarget: SandboxInstance has neither .url nor .connection.runtimeUrl set`,\n )\n }\n return {\n id: instance.id,\n runtimeUrl: base.replace(/\\/+$/, ''),\n authHeader: opts?.authHeader,\n }\n}\n","/**\n * Derive a stable executionId from the run identity. The same\n * `(projectId, sessionId, turnIndex)` tuple yields the same id — so a\n * client retry of the same turn lands on the same substrate execution\n * and the orchestrator's buffer replays instead of starting a second\n * prompt.\n *\n * Format is readable, not hashed: operators grepping orchestrator logs\n * for `gtm-agent:thread-abc:3` find the run without translating an\n * opaque id. Substrate executionIds are not a secrecy boundary.\n *\n * Wire integration:\n * - `@tangle-network/sandbox@0.1.x` PromptOptions does not yet expose\n * `executionId`. The SDK auto-reconnects in-call by extracting it\n * from the response `execution.started` event; products do nothing.\n * - For cross-process reconnect today, bypass the SDK and POST to the\n * orchestrator's `/agents/run/stream` directly with this id in the\n * `X-Execution-ID` header (see tax-agent's `sessions.ts`).\n */\nexport function deriveExecutionId(input: {\n projectId: string\n sessionId: string\n turnIndex: number\n}): string {\n return `${input.projectId}:${input.sessionId}:${input.turnIndex}`\n}\n","/**\n * `handleChatTurn` — framework-neutral chat-turn HTTP orchestrator.\n * Owns the NDJSON `ChatStreamEvent` line protocol, the `session.run.*`\n * lifecycle vocabulary, and the persist / post-process / trace-flush\n * hook order. Returns a `ReadableStream` body the product hands to its\n * platform `Response`.\n *\n * Execution durability is the substrate's concern: `box.streamPrompt`\n * auto-reconnects in-call; cross-process reconnect via `X-Execution-ID`\n * is the product's job. The producer this engine wraps already speaks\n * that protocol — the engine just frames the events.\n *\n * Hooks (`ChatTurnHooks`):\n * - `produce` — build the backend event stream\n * - `persistAssistantMessage` — write the assistant turn to the product DB\n * - `onTurnComplete?` — post-process (proposals, citations, …)\n * - `onEvent?` — per-event side channel (e.g. DO broadcast)\n * - `transformFinalText?` — pre-persist transform (e.g. PII redact)\n * - `traceFlush?` — handed to waitUntil so OTLP export lands\n *\n * Framework neutrality: takes already-resolved values (`identity` tuple,\n * a `waitUntil`), never a `Request` or a `Context`. The product's thin\n * route adapter does auth + parse + access-control, then calls\n * `handleChatTurn(...)` and returns `result.body` as its platform `Response`.\n */\n\n/** The NDJSON line protocol every product chat client already speaks. */\nexport interface ChatStreamEvent {\n type: string\n data?: Record<string, unknown>\n}\n\n/** Identity of a chat turn. `tenantId` is the workspace id for workspace-\n * scoped products and the user id for session-scoped products. */\nexport interface ChatTurnIdentity {\n tenantId: string\n /** Thread / session id. */\n sessionId: string\n userId: string\n /** Monotonic 0-based turn index within the session. */\n turnIndex: number\n}\n\n/** The live side of a turn — what the product's `produce` hook returns. */\nexport interface ChatTurnProducer<TEvent extends ChatStreamEvent = ChatStreamEvent> {\n /** The turn's event stream. Forwarded verbatim to the caller. */\n stream: AsyncGenerator<TEvent, void, unknown>\n /** The turn's final assistant text. Read once, after `stream` drains. */\n finalText(): string\n}\n\nexport interface ChatTurnHooks {\n /** Build the backend stream. The engine forwards events verbatim and\n * reads `finalText()` once the stream drains. */\n produce(): ChatTurnProducer\n /** Persist the assistant message to the product's own store. Called\n * once, after drain, with the assembled (transform-applied) text. */\n persistAssistantMessage(input: {\n identity: ChatTurnIdentity\n finalText: string\n }): Promise<void>\n /** Optional post-processing (proposals, citations, credit metering …).\n * Errors are swallowed + logged — post-process must never fail a turn\n * that already streamed successfully. */\n onTurnComplete?(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional per-event side channel (e.g. DO broadcast). Runs for every\n * emitted event, lifecycle envelope included. Errors swallowed — a\n * broadcast failure must not break the chat stream. */\n onEvent?(event: ChatStreamEvent): void | Promise<void>\n /** Optional pre-persist transform of the final text (e.g. PII\n * redaction). Affects only what is persisted; the live stream is\n * never altered. */\n transformFinalText?(text: string): string | Promise<string>\n /** Optional trace flush — resolves when OTLP export completes. Handed\n * to `waitUntil` so the worker isolate stays alive for the POST. */\n traceFlush?(): Promise<void>\n}\n\nexport interface RunChatTurnInput {\n identity: ChatTurnIdentity\n hooks: ChatTurnHooks\n /** Worker liveness hook. When omitted, trace flush is awaited inline\n * before the stream closes. */\n waitUntil?: (p: Promise<unknown>) => void\n /** Structured logger for swallowed hook errors. Defaults to\n * `console.error` so failures surface without product wiring. */\n log?: (message: string, meta?: Record<string, unknown>) => void\n}\n\nexport interface ChatTurnResult {\n /** NDJSON body — return this as the platform `Response` body. */\n body: ReadableStream<Uint8Array>\n /** Content type for the response. */\n contentType: 'application/x-ndjson'\n}\n\nconst encoder = new TextEncoder()\n\nfunction encodeLine(event: ChatStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`)\n}\n\nfunction defaultLog(message: string, meta?: Record<string, unknown>): void {\n if (meta) console.error(message, meta)\n else console.error(message)\n}\n\n/**\n * Run one chat turn. Returns immediately with a `ReadableStream` body;\n * the turn executes as the body is pulled. Never rejects — backend\n * failures surface as `error` + `session.run.failed` events.\n */\nexport function handleChatTurn(input: RunChatTurnInput): ChatTurnResult {\n const log = input.log ?? defaultLog\n const { identity, hooks } = input\n\n const body = new ReadableStream<Uint8Array>({\n start: async (controller) => {\n const emit = async (event: ChatStreamEvent): Promise<void> => {\n controller.enqueue(encodeLine(event))\n if (hooks.onEvent) {\n try {\n await hooks.onEvent(event)\n } catch (err) {\n log('[chat-engine] onEvent hook threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n }\n\n try {\n await emit({\n type: 'session.run.started',\n data: {\n sessionId: identity.sessionId,\n tenantId: identity.tenantId,\n turnIndex: identity.turnIndex,\n },\n })\n\n const producer = hooks.produce()\n for await (const event of producer.stream) {\n await emit(event)\n }\n const rawFinal = producer.finalText()\n const finalText = hooks.transformFinalText\n ? await hooks.transformFinalText(rawFinal)\n : rawFinal\n\n try {\n await hooks.persistAssistantMessage({ identity, finalText })\n } catch (err) {\n log('[chat-engine] persistAssistantMessage threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n if (hooks.onTurnComplete) {\n try {\n await hooks.onTurnComplete({ identity, finalText })\n } catch (err) {\n log('[chat-engine] onTurnComplete threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n await emit({\n type: 'session.run.completed',\n data: { sessionId: identity.sessionId },\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n log('[chat-engine] turn failed', { error: message })\n await emit({ type: 'error', data: { message } })\n await emit({\n type: 'session.run.failed',\n data: { sessionId: identity.sessionId, message },\n })\n } finally {\n if (hooks.traceFlush) {\n const flush = hooks.traceFlush().catch((err) =>\n log('[chat-engine] traceFlush threw', {\n error: err instanceof Error ? err.message : String(err),\n }),\n )\n if (input.waitUntil) input.waitUntil(flush)\n else await flush\n }\n controller.close()\n }\n },\n })\n\n return { body, contentType: 'application/x-ndjson' }\n}\n","/**\n * Classify a user message against a profile's subagent map. Routes are\n * declared on each `AgentSubagentProfile.metadata.matchers` (keywords +\n * regex patterns); `classifyIntent` scores every subagent against the\n * message and returns a typed result. Pure scoring — no LLM call. Caller\n * decides whether the score is high enough to dispatch the subagent.\n */\n\nimport type { AgentProfile, AgentSubagentProfile } from '@tangle-network/sandbox'\n\n/** Matcher shape attached to `subagent.metadata.matchers`. */\nexport interface SubagentMatcher {\n /** Literal keywords (case-insensitive substring match). +1 per match unless `weight` overrides. */\n keywords?: readonly string[]\n /** Regex patterns (case-insensitive). +`weight` per match (default 1.5). */\n patterns?: readonly (string | RegExp)[]\n /** Per-rule weight override. */\n weight?: number\n /** Minimum score for this subagent to be considered \"matched\". Default 1. */\n minScore?: number\n}\n\nexport interface ClassifyIntentResult {\n /** Best-scoring subagent id; null if no subagent crossed `minScore`. */\n id: string | null\n /** Best subagent's `AgentSubagentProfile`; null if no match. */\n subagent: AgentSubagentProfile | null\n /** Score of the chosen subagent. */\n score: number\n /** All subagent scores keyed by id — useful for telemetry / debugging. */\n scores: Record<string, number>\n /** The matchers checked, for debugging \"why didn't X route?\" */\n evaluated: Record<string, { keywordHits: number; patternHits: number; minScore: number }>\n}\n\nexport interface ClassifyIntentOptions {\n /** Override the global default `minScore` (used when a subagent omits its own). */\n defaultMinScore?: number\n /** Subagent ids to skip (e.g. scaffold-only subagents with `metadata.status === 'scaffold'`). */\n skip?: readonly string[]\n /** Only consider subagents whose metadata predicate returns true (e.g. `m =&gt; m.status === 'full'`). */\n filter?: (subagent: AgentSubagentProfile, id: string) => boolean\n}\n\nconst DEFAULT_PATTERN_WEIGHT = 1.5\nconst DEFAULT_MIN_SCORE = 1\n\nfunction isMatcher(value: unknown): value is SubagentMatcher {\n if (!value || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n return Array.isArray(v.keywords) || Array.isArray(v.patterns) || typeof v.minScore === 'number'\n}\n\nfunction readMatcher(subagent: AgentSubagentProfile): SubagentMatcher | null {\n const m = subagent.metadata as Record<string, unknown> | undefined\n if (!m) return null\n const raw = m.matchers ?? m.matcher ?? null\n if (!raw) return null\n if (Array.isArray(raw)) {\n // Allow consumers to declare an array-of-matchers; merge into one shape.\n const merged: SubagentMatcher = { keywords: [], patterns: [], minScore: DEFAULT_MIN_SCORE }\n for (const entry of raw) {\n if (!isMatcher(entry)) continue\n merged.keywords = [...(merged.keywords ?? []), ...(entry.keywords ?? [])]\n merged.patterns = [...(merged.patterns ?? []), ...(entry.patterns ?? [])]\n if (entry.minScore !== undefined) merged.minScore = entry.minScore\n }\n return merged\n }\n if (isMatcher(raw)) return raw\n return null\n}\n\n/**\n * Pure intent classifier.\n *\n * For each subagent in `profile.subagents`: read `metadata.matchers`,\n * score keyword + pattern hits against the user message, return the\n * highest-scoring subagent (or null if none crossed `minScore`). No LLM\n * call, no side effects. The runtime decides what to do with the result.\n */\nexport function classifyIntent(\n profile: AgentProfile,\n message: string,\n opts: ClassifyIntentOptions = {},\n): ClassifyIntentResult {\n const lower = message.toLowerCase()\n const subagents = profile.subagents ?? {}\n const skip = new Set(opts.skip ?? [])\n const defaultMinScore = opts.defaultMinScore ?? DEFAULT_MIN_SCORE\n\n const scores: Record<string, number> = {}\n const evaluated: Record<string, { keywordHits: number; patternHits: number; minScore: number }> =\n {}\n let bestId: string | null = null\n let bestScore = -Infinity\n let bestSubagent: AgentSubagentProfile | null = null\n\n for (const [id, subagent] of Object.entries(subagents)) {\n if (skip.has(id)) continue\n if (opts.filter && !opts.filter(subagent, id)) continue\n const matcher = readMatcher(subagent)\n if (!matcher) {\n evaluated[id] = { keywordHits: 0, patternHits: 0, minScore: defaultMinScore }\n scores[id] = 0\n continue\n }\n const weight = matcher.weight ?? 1\n let kHits = 0\n for (const kw of matcher.keywords ?? []) {\n if (kw && lower.includes(kw.toLowerCase())) kHits += 1\n }\n let pHits = 0\n for (const p of matcher.patterns ?? []) {\n const re = p instanceof RegExp ? p : new RegExp(p, 'i')\n if (re.test(message)) pHits += 1\n }\n const score = kHits * weight + pHits * DEFAULT_PATTERN_WEIGHT * weight\n const minScore = matcher.minScore ?? defaultMinScore\n scores[id] = score\n evaluated[id] = { keywordHits: kHits, patternHits: pHits, minScore }\n if (score >= minScore && score > bestScore) {\n bestScore = score\n bestId = id\n bestSubagent = subagent\n }\n }\n\n if (bestId === null) {\n return { id: null, subagent: null, score: 0, scores, evaluated }\n }\n return { id: bestId, subagent: bestSubagent, score: bestScore, scores, evaluated }\n}\n","/**\n * @stable\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\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\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/**\n * Prepend synthetic catalog entries for ids the environment pins but the\n * router may not list (e.g. a private or self-hosted chat model). Ids already\n * present in `models` are not duplicated.\n */\nexport function withConfiguredModels(models: ModelInfo[], extraIds: string[]): ModelInfo[] {\n const known = new Set(models.map((model) => model.id))\n const extra = extraIds\n .map((id) => cleanModelId(id))\n .filter((id): id is string => id !== undefined && !known.has(id))\n .map(\n (id): ModelInfo => ({\n id,\n name: id,\n description: 'Configured chat model for this environment.',\n architecture: {\n modality: 'text->text',\n input_modalities: ['text'],\n output_modalities: ['text'],\n },\n }),\n )\n return extra.length > 0 ? [...extra, ...models] : models\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 * Validate an AgentProfile against canonical conformance rules: tool keys\n * must map to an MCP server entry (not be shell capabilities masquerading\n * as tools), subagents marked `metadata.status: 'scaffold'` must not be\n * dispatchable, system prompts must be substantive. Pure — no I/O — so\n * callers run it in a unit test or at module load to fail-fast on\n * misconfiguration.\n */\n\nimport type {\n AgentProfile,\n AgentProfileMcpServer,\n AgentSubagentProfile,\n} from '@tangle-network/sandbox'\n\nexport interface ConformanceIssue {\n severity: 'error' | 'warn'\n /** Stable kebab-case code, useful for CI matching. */\n code: string\n /** Profile path the issue is anchored to, e.g. `tools.bash` or `subagents.foo`. */\n path: string\n /** Human-readable failure reason. */\n message: string\n}\n\nexport interface ConformanceResult {\n valid: boolean\n errors: ConformanceIssue[]\n warnings: ConformanceIssue[]\n}\n\nexport interface ConformanceOptions {\n /**\n * Shell-style capabilities that may appear in `permissions` but NEVER in\n * `tools`. Declaring these as tools is decorative — the runtime doesn't\n * dispatch them as MCP servers. Default covers the observed offenders.\n */\n knownShellCapabilities?: readonly string[]\n /**\n * If true, treat `subagents[id].metadata.status === 'scaffold'` as an\n * error rather than a warning. Default false — scaffolds are honest\n * stubs as long as the router skips them.\n */\n strictNoScaffolds?: boolean\n /**\n * Names that may appear in `tools` without a corresponding MCP server or\n * resource mount. Default empty — kills decorative-tool anti-pattern.\n */\n toolsAllowedWithoutMcp?: readonly string[]\n /**\n * Minimum length of `prompt.systemPrompt`. Profiles below this are\n * likely incomplete. Default 800 chars (rough lower bound for the\n * partner-tier prompts the product agents target).\n */\n minSystemPromptChars?: number\n}\n\nconst DEFAULT_SHELL_CAPS = [\n 'bash',\n 'sh',\n 'python',\n 'node',\n 'curl',\n 'web',\n 'browser',\n 'shell',\n] as const\n\nconst DEFAULT_MIN_PROMPT_CHARS = 800\n\nfunction checkSystemPrompt(profile: AgentProfile, minChars: number): ConformanceIssue[] {\n const prompt = profile.prompt?.systemPrompt\n if (!prompt || prompt.trim().length < minChars) {\n return [\n {\n severity: 'error',\n code: 'system-prompt-too-short',\n path: 'prompt.systemPrompt',\n message: `prompt.systemPrompt is ${prompt?.length ?? 0} chars; min required is ${minChars}. Profiles below this threshold are almost always placeholders.`,\n },\n ]\n }\n return []\n}\n\nfunction checkToolsVsMcp(profile: AgentProfile, opts: ConformanceOptions): ConformanceIssue[] {\n const issues: ConformanceIssue[] = []\n const shellCaps = new Set(opts.knownShellCapabilities ?? DEFAULT_SHELL_CAPS)\n const allowedWithoutMcp = new Set(opts.toolsAllowedWithoutMcp ?? [])\n const tools = (profile.tools ?? {}) as Record<string, unknown>\n const mcp = (profile.mcp ?? {}) as Record<string, AgentProfileMcpServer>\n for (const [name, value] of Object.entries(tools)) {\n // Shell capabilities masquerading as tools — should be in permissions, not tools.\n if (shellCaps.has(name)) {\n issues.push({\n severity: 'error',\n code: 'shell-capability-as-tool',\n path: `tools.${name}`,\n message: `'${name}' is a shell capability, not a tool. Move to permissions and remove from tools.`,\n })\n continue\n }\n if (allowedWithoutMcp.has(name)) continue\n if (value === false) continue\n if (!mcp[name]) {\n issues.push({\n severity: 'error',\n code: 'decorative-tool-without-mcp',\n path: `tools.${name}`,\n message: `'${name}' declared in tools but no corresponding mcp[${name}] AgentProfileMcpServer. Either wire an MCP server, list this name in toolsAllowedWithoutMcp (if it's a file-mounted CLI binary), or remove from tools.`,\n })\n }\n }\n return issues\n}\n\nfunction checkSubagentShape(subagent: AgentSubagentProfile, id: string): ConformanceIssue[] {\n const issues: ConformanceIssue[] = []\n if (!subagent.description || subagent.description.trim().length < 40) {\n issues.push({\n severity: 'error',\n code: 'subagent-description-too-short',\n path: `subagents.${id}.description`,\n message: `subagents.${id}.description is missing or too short. Required for routing UX + audit trail.`,\n })\n }\n if (!subagent.prompt || subagent.prompt.trim().length < 100) {\n issues.push({\n severity: 'error',\n code: 'subagent-prompt-too-short',\n path: `subagents.${id}.prompt`,\n message: `subagents.${id}.prompt is missing or below 100 chars. Either ship the specialist prompt or move this subagent under metadata.plannedSubagents.`,\n })\n }\n return issues\n}\n\nfunction checkScaffoldSubagents(profile: AgentProfile, strict: boolean): ConformanceIssue[] {\n const issues: ConformanceIssue[] = []\n const subagents = profile.subagents ?? {}\n for (const [id, subagent] of Object.entries(subagents)) {\n const meta = subagent.metadata as Record<string, unknown> | undefined\n const status = meta?.status\n if (\n status === 'scaffold' ||\n status === 'not-implemented' ||\n (meta as { implemented?: boolean })?.implemented === false\n ) {\n issues.push({\n severity: strict ? 'error' : 'warn',\n code: 'subagent-scaffold-shipped',\n path: `subagents.${id}`,\n message: `subagents.${id} is a scaffold (metadata.status='${status}'). Router must gate on metadata.status === 'full' OR caller must opt into scaffolds explicitly.`,\n })\n }\n }\n return issues\n}\n\n/**\n * Run all conformance checks against a profile. Designed to be called from\n * a unit test:\n *\n * it('legalAgentProfile passes conformance', () => {\n * const result = assertProfileConformance(legalAgentProfile, {\n * toolsAllowedWithoutMcp: ['agent-knowledge:query'], // in-process function\n * })\n * expect(result.valid).toBe(true)\n * expect(result.errors).toEqual([])\n * })\n *\n * Issues carry `path` + `code` so tests can pinpoint failures rather than\n * collapse to a generic \"validation failed.\"\n */\nexport function assertProfileConformance(\n profile: AgentProfile,\n opts: ConformanceOptions = {},\n): ConformanceResult {\n const issues = [\n ...checkSystemPrompt(profile, opts.minSystemPromptChars ?? DEFAULT_MIN_PROMPT_CHARS),\n ...checkToolsVsMcp(profile, opts),\n ...checkScaffoldSubagents(profile, opts.strictNoScaffolds ?? false),\n ]\n for (const [id, subagent] of Object.entries(profile.subagents ?? {})) {\n issues.push(...checkSubagentShape(subagent, id))\n }\n const errors = issues.filter((i) => i.severity === 'error')\n const warnings = issues.filter((i) => i.severity === 'warn')\n return { valid: errors.length === 0, errors, warnings }\n}\n","/**\n * @stable\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\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/** @stable */\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 * @stable\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\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n type KnowledgeReadinessReport,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { SessionMismatchError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { newRuntimeSession, nowIso, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentExecutionBackend,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskRunSummary,\n AgentTaskSpec,\n AgentTaskStatus,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\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: (options.adapter.projectRunRecords?.(control, task) ?? []).map((record) =>\n record.scenarioId === undefined ? { ...record, scenarioId } : record,\n ),\n }\n}\n\n/** @stable */\nexport function summarizeAgentTaskRun<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(result: AgentTaskRunResult<TState, TAction, TActionResult, TEval>): AgentTaskRunSummary {\n return {\n taskId: result.task.id,\n domain: result.task.domain,\n status: result.status,\n reason: result.control.reason,\n readinessStatus: decideKnowledgeReadiness(result.knowledge).status,\n readinessScore: result.knowledge.readinessScore,\n recommendedAction: result.knowledge.recommendedAction,\n blockingGapIds: result.knowledge.blockingMissingRequirements.map(\n (requirement) => requirement.id,\n ),\n nonBlockingGapIds: result.knowledge.nonBlockingGaps.map((requirement) => requirement.id),\n questionCount: result.questions.length,\n acquisitionPlanCount: result.acquisitionPlans.length,\n acquiredEvidenceCount: result.acquiredEvidenceIds.length,\n controlStepCount: result.control.steps.length,\n pass: result.control.pass,\n failureClass: result.control.failureClass,\n wallMs: result.control.wallMs,\n costUsd: result.control.spentCostUsd,\n }\n}\n\n/** @stable */\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 existing = options.sessionId ? await store?.get(options.sessionId) : undefined\n const shouldResume = Boolean(options.resume && existing)\n let session =\n shouldResume && existing\n ? await resumeBackendSession(options.backend, existing, input, {\n task,\n knowledge,\n signal: options.signal,\n })\n : await startBackendSession(\n options.backend,\n input,\n { task, knowledge, signal: options.signal },\n options.sessionId,\n )\n await store?.put(session)\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(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 backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: stopErrorMessage ? `${message}; backend stop failed: ${stopErrorMessage}` : message,\n recoverable: !options.signal?.aborted,\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 })\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\nasync function startBackendSession<TInput extends AgentBackendInput>(\n backend: AgentExecutionBackend<TInput>,\n input: TInput,\n context: { task: AgentTaskSpec; knowledge: KnowledgeReadinessReport; signal?: AbortSignal },\n requestedSessionId?: string,\n): Promise<RuntimeSession> {\n if (backend.start) return backend.start(input, { ...context, requestedSessionId })\n return newRuntimeSession(backend.kind, requestedSessionId)\n}\n\nasync function resumeBackendSession<TInput extends AgentBackendInput>(\n backend: AgentExecutionBackend<TInput>,\n session: RuntimeSession,\n input: TInput,\n context: { task: AgentTaskSpec; knowledge: KnowledgeReadinessReport; signal?: AbortSignal },\n): Promise<RuntimeSession> {\n if (session.backend !== backend.kind) {\n throw new SessionMismatchError(session.backend, backend.kind)\n }\n if (backend.resume) return backend.resume(session, input, context)\n return touchSession({ ...session, status: 'active' })\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 * @stable\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\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 * @stable\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\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 * @stable\n *\n * Sanitization for runtime telemetry. The rule: nothing user-controlled leaks\n * unless the caller opts in with a `RuntimeTelemetryOptions` flag. This is the\n * envelope that ends up in `agent_run.metadata.runtimeEvents` on every\n * consumer, so the default must be safe.\n */\n\nimport type {\n ControlEvalResult,\n ControlRunResult,\n ControlStep,\n DataAcquisitionPlan,\n KnowledgeReadinessReport,\n KnowledgeRequirement,\n UserQuestion,\n} from '@tangle-network/agent-eval'\n\nimport type {\n AgentRuntimeEvent,\n AgentTaskSpec,\n AgentTaskStatus,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\nexport interface RuntimeTelemetryOptions {\n /**\n * Include raw task inputs. Off by default because task inputs often contain\n * customer facts, credentials, source text, or internal IDs.\n */\n includeInputs?: boolean\n /** Include requirement descriptions. Secret requirements are always redacted. */\n includeRequirementDescriptions?: boolean\n /** Include evidence IDs. Off by default; counts are safer for shared reports. */\n includeEvidenceIds?: boolean\n /** Include user answers from question preflight. Off by default. */\n includeUserAnswers?: boolean\n /** Include action payloads and action results for control steps. Off by default. */\n includeControlPayloads?: boolean\n /** Include task metadata. Off by default because metadata may carry IDs or policy internals. */\n includeMetadata?: boolean\n /** Include eval detail/evidence strings. Off by default because validators may echo private input. */\n includeEvalDetails?: boolean\n}\n\n/** @stable */\nexport interface SanitizedKnowledgeRequirement {\n id: string\n description?: string\n requiredFor: string[]\n category: KnowledgeRequirement['category']\n acquisitionMode: KnowledgeRequirement['acquisitionMode']\n importance: KnowledgeRequirement['importance']\n freshness: KnowledgeRequirement['freshness']\n sensitivity: KnowledgeRequirement['sensitivity']\n confidenceNeeded: number\n currentConfidence: number\n evidenceCount: number\n evidenceIds?: string[]\n fallbackPolicy: KnowledgeRequirement['fallbackPolicy']\n}\n\n/** @stable */\nexport interface SanitizedKnowledgeReadinessReport {\n taskId: string\n readinessScore: number\n recommendedAction: KnowledgeReadinessReport['recommendedAction']\n severity: KnowledgeReadinessReport['severity']\n reason: string\n blockingMissingRequirements: SanitizedKnowledgeRequirement[]\n nonBlockingGaps: SanitizedKnowledgeRequirement[]\n evidenceCount: number\n evidenceIds?: string[]\n missingRequirementIds: string[]\n}\n\n/** @stable */\nexport function sanitizeKnowledgeReadinessReport(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions = {},\n): SanitizedKnowledgeReadinessReport {\n return {\n taskId: report.taskId,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n reason: report.reason,\n blockingMissingRequirements: report.blockingMissingRequirements.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n nonBlockingGaps: report.nonBlockingGaps.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n evidenceCount: report.bundle.evidenceIds.length,\n evidenceIds: options.includeEvidenceIds ? report.bundle.evidenceIds : undefined,\n missingRequirementIds: report.bundle.missing.map((requirement) => requirement.id),\n }\n}\n\n/** @stable */\nexport function sanitizeAgentRuntimeEvent<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions = {},\n): Record<string, unknown> {\n const base = { type: event.type, task: sanitizeTask(event.task, options) }\n if (\n event.type === 'readiness_start' ||\n event.type === 'task_start' ||\n event.type === 'control_start'\n ) {\n return event.type === 'control_start'\n ? { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) }\n : base\n }\n if (event.type === 'readiness_end') {\n return { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) }\n }\n if (event.type === 'questions_start') {\n return {\n ...base,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n }\n }\n if (event.type === 'questions_end') {\n return {\n ...base,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers),\n }\n }\n if (event.type === 'acquisition_start') {\n return { ...base, acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan) }\n }\n if (event.type === 'acquisition_end') {\n return {\n ...base,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n acquiredEvidenceCount: event.acquiredEvidenceIds.length,\n acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : undefined,\n }\n }\n if (event.type === 'control_step') {\n return { ...base, step: sanitizeControlStep(event.step, options) }\n }\n if (event.type === 'control_end') {\n return { ...base, control: sanitizeControlRun(event.control, options) }\n }\n return { ...base, status: event.status, reason: event.reason }\n}\n\n/** @stable */\nexport function sanitizeRuntimeStreamEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions = {},\n): Record<string, unknown> {\n const withTask = 'task' in event && event.task ? { task: sanitizeTask(event.task, options) } : {}\n const withSession =\n 'session' in event && event.session\n ? { session: sanitizeRuntimeSession(event.session, options) }\n : {}\n\n if (event.type === 'readiness_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n decision: event.decision,\n knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options),\n }\n }\n if (event.type === 'questions_start') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n }\n }\n if (event.type === 'questions_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers),\n }\n }\n if (event.type === 'acquisition_start') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n }\n }\n if (event.type === 'acquisition_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n acquiredEvidenceCount: event.acquiredEvidenceIds.length,\n acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : undefined,\n }\n }\n if (event.type === 'tool_call') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n args: options.includeControlPayloads ? event.args : undefined,\n }\n }\n if (event.type === 'tool_result') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n result: options.includeControlPayloads ? event.result : undefined,\n }\n }\n if (event.type === 'llm_call') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n model: event.model,\n tokensIn: event.tokensIn,\n tokensOut: event.tokensOut,\n costUsd: event.costUsd,\n latencyMs: event.latencyMs,\n finishReason: event.finishReason,\n }\n }\n if (event.type === 'artifact') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n artifactId: event.artifactId,\n name: event.name,\n mimeType: event.mimeType,\n uri: options.includeEvidenceIds ? event.uri : undefined,\n content: options.includeControlPayloads ? event.content : undefined,\n metadata: options.includeMetadata ? event.metadata : undefined,\n }\n }\n if (event.type === 'proposal_created') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n proposalId: event.proposalId,\n title: options.includeControlPayloads ? event.title : undefined,\n status: event.status,\n }\n }\n if (event.type === 'final') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n status: event.status,\n reason: event.reason,\n text: options.includeControlPayloads ? event.text : undefined,\n metadata: options.includeMetadata ? event.metadata : undefined,\n }\n }\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: 'timestamp' in event ? event.timestamp : undefined,\n ...pickPublicStreamFields(event),\n }\n}\n\nfunction sanitizeTask(\n task: AgentTaskSpec,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: task.id,\n intent: task.intent,\n domain: task.domain,\n inputs: options.includeInputs ? task.inputs : task.inputs ? '[redacted]' : undefined,\n requiredKnowledge: task.requiredKnowledge?.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n metadata: options.includeMetadata ? task.metadata : task.metadata ? '[redacted]' : undefined,\n }\n}\n\nfunction sanitizeRuntimeSession(\n session: RuntimeSession,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: session.id,\n backend: session.backend,\n status: session.status,\n hasResumeToken: Boolean(session.resumeToken),\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n metadata: options.includeMetadata\n ? session.metadata\n : session.metadata\n ? '[redacted]'\n : undefined,\n }\n}\n\nfunction sanitizeKnowledgeRequirement(\n requirement: KnowledgeRequirement,\n options: RuntimeTelemetryOptions,\n): SanitizedKnowledgeRequirement {\n const includeDescription =\n options.includeRequirementDescriptions && requirement.sensitivity !== 'secret'\n return {\n id: requirement.id,\n description: includeDescription ? requirement.description : undefined,\n requiredFor: requirement.requiredFor,\n category: requirement.category,\n acquisitionMode: requirement.acquisitionMode,\n importance: requirement.importance,\n freshness: requirement.freshness,\n sensitivity: requirement.sensitivity,\n confidenceNeeded: requirement.confidenceNeeded,\n currentConfidence: requirement.currentConfidence,\n evidenceCount: requirement.evidenceIds.length,\n evidenceIds: options.includeEvidenceIds ? requirement.evidenceIds : undefined,\n fallbackPolicy: requirement.fallbackPolicy,\n }\n}\n\nfunction sanitizeQuestion(\n question: UserQuestion,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: question.id,\n question:\n options.includeRequirementDescriptions && question.answerType !== 'credential'\n ? question.question\n : undefined,\n reason: options.includeRequirementDescriptions ? question.reason : undefined,\n requirementId: question.requirementId,\n importance: question.importance,\n answerType: question.answerType,\n impactIfUnknown: options.includeRequirementDescriptions ? question.impactIfUnknown : undefined,\n optionCount: question.options?.length ?? 0,\n }\n}\n\nfunction sanitizeAcquisitionPlan(plan: DataAcquisitionPlan): Record<string, unknown> {\n return {\n id: plan.id,\n requirementIds: plan.requirementIds,\n mode: plan.mode,\n priority: plan.priority,\n expectedEvidenceCount: plan.expectedEvidenceIds?.length ?? 0,\n questionCount: plan.questions?.length ?? 0,\n }\n}\n\nfunction sanitizeControlStep<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n step: ControlStep<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n const actionOutcome = step.actionOutcome\n return {\n index: step.index,\n decisionType: step.decision.type,\n reason: step.decision.reason,\n action:\n options.includeControlPayloads && step.decision.type === 'continue'\n ? step.decision.action\n : undefined,\n result: options.includeControlPayloads && actionOutcome?.ok ? actionOutcome.result : undefined,\n actionOk: actionOutcome?.ok,\n actionError: actionOutcome?.ok === false ? actionOutcome.error : undefined,\n durationMs: actionOutcome?.durationMs,\n evalsBefore: summarizeEvals(step.evalsBefore, options),\n evalsAfter: summarizeEvals(step.evalsAfter, options),\n startedAt: step.startedAt,\n endedAt: step.endedAt,\n }\n}\n\nfunction sanitizeControlRun<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n control: ControlRunResult<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n pass: control.pass,\n completed: control.completed,\n reason: control.reason,\n score: control.score,\n stepCount: control.steps.length,\n wallMs: control.wallMs,\n spentCostUsd: control.spentCostUsd,\n failureClass: control.failureClass,\n stoppedBy: control.stoppedBy,\n runId: control.runId,\n runtimeErrorCount: control.runtimeErrors.length,\n finalEvals: summarizeEvals(control.finalEvals, options),\n }\n}\n\nfunction summarizeEvals(\n evals: ControlEvalResult[],\n options: RuntimeTelemetryOptions,\n): Array<Record<string, unknown>> {\n return evals.map((evalResult) => ({\n id: evalResult.id,\n passed: evalResult.passed,\n score: evalResult.score,\n severity: evalResult.severity,\n objective: evalResult.objective,\n detail: options.includeEvalDetails ? evalResult.detail : undefined,\n evidence: options.includeEvalDetails ? evalResult.evidence : undefined,\n }))\n}\n\nfunction redactRecord(record: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(record).map((key) => [key, '[redacted]']))\n}\n\nfunction pickPublicStreamFields(event: RuntimeStreamEvent): Record<string, unknown> {\n if (event.type === 'session_created' || event.type === 'session_resumed') return {}\n if (event.type === 'backend_start' || event.type === 'backend_end')\n return { backend: event.backend }\n if (event.type === 'backend_error') {\n return { backend: event.backend, message: event.message, recoverable: event.recoverable }\n }\n if (event.type === 'task_end') return { status: event.status, reason: event.reason }\n if (event.type === 'text_delta' || event.type === 'reasoning_delta') return { text: event.text }\n return {}\n}\n\n/** @stable */\nexport interface RuntimeEventCollector<\n TState = unknown,\n TAction = unknown,\n TActionResult = unknown,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n onEvent: (event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>) => void\n events: Array<Record<string, unknown>>\n}\n\n/** @stable */\nexport type RuntimeStreamEventSink = (event: RuntimeStreamEvent) => void\n\n/** @stable */\nexport interface RuntimeStreamEventSummary {\n /** Total count of sanitized events collected. */\n eventCount: number\n /** Count of events per `type`. Useful for log-line summaries. */\n eventCountsByType: Record<string, number>\n /** First session id observed in a `session_created` / `session_resumed` event, if any. */\n firstSessionId?: string\n /** Last `final` event's status, if a final event was observed. */\n finalStatus?: AgentTaskStatus\n /** Last `final` event's reason, if a final event was observed. */\n finalReason?: string\n /** Concatenated `text_delta.text` across the stream, even when payloads are redacted. */\n finalText: string\n}\n\n/** @stable */\nexport interface RuntimeStreamEventCollector {\n onEvent: RuntimeStreamEventSink\n events: Array<Record<string, unknown>>\n /** Snapshot of a small streaming-flavored summary derived from collected events. */\n summary(): RuntimeStreamEventSummary\n}\n\n/** @stable */\nexport function createRuntimeEventCollector<\n TState = unknown,\n TAction = unknown,\n TActionResult = unknown,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RuntimeTelemetryOptions = {},\n): RuntimeEventCollector<TState, TAction, TActionResult, TEval> {\n const events: Array<Record<string, unknown>> = []\n return {\n events,\n onEvent: (event) => {\n events.push(sanitizeAgentRuntimeEvent(event, options))\n },\n }\n}\n\n/**\n * @stable\n *\n * Streaming-event counterpart of `createRuntimeEventCollector`. Pass each\n * event yielded by `runAgentTaskStream` through `onEvent` and read the\n * sanitized copies off `events`; the same `RuntimeTelemetryOptions` redaction\n * flags apply. Kept distinct from `createRuntimeEventCollector` because the\n * stream and non-stream event shapes overlap on `type` literals — dispatching\n * on `type` alone would misroute events.\n */\nexport function createRuntimeStreamEventCollector(\n options: RuntimeTelemetryOptions = {},\n): RuntimeStreamEventCollector {\n const events: Array<Record<string, unknown>> = []\n const eventCountsByType: Record<string, number> = {}\n let firstSessionId: string | undefined\n let finalStatus: AgentTaskStatus | undefined\n let finalReason: string | undefined\n let finalText = ''\n return {\n events,\n onEvent: (event) => {\n events.push(sanitizeRuntimeStreamEvent(event, options))\n eventCountsByType[event.type] = (eventCountsByType[event.type] ?? 0) + 1\n if (event.type === 'text_delta') finalText += event.text\n if (\n !firstSessionId &&\n (event.type === 'session_created' || event.type === 'session_resumed')\n ) {\n firstSessionId = event.session.id\n }\n if (event.type === 'final') {\n finalStatus = event.status\n finalReason = event.reason\n }\n },\n summary() {\n return {\n eventCount: events.length,\n eventCountsByType: { ...eventCountsByType },\n firstSessionId,\n finalStatus,\n finalReason,\n finalText,\n }\n },\n }\n}\n","/**\n * @stable\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\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/** @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/** @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","/**\n * @stable\n *\n * One-way bridge from `RuntimeStreamEvent` to agent-eval's `TraceEvent`.\n *\n * The reverse direction is intentionally unsupported — agent-eval events\n * have no session / task affinity, so round-tripping would erase information.\n */\n\nimport type { EventKind, TraceEvent } from '@tangle-network/agent-eval'\n\nimport { ValidationError } from './errors'\nimport type { RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport interface TraceBridgeOptions {\n /**\n * Stable `runId` to stamp on every emitted `TraceEvent`. Required because\n * agent-eval's `TraceEvent.runId` is non-optional.\n */\n runId: string\n /**\n * Optional `spanId` to attach when an event maps to a known span (for\n * example, an outer runtime-task span the consumer is already emitting).\n */\n spanId?: string\n /**\n * Optional id generator; default = monotonic counter scoped to this bridge\n * instance. Override for deterministic tests or to integrate with a wider\n * id-allocator (uuid, ksuid).\n */\n newEventId?: () => string\n}\n\n/** @stable */\nexport interface TraceBridge {\n /**\n * Map a single `RuntimeStreamEvent` to a `TraceEvent`. Returns `undefined`\n * for events that have no useful trace projection (text deltas, reasoning\n * deltas — these belong inside an `LlmSpan.output`, not as separate trace\n * events).\n */\n toTraceEvent(event: RuntimeStreamEvent): TraceEvent | undefined\n /** Convenience: drain an iterable of stream events into trace events. */\n drain(events: Iterable<RuntimeStreamEvent>): TraceEvent[]\n}\n\n/**\n * @stable\n *\n * Build a stateful bridge. State is intentionally minimal — only the event-id\n * counter — because the runtime stream already carries timestamps and the\n * caller already knows the `runId`.\n */\nexport function createTraceBridge(options: TraceBridgeOptions): TraceBridge {\n if (!options.runId) {\n throw new ValidationError('createTraceBridge: runId is required')\n }\n let counter = 0\n const newEventId = options.newEventId ?? (() => `evt-${++counter}`)\n const baseSpanId = options.spanId\n\n const toTraceEvent = (event: RuntimeStreamEvent): TraceEvent | undefined => {\n const projection = projectToTraceEvent(event)\n if (!projection) return undefined\n return {\n eventId: newEventId(),\n runId: options.runId,\n spanId: baseSpanId,\n kind: projection.kind,\n timestamp: timestampFor(event),\n payload: projection.payload,\n }\n }\n\n return {\n toTraceEvent,\n drain(events) {\n const out: TraceEvent[] = []\n for (const event of events) {\n const trace = toTraceEvent(event)\n if (trace) out.push(trace)\n }\n return out\n },\n }\n}\n\n/**\n * @stable\n *\n * One-shot convenience for callers who don't want to hold a bridge instance.\n * Internally allocates a single-use bridge so id-generation stays consistent\n * within the call.\n */\nexport function toAgentEvalTrace(\n event: RuntimeStreamEvent,\n options: TraceBridgeOptions,\n): TraceEvent | undefined {\n return createTraceBridge(options).toTraceEvent(event)\n}\n\ninterface TraceProjection {\n kind: EventKind\n payload: Record<string, unknown>\n}\n\nfunction projectToTraceEvent(event: RuntimeStreamEvent): TraceProjection | undefined {\n switch (event.type) {\n case 'task_start':\n return {\n kind: 'log',\n payload: { phase: 'task_start', taskId: event.task.id, intent: event.task.intent },\n }\n case 'readiness_start':\n return { kind: 'log', payload: { phase: 'readiness_start', taskId: event.task.id } }\n case 'readiness_end':\n return {\n kind: event.decision.passed ? 'log' : 'policy_violation',\n payload: {\n phase: 'readiness_end',\n taskId: event.task.id,\n status: event.decision.status,\n readinessScore: event.decision.readinessScore,\n blockingGapIds: event.decision.blockingGapIds,\n nonBlockingGapIds: event.decision.nonBlockingGapIds,\n reason: event.decision.reason,\n },\n }\n case 'questions_start':\n return {\n kind: 'log',\n payload: { phase: 'questions_start', questionCount: event.questions.length },\n }\n case 'questions_end':\n return {\n kind: 'log',\n payload: {\n phase: 'questions_end',\n questionCount: event.questions.length,\n answerCount: Object.keys(event.userAnswers).length,\n },\n }\n case 'acquisition_start':\n return {\n kind: 'log',\n payload: { phase: 'acquisition_start', planCount: event.acquisitionPlans.length },\n }\n case 'acquisition_end':\n return {\n kind: 'log',\n payload: {\n phase: 'acquisition_end',\n planCount: event.acquisitionPlans.length,\n evidenceCount: event.acquiredEvidenceIds.length,\n },\n }\n case 'session_created':\n case 'session_resumed':\n return {\n kind: 'log',\n payload: {\n phase: event.type,\n sessionId: event.session.id,\n backend: event.session.backend,\n },\n }\n case 'backend_start':\n case 'backend_end':\n return { kind: 'log', payload: { phase: event.type, backend: event.backend } }\n case 'backend_error':\n return {\n kind: 'error',\n payload: {\n backend: event.backend,\n message: event.message,\n recoverable: event.recoverable,\n },\n }\n case 'tool_call':\n return {\n kind: 'log',\n payload: {\n phase: 'tool_call',\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n // Args omitted — trace events are point-in-time markers, not the\n // canonical store for tool I/O. Attach payloads to a `ToolSpan`\n // when retention is required.\n },\n }\n case 'tool_result':\n return {\n kind: 'log',\n payload: {\n phase: 'tool_result',\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n },\n }\n case 'llm_call':\n return {\n kind: 'log',\n payload: {\n phase: 'llm_call',\n model: event.model,\n tokensIn: event.tokensIn,\n tokensOut: event.tokensOut,\n costUsd: event.costUsd,\n latencyMs: event.latencyMs,\n finishReason: event.finishReason,\n },\n }\n case 'artifact':\n return {\n kind: 'state_mutation',\n payload: {\n phase: 'artifact',\n artifactId: event.artifactId,\n name: event.name,\n mimeType: event.mimeType,\n },\n }\n case 'proposal_created':\n return {\n kind: 'state_mutation',\n payload: {\n phase: 'proposal_created',\n proposalId: event.proposalId,\n title: event.title,\n status: event.status,\n },\n }\n case 'task_end':\n return {\n kind: event.status === 'failed' || event.status === 'aborted' ? 'error' : 'log',\n payload: { phase: 'task_end', status: event.status, reason: event.reason },\n }\n case 'final':\n return {\n kind: event.status === 'failed' || event.status === 'aborted' ? 'error' : 'log',\n payload: { phase: 'final', status: event.status, reason: event.reason },\n }\n case 'text_delta':\n case 'reasoning_delta':\n // Token-level deltas don't map cleanly to a single `TraceEvent`. Consumers\n // accumulate the text into an `LlmSpan.output` or read the `final` event.\n return undefined\n default: {\n // Exhaustiveness guard — adding a new event type must add a case above.\n const exhaust: never = event\n void exhaust\n return undefined\n }\n }\n}\n\nfunction timestampFor(event: RuntimeStreamEvent): number {\n const iso = 'timestamp' in event ? event.timestamp : undefined\n if (!iso) return Date.now()\n const parsed = Date.parse(iso)\n return Number.isFinite(parsed) ? parsed : Date.now()\n}\n"],"mappings":"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","names":["AgentEvalError","emit"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/sessions.ts","../src/backends.ts","../src/durable/chat-engine.ts","../src/durable/execution-handle.ts","../src/model-resolution.ts","../src/readiness.ts","../src/run.ts","../src/runtime-run.ts","../src/sanitize.ts","../src/sse.ts"],"sourcesContent":["/**\n * @stable\n *\n * Error taxonomy for `@tangle-network/agent-runtime`.\n *\n * Public contract: every error this package throws as part of its consumer-\n * facing API either extends `AgentEvalError` (re-exported here for ergonomic\n * `instanceof` checks at the runtime boundary) or extends one of the\n * runtime-specific subclasses below.\n *\n * Internal invariant guards (`throw new Error('this should never happen')`)\n * remain plain `Error` — they are programmer-mistake assertions, not\n * consumer-catchable contract failures.\n *\n * Subclassing strategy: where a runtime-specific failure maps cleanly to an\n * agent-eval code (validation, config, not_found), we re-use the agent-eval\n * subclass. Runtime-only failure modes (session resume against the wrong\n * backend, backend transport errors) get fresh subclasses that still carry an\n * `AgentEvalErrorCode` so cross-package handlers can pattern-match without\n * importing the runtime.\n */\n\nimport { AgentEvalError } from '@tangle-network/agent-eval'\n\nexport {\n AgentEvalError,\n type AgentEvalErrorCode,\n CaptureIntegrityError,\n ConfigError,\n JudgeError,\n NotFoundError,\n ReplayError,\n ValidationError,\n VerificationError,\n} from '@tangle-network/agent-eval'\n\n/**\n * @stable\n *\n * Caller asked to resume a session against a backend whose `kind` does not\n * match the session's recorded backend. This is a routing bug — the same\n * session id was reused across two different backend implementations — and\n * is not retryable without picking the right backend.\n */\nexport class SessionMismatchError extends AgentEvalError {\n readonly sessionBackend: string\n readonly requestedBackend: string\n\n constructor(sessionBackend: string, requestedBackend: string, options?: { cause?: unknown }) {\n super(\n 'validation',\n `Cannot resume ${sessionBackend} session with ${requestedBackend} backend`,\n options,\n )\n this.sessionBackend = sessionBackend\n this.requestedBackend = requestedBackend\n }\n}\n\n/**\n * @stable\n *\n * A backend transport call (HTTP, gRPC, sidecar IPC) failed with a non-success\n * status. Distinct from `JudgeError` (which is structural / unrecoverable)\n * because backend failures are sometimes retryable and consumers may want to\n * branch on the upstream status code.\n */\nexport class BackendTransportError extends AgentEvalError {\n readonly backend: string\n readonly status?: number\n\n constructor(backend: string, message: string, options?: { cause?: unknown; status?: number }) {\n super('config', message, options)\n this.backend = backend\n this.status = options?.status\n }\n}\n\n/**\n * @stable\n *\n * A runtime-run lifecycle method was called in an order the state machine does\n * not allow: `persist()` before `complete()`, `complete()` twice, etc.\n */\nexport class RuntimeRunStateError extends AgentEvalError {\n constructor(message: string, options?: { cause?: unknown }) {\n super('validation', message, options)\n }\n}\n","/**\n * @stable\n *\n * Session helpers + an in-memory `RuntimeSessionStore` implementation suitable\n * for tests, scratch processes, and per-request scratch storage in serverless\n * runtimes. Durable stores (D1, postgres, Durable Objects) implement the same\n * interface from `./types`.\n */\n\nimport type { RuntimeSession, RuntimeSessionStore, RuntimeStreamEvent } from './types'\n\n/** @internal */\nexport function newRuntimeSession(\n backend: string,\n requestedId?: string,\n metadata?: Record<string, unknown>,\n): RuntimeSession {\n const now = nowIso()\n return {\n id: requestedId || crypto.randomUUID(),\n backend,\n status: 'active',\n createdAt: now,\n updatedAt: now,\n metadata,\n }\n}\n\n/** @internal */\nexport function touchSession(session: RuntimeSession): RuntimeSession {\n return { ...session, updatedAt: nowIso() }\n}\n\n/** @internal */\nexport function nowIso(): string {\n return new Date().toISOString()\n}\n\n/** @stable */\nexport class InMemoryRuntimeSessionStore implements RuntimeSessionStore {\n private readonly sessions = new Map<string, RuntimeSession>()\n private readonly events = new Map<string, RuntimeStreamEvent[]>()\n\n get(sessionId: string): RuntimeSession | undefined {\n return this.sessions.get(sessionId)\n }\n\n put(session: RuntimeSession): void {\n this.sessions.set(session.id, session)\n }\n\n appendEvent(sessionId: string, event: RuntimeStreamEvent): void {\n const existing = this.events.get(sessionId) ?? []\n existing.push(event)\n this.events.set(sessionId, existing)\n }\n\n listEvents(sessionId: string): RuntimeStreamEvent[] {\n return [...(this.events.get(sessionId) ?? [])]\n }\n}\n","/**\n * @stable\n *\n * Backend factories for `runAgentTaskStream`. Three shapes ship in core:\n *\n * - `createIterableBackend` — wrap any custom async iterable into a backend\n * - `createSandboxPromptBackend` — sandbox / sidecar `streamPrompt` clients\n * - `createOpenAICompatibleBackend` — OpenAI-style chat completions endpoints\n *\n * Adapters stay thin: domain repos own auth, model selection, and the concrete\n * tool surface. The factories handle session creation, stream normalization,\n * and graceful end-of-stream signalling.\n */\n\nimport { BackendTransportError } from './errors'\nimport { newRuntimeSession, nowIso, touchSession } from './sessions'\nimport type {\n AgentBackendContext,\n AgentBackendInput,\n AgentExecutionBackend,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\nexport function createIterableBackend<TInput extends AgentBackendInput>(options: {\n kind: string\n start?: AgentExecutionBackend<TInput>['start']\n resume?: AgentExecutionBackend<TInput>['resume']\n stream: AgentExecutionBackend<TInput>['stream']\n stop?: AgentExecutionBackend<TInput>['stop']\n}): AgentExecutionBackend<TInput> {\n return options\n}\n\n/** @stable */\nexport function createSandboxPromptBackend<\n TBox,\n TInput extends AgentBackendInput = AgentBackendInput,\n>(options: {\n kind?: string\n getBox(input: TInput, context: Omit<AgentBackendContext, 'session'>): Promise<TBox> | TBox\n streamPrompt(box: TBox, message: string, context: AgentBackendContext): AsyncIterable<unknown>\n mapEvent?: (event: unknown, context: AgentBackendContext) => RuntimeStreamEvent | undefined\n getSessionId?: (box: TBox, input: TInput) => string | undefined\n}): AgentExecutionBackend<TInput> {\n const kind = options.kind ?? 'sandbox'\n return {\n kind,\n async start(input, context) {\n const box = await options.getBox(input, context)\n return newRuntimeSession(\n kind,\n options.getSessionId?.(box, input) ?? context.requestedSessionId,\n { resumable: true },\n )\n },\n resume(session) {\n return touchSession({ ...session, status: 'active' })\n },\n async *stream(input, context) {\n const box = await options.getBox(input, context)\n const message = input.message ?? input.messages?.at(-1)?.content ?? context.task.intent\n for await (const event of options.streamPrompt(box, message, context)) {\n const mapped = options.mapEvent?.(event, context) ?? mapCommonBackendEvent(event, context)\n if (mapped) yield mapped\n }\n },\n }\n}\n\n/** @stable */\n/**\n * Retry policy for transient transport errors (rate limits, upstream\n * timeouts). Defaults to 5 attempts with exponential backoff starting at\n * 1s, ±25% jitter, capped at 30s. Set `maxAttempts: 1` to disable retries.\n *\n * Retried status codes:\n * - 408 Request Timeout\n * - 425 Too Early\n * - 429 Too Many Requests\n * - 500 / 502 / 503 / 504 — upstream transient failures\n *\n * Hard failures (401, 403, 4xx other than the above) propagate immediately.\n */\nexport interface BackendRetryPolicy {\n /** Total attempts including the first try. Default 5. */\n maxAttempts?: number\n /** Initial backoff in ms before the second attempt. Default 1000. */\n initialBackoffMs?: number\n /** Hard ceiling on backoff in ms. Default 30000. */\n maxBackoffMs?: number\n /** Jitter fraction in [0, 1]. Default 0.25 (±25%). */\n jitter?: number\n /** Status codes that trigger a retry. Default: 408, 425, 429, 500, 502, 503, 504. */\n retryStatuses?: ReadonlyArray<number>\n /**\n * Per-attempt wall-clock deadline in ms. If a single fetch attempt does\n * not return headers within this window the attempt is aborted and\n * retried. Default 120000 (2 min). Without this a hung upstream blocks\n * the attempt indefinitely — observed in production as a 15-minute\n * `fetch failed` that burned an entire eval persona. Set to 0 to disable.\n */\n requestTimeoutMs?: number\n}\n\nconst DEFAULT_RETRY_STATUSES = [408, 425, 429, 500, 502, 503, 504] as const\n\nfunction pickRetryDelayMs(attempt: number, policy: Required<BackendRetryPolicy>): number {\n const exp = policy.initialBackoffMs * 2 ** (attempt - 1)\n const capped = Math.min(exp, policy.maxBackoffMs)\n const jitter = capped * policy.jitter * (Math.random() * 2 - 1)\n return Math.max(0, Math.round(capped + jitter))\n}\n\n/**\n * Derive a per-attempt AbortSignal that fires when EITHER the caller's\n * signal aborts OR `timeoutMs` elapses. `dispose()` clears the timer so a\n * completed attempt doesn't leak a pending timeout. `timeoutMs <= 0`\n * disables the deadline (caller signal still propagates).\n */\nfunction withTimeout(\n callerSignal: AbortSignal | undefined,\n timeoutMs: number,\n): { signal: AbortSignal; dispose: () => void } {\n if (timeoutMs <= 0) {\n return { signal: callerSignal ?? new AbortController().signal, dispose: () => undefined }\n }\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(new Error(`request timed out after ${timeoutMs}ms`)),\n timeoutMs,\n )\n if (typeof (timer as { unref?: () => void }).unref === 'function') {\n ;(timer as { unref: () => void }).unref()\n }\n const onCallerAbort = () => controller.abort(callerSignal?.reason ?? new Error('aborted'))\n if (callerSignal) {\n if (callerSignal.aborted) onCallerAbort()\n else callerSignal.addEventListener('abort', onCallerAbort, { once: true })\n }\n return {\n signal: controller.signal,\n dispose: () => {\n clearTimeout(timer)\n callerSignal?.removeEventListener('abort', onCallerAbort)\n },\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error('aborted'))\n return\n }\n const t = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n const onAbort = () => {\n clearTimeout(t)\n reject(signal?.reason ?? new Error('aborted'))\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport function createOpenAICompatibleBackend<\n TInput extends AgentBackendInput = AgentBackendInput,\n>(options: {\n apiKey: string\n baseUrl: string\n model: string\n kind?: string\n fetchImpl?: typeof fetch\n retry?: BackendRetryPolicy\n}): AgentExecutionBackend<TInput> {\n const fetcher = options.fetchImpl ?? fetch\n const kind = options.kind ?? 'tcloud'\n const retryPolicy: Required<BackendRetryPolicy> = {\n maxAttempts: options.retry?.maxAttempts ?? 5,\n initialBackoffMs: options.retry?.initialBackoffMs ?? 1000,\n maxBackoffMs: options.retry?.maxBackoffMs ?? 30000,\n jitter: options.retry?.jitter ?? 0.25,\n retryStatuses: options.retry?.retryStatuses ?? DEFAULT_RETRY_STATUSES,\n requestTimeoutMs: options.retry?.requestTimeoutMs ?? 120_000,\n }\n return {\n kind,\n start(_input, context) {\n return newRuntimeSession(kind, context.requestedSessionId)\n },\n async *stream(input, context) {\n const url = `${options.baseUrl.replace(/\\/$/, '')}/chat/completions`\n const requestBody = JSON.stringify({\n model: options.model,\n stream: true,\n messages: input.messages ?? [\n { role: 'user', content: input.message ?? context.task.intent },\n ],\n })\n let response: Response | undefined\n let lastStatus = 0\n // The last thrown transport error (timeout abort, DNS / connection\n // failure). Network throws are retryable just like 5xx — without this\n // a `fetch failed` propagated immediately and burned the attempt.\n let lastThrown: unknown\n for (let attempt = 1; attempt <= retryPolicy.maxAttempts; attempt++) {\n lastThrown = undefined\n // Per-attempt deadline: abort a hung upstream instead of waiting\n // forever. Linked to context.signal so a caller cancel still wins.\n const attemptSignal = withTimeout(context.signal, retryPolicy.requestTimeoutMs)\n try {\n response = await fetcher(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: requestBody,\n signal: attemptSignal.signal,\n })\n } catch (err) {\n attemptSignal.dispose()\n // A caller-initiated abort is terminal — do not retry it.\n if (context.signal?.aborted) throw err\n lastThrown = err\n response = undefined\n if (attempt === retryPolicy.maxAttempts) break\n await sleep(pickRetryDelayMs(attempt, retryPolicy), context.signal)\n continue\n }\n attemptSignal.dispose()\n if (response.ok) break\n lastStatus = response.status\n if (!retryPolicy.retryStatuses.includes(response.status)) break\n if (attempt === retryPolicy.maxAttempts) break\n // Drain the failed body so the connection can be reused.\n try {\n await response.body?.cancel()\n } catch {\n // Best-effort — some runtimes don't expose cancel.\n }\n const delayMs = pickRetryDelayMs(attempt, retryPolicy)\n await sleep(delayMs, context.signal)\n }\n if (!response) {\n const reason = lastThrown instanceof Error ? lastThrown.message : String(lastThrown)\n throw new BackendTransportError(\n kind,\n `chat backend unreachable after ${retryPolicy.maxAttempts} attempts: ${reason}`,\n { status: 0 },\n )\n }\n if (!response.ok) {\n throw new BackendTransportError(kind, `chat backend returned ${lastStatus || 'unknown'}`, {\n status: lastStatus || 0,\n })\n }\n yield* streamResponseEvents(response, context)\n },\n }\n}\n\n/** @internal */\nexport function normalizeBackendStreamEvent(\n event: RuntimeStreamEvent,\n task: AgentBackendContext['task'],\n session: RuntimeSession,\n): RuntimeStreamEvent {\n if (\n 'task' in event &&\n event.task &&\n 'session' in event &&\n event.session &&\n 'timestamp' in event &&\n event.timestamp\n ) {\n return event\n }\n return {\n ...event,\n task: 'task' in event && event.task ? event.task : task,\n session: 'session' in event && event.session ? event.session : session,\n timestamp: 'timestamp' in event && event.timestamp ? event.timestamp : nowIso(),\n } as RuntimeStreamEvent\n}\n\nfunction mapCommonBackendEvent(\n event: unknown,\n context: AgentBackendContext,\n): RuntimeStreamEvent | undefined {\n if (!event || typeof event !== 'object') return undefined\n const record = event as Record<string, unknown>\n const type = String(record.type ?? '')\n const data =\n record.data && typeof record.data === 'object'\n ? (record.data as Record<string, unknown>)\n : record\n if (type === 'message.part.updated' || type === 'text_delta' || type === 'delta') {\n // `@tangle-network/sandbox` `box.streamTask` emits `message.part.updated`\n // with a nested part: `{ type: 'message.part.updated', data: { part:\n // { type: 'text', text: '…' } } }`. Walk into `data.part.text` so the\n // canonical sandbox-SDK shape produces a `text_delta` natively — no\n // per-product `mapEvent` shim required. Tool parts are picked up by\n // the `tool_call` / `tool_result` branches below; non-text parts here\n // fall through to `undefined` (the consumer can opt in via `mapEvent`).\n const part = data.part as Record<string, unknown> | undefined\n const partText =\n part !== undefined &&\n typeof part === 'object' &&\n (part.type === 'text' || part.type === undefined)\n ? stringValue(part.text)\n : undefined\n const text =\n stringValue(data.text) ?? stringValue(data.delta) ?? stringValue(record.text) ?? partText\n return text\n ? {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n if (type === 'reasoning_delta') {\n const text = stringValue(data.text) ?? stringValue(record.text)\n return text\n ? {\n type: 'reasoning_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n if (type === 'tool_call') {\n return {\n type: 'tool_call',\n task: context.task,\n session: context.session,\n toolName: stringValue(data.name) ?? stringValue(record.toolName) ?? 'tool',\n toolCallId: stringValue(data.id) ?? stringValue(record.toolCallId),\n args: data.args ?? data.input ?? record.args,\n timestamp: nowIso(),\n }\n }\n if (type === 'tool_result') {\n return {\n type: 'tool_result',\n task: context.task,\n session: context.session,\n toolName: stringValue(data.name) ?? stringValue(record.toolName) ?? 'tool',\n toolCallId: stringValue(data.id) ?? stringValue(record.toolCallId),\n result: data.result ?? data.output ?? record.result,\n timestamp: nowIso(),\n }\n }\n if (type === 'artifact') {\n const artifactId =\n stringValue(data.artifactId) ?? stringValue(data.id) ?? stringValue(record.artifactId)\n if (!artifactId) return undefined\n return {\n type: 'artifact',\n task: context.task,\n session: context.session,\n artifactId,\n name: stringValue(data.name) ?? stringValue(record.name),\n mimeType: stringValue(data.mimeType) ?? stringValue(record.mimeType),\n uri: stringValue(data.uri) ?? stringValue(record.uri),\n content: stringValue(data.content) ?? stringValue(data.body) ?? stringValue(record.content),\n metadata:\n data.metadata && typeof data.metadata === 'object'\n ? (data.metadata as Record<string, unknown>)\n : undefined,\n timestamp: nowIso(),\n }\n }\n if (type === 'proposal_created' || type === 'proposal' || type === 'filing') {\n const proposalId =\n stringValue(data.proposalId) ?? stringValue(data.id) ?? stringValue(record.proposalId)\n if (!proposalId) return undefined\n const status = stringValue(data.status) ?? stringValue(record.status)\n return {\n type: 'proposal_created',\n task: context.task,\n session: context.session,\n proposalId,\n title: stringValue(data.title) ?? stringValue(record.title) ?? proposalId,\n status:\n status === 'pending' || status === 'approved' || status === 'rejected' ? status : undefined,\n timestamp: nowIso(),\n }\n }\n if (type === 'result' || type === 'final') {\n const text = stringValue(data.finalText) ?? stringValue(data.text) ?? stringValue(record.text)\n return text\n ? {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n : undefined\n }\n return undefined\n}\n\nasync function* streamResponseEvents(\n response: Response,\n context: AgentBackendContext,\n): AsyncIterable<RuntimeStreamEvent> {\n const body = response.body\n if (!body) return\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n buffer += decoder.decode(value, { stream: true }).replace(/\\r\\n/g, '\\n')\n for (const event of drainStreamBuffer(false)) yield event\n }\n buffer += decoder.decode().replace(/\\r\\n/g, '\\n')\n for (const event of drainStreamBuffer(true)) yield event\n if (buffer.trim()) {\n const event = parseStreamChunk(buffer, context)\n if (event) yield event\n }\n\n function* drainStreamBuffer(flush: boolean): Iterable<RuntimeStreamEvent> {\n for (;;) {\n const sseBoundary = buffer.indexOf('\\n\\n')\n if (sseBoundary >= 0) {\n const chunk = buffer.slice(0, sseBoundary)\n buffer = buffer.slice(sseBoundary + 2)\n const event = parseStreamChunk(chunk, context)\n if (event) yield event\n continue\n }\n\n const newline = buffer.indexOf('\\n')\n if (newline >= 0 && !buffer.slice(0, newline).startsWith('data:')) {\n const line = buffer.slice(0, newline)\n buffer = buffer.slice(newline + 1)\n const event = parseStreamChunk(line, context)\n if (event) yield event\n continue\n }\n\n if (flush && buffer.trim() && !buffer.trimStart().startsWith('data:')) {\n const line = buffer\n buffer = ''\n const event = parseStreamChunk(line, context)\n if (event) yield event\n continue\n }\n\n break\n }\n }\n}\n\nfunction parseStreamChunk(\n chunk: string,\n context: AgentBackendContext,\n): RuntimeStreamEvent | undefined {\n const lines = chunk.split(/\\r?\\n/)\n const dataLines = lines.filter((line) => line.startsWith('data:'))\n const data =\n dataLines.length > 0\n ? dataLines.map((line) => line.slice(5).trimStart()).join('\\n')\n : chunk.trim()\n if (!data || data === '[DONE]') return undefined\n try {\n const parsed = JSON.parse(data) as Record<string, unknown>\n const choices = parsed.choices\n const choice = Array.isArray(choices)\n ? (choices[0] as Record<string, unknown> | undefined)\n : undefined\n const delta = choice?.delta as Record<string, unknown> | undefined\n const message = choice?.message as Record<string, unknown> | undefined\n const text =\n stringValue(delta?.content) ?? stringValue(message?.content) ?? stringValue(parsed.text)\n if (text) {\n return {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text,\n timestamp: nowIso(),\n }\n }\n return mapCommonBackendEvent(parsed, context)\n } catch {\n return {\n type: 'text_delta',\n task: context.task,\n session: context.session,\n text: data,\n timestamp: nowIso(),\n }\n }\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n","/**\n * `handleChatTurn` — framework-neutral chat-turn HTTP orchestrator.\n * Owns the NDJSON `ChatStreamEvent` line protocol, the `session.run.*`\n * lifecycle vocabulary, and the persist / post-process / trace-flush\n * hook order. Returns a `ReadableStream` body the product hands to its\n * platform `Response`.\n *\n * Execution durability is the substrate's concern: `box.streamPrompt`\n * auto-reconnects in-call; cross-process reconnect via `X-Execution-ID`\n * is the product's job. The producer this engine wraps already speaks\n * that protocol — the engine just frames the events.\n *\n * Hooks (`ChatTurnHooks`):\n * - `produce` — build the backend event stream\n * - `persistAssistantMessage` — write the assistant turn to the product DB\n * - `onTurnComplete?` — post-process (proposals, citations, …)\n * - `onEvent?` — per-event side channel (e.g. DO broadcast)\n * - `transformFinalText?` — pre-persist transform (e.g. PII redact)\n * - `traceFlush?` — handed to waitUntil so OTLP export lands\n *\n * Framework neutrality: takes already-resolved values (`identity` tuple,\n * a `waitUntil`), never a `Request` or a `Context`. The product's thin\n * route adapter does auth + parse + access-control, then calls\n * `handleChatTurn(...)` and returns `result.body` as its platform `Response`.\n */\n\n/** The NDJSON line protocol every product chat client already speaks. */\nexport interface ChatStreamEvent {\n type: string\n data?: Record<string, unknown>\n}\n\n/** Identity of a chat turn. `tenantId` is the workspace id for workspace-\n * scoped products and the user id for session-scoped products. */\nexport interface ChatTurnIdentity {\n tenantId: string\n /** Thread / session id. */\n sessionId: string\n userId: string\n /** Monotonic 0-based turn index within the session. */\n turnIndex: number\n}\n\n/** The live side of a turn — what the product's `produce` hook returns. */\nexport interface ChatTurnProducer<TEvent extends ChatStreamEvent = ChatStreamEvent> {\n /** The turn's event stream. Forwarded verbatim to the caller. */\n stream: AsyncGenerator<TEvent, void, unknown>\n /** The turn's final assistant text. Read once, after `stream` drains. */\n finalText(): string\n}\n\nexport interface ChatTurnHooks {\n /** Build the backend stream. The engine forwards events verbatim and\n * reads `finalText()` once the stream drains. */\n produce(): ChatTurnProducer\n /** Persist the assistant message to the product's own store. Called\n * once, after drain, with the assembled (transform-applied) text. */\n persistAssistantMessage(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional post-processing (proposals, citations, credit metering …).\n * Errors are swallowed + logged — post-process must never fail a turn\n * that already streamed successfully. */\n onTurnComplete?(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional per-event side channel (e.g. DO broadcast). Runs for every\n * emitted event, lifecycle envelope included. Errors swallowed — a\n * broadcast failure must not break the chat stream. */\n onEvent?(event: ChatStreamEvent): void | Promise<void>\n /** Optional pre-persist transform of the final text (e.g. PII\n * redaction). Affects only what is persisted; the live stream is\n * never altered. */\n transformFinalText?(text: string): string | Promise<string>\n /** Optional trace flush — resolves when OTLP export completes. Handed\n * to `waitUntil` so the worker isolate stays alive for the POST. */\n traceFlush?(): Promise<void>\n}\n\nexport interface RunChatTurnInput {\n identity: ChatTurnIdentity\n hooks: ChatTurnHooks\n /** Worker liveness hook. When omitted, trace flush is awaited inline\n * before the stream closes. */\n waitUntil?: (p: Promise<unknown>) => void\n /** Structured logger for swallowed hook errors. Defaults to\n * `console.error` so failures surface without product wiring. */\n log?: (message: string, meta?: Record<string, unknown>) => void\n}\n\nexport interface ChatTurnResult {\n /** NDJSON body — return this as the platform `Response` body. */\n body: ReadableStream<Uint8Array>\n /** Content type for the response. */\n contentType: 'application/x-ndjson'\n}\n\nconst encoder = new TextEncoder()\n\nfunction encodeLine(event: ChatStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`)\n}\n\nfunction defaultLog(message: string, meta?: Record<string, unknown>): void {\n if (meta) console.error(message, meta)\n else console.error(message)\n}\n\n/**\n * Run one chat turn. Returns immediately with a `ReadableStream` body;\n * the turn executes as the body is pulled. Never rejects — backend\n * failures surface as `error` + `session.run.failed` events.\n */\nexport function handleChatTurn(input: RunChatTurnInput): ChatTurnResult {\n const log = input.log ?? defaultLog\n const { identity, hooks } = input\n\n const body = new ReadableStream<Uint8Array>({\n start: async (controller) => {\n const emit = async (event: ChatStreamEvent): Promise<void> => {\n controller.enqueue(encodeLine(event))\n if (hooks.onEvent) {\n try {\n await hooks.onEvent(event)\n } catch (err) {\n log('[chat-engine] onEvent hook threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n }\n\n try {\n await emit({\n type: 'session.run.started',\n data: {\n sessionId: identity.sessionId,\n tenantId: identity.tenantId,\n turnIndex: identity.turnIndex,\n },\n })\n\n const producer = hooks.produce()\n for await (const event of producer.stream) {\n await emit(event)\n }\n const rawFinal = producer.finalText()\n const finalText = hooks.transformFinalText\n ? await hooks.transformFinalText(rawFinal)\n : rawFinal\n\n try {\n await hooks.persistAssistantMessage({ identity, finalText })\n } catch (err) {\n log('[chat-engine] persistAssistantMessage threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n if (hooks.onTurnComplete) {\n try {\n await hooks.onTurnComplete({ identity, finalText })\n } catch (err) {\n log('[chat-engine] onTurnComplete threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n await emit({\n type: 'session.run.completed',\n data: { sessionId: identity.sessionId },\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n log('[chat-engine] turn failed', { error: message })\n await emit({ type: 'error', data: { message } })\n await emit({\n type: 'session.run.failed',\n data: { sessionId: identity.sessionId, message },\n })\n } finally {\n if (hooks.traceFlush) {\n const flush = hooks.traceFlush().catch((err) =>\n log('[chat-engine] traceFlush threw', {\n error: err instanceof Error ? err.message : String(err),\n }),\n )\n if (input.waitUntil) input.waitUntil(flush)\n else await flush\n }\n controller.close()\n }\n },\n })\n\n return { body, contentType: 'application/x-ndjson' }\n}\n","/**\n * Derive a stable executionId from the run identity. The same\n * `(projectId, sessionId, turnIndex)` tuple yields the same id — so a\n * client retry of the same turn lands on the same substrate execution\n * and the orchestrator's buffer replays instead of starting a second\n * prompt.\n *\n * Format is readable, not hashed: operators grepping orchestrator logs\n * for `gtm-agent:thread-abc:3` find the run without translating an\n * opaque id. Substrate executionIds are not a secrecy boundary.\n *\n * Wire integration:\n * - `@tangle-network/sandbox@0.1.x` PromptOptions does not yet expose\n * `executionId`. The SDK auto-reconnects in-call by extracting it\n * from the response `execution.started` event; products do nothing.\n * - For cross-process reconnect today, bypass the SDK and POST to the\n * orchestrator's `/agents/run/stream` directly with this id in the\n * `X-Execution-ID` header (see tax-agent's `sessions.ts`).\n */\nexport function deriveExecutionId(input: {\n projectId: string\n sessionId: string\n turnIndex: number\n}): string {\n return `${input.projectId}:${input.sessionId}:${input.turnIndex}`\n}\n","/**\n * @stable\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\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\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\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 * @stable\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\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/** @stable */\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 * @stable\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\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n type KnowledgeReadinessReport,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { SessionMismatchError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { newRuntimeSession, nowIso, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentExecutionBackend,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskSpec,\n AgentTaskStatus,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\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: (options.adapter.projectRunRecords?.(control, task) ?? []).map((record) =>\n record.scenarioId === undefined ? { ...record, scenarioId } : record,\n ),\n }\n}\n\n/** @stable */\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 existing = options.sessionId ? await store?.get(options.sessionId) : undefined\n const shouldResume = Boolean(options.resume && existing)\n let session =\n shouldResume && existing\n ? await resumeBackendSession(options.backend, existing, input, {\n task,\n knowledge,\n signal: options.signal,\n })\n : await startBackendSession(\n options.backend,\n input,\n { task, knowledge, signal: options.signal },\n options.sessionId,\n )\n await store?.put(session)\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(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 backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: stopErrorMessage ? `${message}; backend stop failed: ${stopErrorMessage}` : message,\n recoverable: !options.signal?.aborted,\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 })\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\nasync function startBackendSession<TInput extends AgentBackendInput>(\n backend: AgentExecutionBackend<TInput>,\n input: TInput,\n context: { task: AgentTaskSpec; knowledge: KnowledgeReadinessReport; signal?: AbortSignal },\n requestedSessionId?: string,\n): Promise<RuntimeSession> {\n if (backend.start) return backend.start(input, { ...context, requestedSessionId })\n return newRuntimeSession(backend.kind, requestedSessionId)\n}\n\nasync function resumeBackendSession<TInput extends AgentBackendInput>(\n backend: AgentExecutionBackend<TInput>,\n session: RuntimeSession,\n input: TInput,\n context: { task: AgentTaskSpec; knowledge: KnowledgeReadinessReport; signal?: AbortSignal },\n): Promise<RuntimeSession> {\n if (session.backend !== backend.kind) {\n throw new SessionMismatchError(session.backend, backend.kind)\n }\n if (backend.resume) return backend.resume(session, input, context)\n return touchSession({ ...session, status: 'active' })\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 * @stable\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\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 * @stable\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\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 * @stable\n *\n * Sanitization for runtime telemetry. The rule: nothing user-controlled leaks\n * unless the caller opts in with a `RuntimeTelemetryOptions` flag. This is the\n * envelope that ends up in `agent_run.metadata.runtimeEvents` on every\n * consumer, so the default must be safe.\n */\n\nimport type {\n ControlEvalResult,\n ControlRunResult,\n ControlStep,\n DataAcquisitionPlan,\n KnowledgeReadinessReport,\n KnowledgeRequirement,\n UserQuestion,\n} from '@tangle-network/agent-eval'\n\nimport type {\n AgentRuntimeEvent,\n AgentTaskSpec,\n AgentTaskStatus,\n RuntimeSession,\n RuntimeStreamEvent,\n} from './types'\n\n/** @stable */\nexport interface RuntimeTelemetryOptions {\n /**\n * Include raw task inputs. Off by default because task inputs often contain\n * customer facts, credentials, source text, or internal IDs.\n */\n includeInputs?: boolean\n /** Include requirement descriptions. Secret requirements are always redacted. */\n includeRequirementDescriptions?: boolean\n /** Include evidence IDs. Off by default; counts are safer for shared reports. */\n includeEvidenceIds?: boolean\n /** Include user answers from question preflight. Off by default. */\n includeUserAnswers?: boolean\n /** Include action payloads and action results for control steps. Off by default. */\n includeControlPayloads?: boolean\n /** Include task metadata. Off by default because metadata may carry IDs or policy internals. */\n includeMetadata?: boolean\n /** Include eval detail/evidence strings. Off by default because validators may echo private input. */\n includeEvalDetails?: boolean\n}\n\n/** @stable */\nexport interface SanitizedKnowledgeRequirement {\n id: string\n description?: string\n requiredFor: string[]\n category: KnowledgeRequirement['category']\n acquisitionMode: KnowledgeRequirement['acquisitionMode']\n importance: KnowledgeRequirement['importance']\n freshness: KnowledgeRequirement['freshness']\n sensitivity: KnowledgeRequirement['sensitivity']\n confidenceNeeded: number\n currentConfidence: number\n evidenceCount: number\n evidenceIds?: string[]\n fallbackPolicy: KnowledgeRequirement['fallbackPolicy']\n}\n\n/** @stable */\nexport interface SanitizedKnowledgeReadinessReport {\n taskId: string\n readinessScore: number\n recommendedAction: KnowledgeReadinessReport['recommendedAction']\n severity: KnowledgeReadinessReport['severity']\n reason: string\n blockingMissingRequirements: SanitizedKnowledgeRequirement[]\n nonBlockingGaps: SanitizedKnowledgeRequirement[]\n evidenceCount: number\n evidenceIds?: string[]\n missingRequirementIds: string[]\n}\n\n/** @stable */\nexport function sanitizeKnowledgeReadinessReport(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions = {},\n): SanitizedKnowledgeReadinessReport {\n return {\n taskId: report.taskId,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n reason: report.reason,\n blockingMissingRequirements: report.blockingMissingRequirements.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n nonBlockingGaps: report.nonBlockingGaps.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n evidenceCount: report.bundle.evidenceIds.length,\n evidenceIds: options.includeEvidenceIds ? report.bundle.evidenceIds : undefined,\n missingRequirementIds: report.bundle.missing.map((requirement) => requirement.id),\n }\n}\n\n/** @stable */\nexport function sanitizeAgentRuntimeEvent<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions = {},\n): Record<string, unknown> {\n const base = { type: event.type, task: sanitizeTask(event.task, options) }\n if (\n event.type === 'readiness_start' ||\n event.type === 'task_start' ||\n event.type === 'control_start'\n ) {\n return event.type === 'control_start'\n ? { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) }\n : base\n }\n if (event.type === 'readiness_end') {\n return { ...base, knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options) }\n }\n if (event.type === 'questions_start') {\n return {\n ...base,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n }\n }\n if (event.type === 'questions_end') {\n return {\n ...base,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers),\n }\n }\n if (event.type === 'acquisition_start') {\n return { ...base, acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan) }\n }\n if (event.type === 'acquisition_end') {\n return {\n ...base,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n acquiredEvidenceCount: event.acquiredEvidenceIds.length,\n acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : undefined,\n }\n }\n if (event.type === 'control_step') {\n return { ...base, step: sanitizeControlStep(event.step, options) }\n }\n if (event.type === 'control_end') {\n return { ...base, control: sanitizeControlRun(event.control, options) }\n }\n return { ...base, status: event.status, reason: event.reason }\n}\n\n/** @stable */\nexport function sanitizeRuntimeStreamEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions = {},\n): Record<string, unknown> {\n const withTask = 'task' in event && event.task ? { task: sanitizeTask(event.task, options) } : {}\n const withSession =\n 'session' in event && event.session\n ? { session: sanitizeRuntimeSession(event.session, options) }\n : {}\n\n if (event.type === 'readiness_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n decision: event.decision,\n knowledge: sanitizeKnowledgeReadinessReport(event.knowledge, options),\n }\n }\n if (event.type === 'questions_start') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n }\n }\n if (event.type === 'questions_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n questions: event.questions.map((question) => sanitizeQuestion(question, options)),\n userAnswers: options.includeUserAnswers ? event.userAnswers : redactRecord(event.userAnswers),\n }\n }\n if (event.type === 'acquisition_start') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n }\n }\n if (event.type === 'acquisition_end') {\n return {\n type: event.type,\n ...withTask,\n timestamp: event.timestamp,\n acquisitionPlans: event.acquisitionPlans.map(sanitizeAcquisitionPlan),\n acquiredEvidenceCount: event.acquiredEvidenceIds.length,\n acquiredEvidenceIds: options.includeEvidenceIds ? event.acquiredEvidenceIds : undefined,\n }\n }\n if (event.type === 'tool_call') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n args: options.includeControlPayloads ? event.args : undefined,\n }\n }\n if (event.type === 'tool_result') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n result: options.includeControlPayloads ? event.result : undefined,\n }\n }\n if (event.type === 'llm_call') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n model: event.model,\n tokensIn: event.tokensIn,\n tokensOut: event.tokensOut,\n costUsd: event.costUsd,\n latencyMs: event.latencyMs,\n finishReason: event.finishReason,\n }\n }\n if (event.type === 'artifact') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n artifactId: event.artifactId,\n name: event.name,\n mimeType: event.mimeType,\n uri: options.includeEvidenceIds ? event.uri : undefined,\n content: options.includeControlPayloads ? event.content : undefined,\n metadata: options.includeMetadata ? event.metadata : undefined,\n }\n }\n if (event.type === 'proposal_created') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n proposalId: event.proposalId,\n title: options.includeControlPayloads ? event.title : undefined,\n status: event.status,\n }\n }\n if (event.type === 'final') {\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: event.timestamp,\n status: event.status,\n reason: event.reason,\n text: options.includeControlPayloads ? event.text : undefined,\n metadata: options.includeMetadata ? event.metadata : undefined,\n }\n }\n return {\n type: event.type,\n ...withTask,\n ...withSession,\n timestamp: 'timestamp' in event ? event.timestamp : undefined,\n ...pickPublicStreamFields(event),\n }\n}\n\nfunction sanitizeTask(\n task: AgentTaskSpec,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: task.id,\n intent: task.intent,\n domain: task.domain,\n inputs: options.includeInputs ? task.inputs : task.inputs ? '[redacted]' : undefined,\n requiredKnowledge: task.requiredKnowledge?.map((requirement) =>\n sanitizeKnowledgeRequirement(requirement, options),\n ),\n metadata: options.includeMetadata ? task.metadata : task.metadata ? '[redacted]' : undefined,\n }\n}\n\nfunction sanitizeRuntimeSession(\n session: RuntimeSession,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: session.id,\n backend: session.backend,\n status: session.status,\n hasResumeToken: Boolean(session.resumeToken),\n createdAt: session.createdAt,\n updatedAt: session.updatedAt,\n metadata: options.includeMetadata\n ? session.metadata\n : session.metadata\n ? '[redacted]'\n : undefined,\n }\n}\n\nfunction sanitizeKnowledgeRequirement(\n requirement: KnowledgeRequirement,\n options: RuntimeTelemetryOptions,\n): SanitizedKnowledgeRequirement {\n const includeDescription =\n options.includeRequirementDescriptions && requirement.sensitivity !== 'secret'\n return {\n id: requirement.id,\n description: includeDescription ? requirement.description : undefined,\n requiredFor: requirement.requiredFor,\n category: requirement.category,\n acquisitionMode: requirement.acquisitionMode,\n importance: requirement.importance,\n freshness: requirement.freshness,\n sensitivity: requirement.sensitivity,\n confidenceNeeded: requirement.confidenceNeeded,\n currentConfidence: requirement.currentConfidence,\n evidenceCount: requirement.evidenceIds.length,\n evidenceIds: options.includeEvidenceIds ? requirement.evidenceIds : undefined,\n fallbackPolicy: requirement.fallbackPolicy,\n }\n}\n\nfunction sanitizeQuestion(\n question: UserQuestion,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n id: question.id,\n question:\n options.includeRequirementDescriptions && question.answerType !== 'credential'\n ? question.question\n : undefined,\n reason: options.includeRequirementDescriptions ? question.reason : undefined,\n requirementId: question.requirementId,\n importance: question.importance,\n answerType: question.answerType,\n impactIfUnknown: options.includeRequirementDescriptions ? question.impactIfUnknown : undefined,\n optionCount: question.options?.length ?? 0,\n }\n}\n\nfunction sanitizeAcquisitionPlan(plan: DataAcquisitionPlan): Record<string, unknown> {\n return {\n id: plan.id,\n requirementIds: plan.requirementIds,\n mode: plan.mode,\n priority: plan.priority,\n expectedEvidenceCount: plan.expectedEvidenceIds?.length ?? 0,\n questionCount: plan.questions?.length ?? 0,\n }\n}\n\nfunction sanitizeControlStep<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n step: ControlStep<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n const actionOutcome = step.actionOutcome\n return {\n index: step.index,\n decisionType: step.decision.type,\n reason: step.decision.reason,\n action:\n options.includeControlPayloads && step.decision.type === 'continue'\n ? step.decision.action\n : undefined,\n result: options.includeControlPayloads && actionOutcome?.ok ? actionOutcome.result : undefined,\n actionOk: actionOutcome?.ok,\n actionError: actionOutcome?.ok === false ? actionOutcome.error : undefined,\n durationMs: actionOutcome?.durationMs,\n evalsBefore: summarizeEvals(step.evalsBefore, options),\n evalsAfter: summarizeEvals(step.evalsAfter, options),\n startedAt: step.startedAt,\n endedAt: step.endedAt,\n }\n}\n\nfunction sanitizeControlRun<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n control: ControlRunResult<TState, TAction, TActionResult, TEval>,\n options: RuntimeTelemetryOptions,\n): Record<string, unknown> {\n return {\n pass: control.pass,\n completed: control.completed,\n reason: control.reason,\n score: control.score,\n stepCount: control.steps.length,\n wallMs: control.wallMs,\n spentCostUsd: control.spentCostUsd,\n failureClass: control.failureClass,\n stoppedBy: control.stoppedBy,\n runId: control.runId,\n runtimeErrorCount: control.runtimeErrors.length,\n finalEvals: summarizeEvals(control.finalEvals, options),\n }\n}\n\nfunction summarizeEvals(\n evals: ControlEvalResult[],\n options: RuntimeTelemetryOptions,\n): Array<Record<string, unknown>> {\n return evals.map((evalResult) => ({\n id: evalResult.id,\n passed: evalResult.passed,\n score: evalResult.score,\n severity: evalResult.severity,\n objective: evalResult.objective,\n detail: options.includeEvalDetails ? evalResult.detail : undefined,\n evidence: options.includeEvalDetails ? evalResult.evidence : undefined,\n }))\n}\n\nfunction redactRecord(record: Record<string, string>): Record<string, string> {\n return Object.fromEntries(Object.keys(record).map((key) => [key, '[redacted]']))\n}\n\nfunction pickPublicStreamFields(event: RuntimeStreamEvent): Record<string, unknown> {\n if (event.type === 'session_created' || event.type === 'session_resumed') return {}\n if (event.type === 'backend_start' || event.type === 'backend_end')\n return { backend: event.backend }\n if (event.type === 'backend_error') {\n return { backend: event.backend, message: event.message, recoverable: event.recoverable }\n }\n if (event.type === 'task_end') return { status: event.status, reason: event.reason }\n if (event.type === 'text_delta' || event.type === 'reasoning_delta') return { text: event.text }\n return {}\n}\n\n/** @stable */\nexport interface RuntimeEventCollector<\n TState = unknown,\n TAction = unknown,\n TActionResult = unknown,\n TEval extends ControlEvalResult = ControlEvalResult,\n> {\n onEvent: (event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>) => void\n events: Array<Record<string, unknown>>\n}\n\n/** @stable */\nexport type RuntimeStreamEventSink = (event: RuntimeStreamEvent) => void\n\n/** @stable */\nexport interface RuntimeStreamEventSummary {\n /** Total count of sanitized events collected. */\n eventCount: number\n /** Count of events per `type`. Useful for log-line summaries. */\n eventCountsByType: Record<string, number>\n /** First session id observed in a `session_created` / `session_resumed` event, if any. */\n firstSessionId?: string\n /** Last `final` event's status, if a final event was observed. */\n finalStatus?: AgentTaskStatus\n /** Last `final` event's reason, if a final event was observed. */\n finalReason?: string\n /** Concatenated `text_delta.text` across the stream, even when payloads are redacted. */\n finalText: string\n}\n\n/** @stable */\nexport interface RuntimeStreamEventCollector {\n onEvent: RuntimeStreamEventSink\n events: Array<Record<string, unknown>>\n /** Snapshot of a small streaming-flavored summary derived from collected events. */\n summary(): RuntimeStreamEventSummary\n}\n\n/** @stable */\nexport function createRuntimeEventCollector<\n TState = unknown,\n TAction = unknown,\n TActionResult = unknown,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RuntimeTelemetryOptions = {},\n): RuntimeEventCollector<TState, TAction, TActionResult, TEval> {\n const events: Array<Record<string, unknown>> = []\n return {\n events,\n onEvent: (event) => {\n events.push(sanitizeAgentRuntimeEvent(event, options))\n },\n }\n}\n\n/**\n * @stable\n *\n * Streaming-event counterpart of `createRuntimeEventCollector`. Pass each\n * event yielded by `runAgentTaskStream` through `onEvent` and read the\n * sanitized copies off `events`; the same `RuntimeTelemetryOptions` redaction\n * flags apply. Kept distinct from `createRuntimeEventCollector` because the\n * stream and non-stream event shapes overlap on `type` literals — dispatching\n * on `type` alone would misroute events.\n */\nexport function createRuntimeStreamEventCollector(\n options: RuntimeTelemetryOptions = {},\n): RuntimeStreamEventCollector {\n const events: Array<Record<string, unknown>> = []\n const eventCountsByType: Record<string, number> = {}\n let firstSessionId: string | undefined\n let finalStatus: AgentTaskStatus | undefined\n let finalReason: string | undefined\n let finalText = ''\n return {\n events,\n onEvent: (event) => {\n events.push(sanitizeRuntimeStreamEvent(event, options))\n eventCountsByType[event.type] = (eventCountsByType[event.type] ?? 0) + 1\n if (event.type === 'text_delta') finalText += event.text\n if (\n !firstSessionId &&\n (event.type === 'session_created' || event.type === 'session_resumed')\n ) {\n firstSessionId = event.session.id\n }\n if (event.type === 'final') {\n finalStatus = event.status\n finalReason = event.reason\n }\n },\n summary() {\n return {\n eventCount: events.length,\n eventCountsByType: { ...eventCountsByType },\n firstSessionId,\n finalStatus,\n finalReason,\n finalText,\n }\n },\n }\n}\n","/**\n * @stable\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\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/** @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/** @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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","names":["AgentEvalError","emit"]}