@tangle-network/agent-runtime 0.13.0 → 0.14.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.d.ts +239 -1
- package/dist/index.js +298 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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/identity.ts","../src/durable/types.ts","../src/durable/d1-store.ts","../src/durable/file-system-store.ts","../src/durable/in-memory-store.ts","../src/durable/runner.ts","../src/durable/workflows.ts","../src/intent-router.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\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\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 }\n return {\n kind,\n start(_input, context) {\n return newRuntimeSession(kind, context.requestedSessionId)\n },\n async *stream(input, context) {\n let response: Response | undefined\n let lastStatus = 0\n for (let attempt = 1; attempt <= retryPolicy.maxAttempts; attempt++) {\n response = await fetcher(`${options.baseUrl.replace(/\\/$/, '')}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: 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 signal: context.signal,\n })\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 || !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 === '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/<id>`. */\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 * Identity + canonical-hash helpers for the durable-runs substrate.\n *\n * Two boundary disciplines:\n *\n * 1. **Manifest hash** — sha256 over a sorted-key JSON of (projectId,\n * scenarioId, task.id, task.intent, task.domain, input). Same hash =\n * same run identity. Used to detect \"same runId, different inputs.\"\n *\n * 2. **Step input hash** — sha256 over a sorted-key JSON of the step's\n * input fingerprint. Used to detect drift across replays.\n *\n * Sorted-key JSON makes hashes deterministic regardless of object insertion\n * order. NaN / Infinity / undefined / functions / symbols / class instances\n * are rejected — pure JSON only at the boundary, so the hash matches whatever\n * the store round-trips.\n */\n\nimport { createHash } from 'node:crypto'\n\nimport type { DurableRunManifest } from './types'\n\n/** sha256-hex over a JSON-canonicalized value. */\nexport function canonicalHash(value: unknown): string {\n const json = canonicalJson(value)\n return createHash('sha256').update(json).digest('hex')\n}\n\n/** Canonical JSON: object keys sorted lexicographically; arrays preserved. */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(canonicalize(value))\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null) return null\n if (Array.isArray(value)) return value.map(canonicalize)\n const t = typeof value\n if (t === 'string' || t === 'boolean') return value\n if (t === 'number') {\n if (!Number.isFinite(value as number)) {\n throw new TypeError(`canonicalJson: non-finite number ${String(value)} not serializable`)\n }\n return value\n }\n if (t === 'undefined' || t === 'function' || t === 'symbol') {\n throw new TypeError(`canonicalJson: ${t} is not JSON-serializable`)\n }\n if (t === 'bigint') {\n // BigInts have no JSON representation. Encode as string; tag for\n // disambiguation so consumers can choose to reject or decode.\n return { __bigint: String(value) }\n }\n if (t === 'object') {\n const obj = value as Record<string, unknown>\n // Reject class instances — Date / Error / Map / Set / TypedArray — to\n // force callers to project to plain JSON at the boundary. Errors round-\n // tripped silently are the #1 source of \"looks the same but differs\"\n // bugs.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype) {\n const ctor = obj.constructor?.name ?? 'unknown'\n throw new TypeError(\n `canonicalJson: class instance (${ctor}) is not JSON-serializable. Project to plain { ... } at the boundary.`,\n )\n }\n const keys = Object.keys(obj).sort()\n const out: Record<string, unknown> = {}\n for (const k of keys) out[k] = canonicalize(obj[k])\n return out\n }\n throw new TypeError(`canonicalJson: unsupported type ${t}`)\n}\n\n/** Hash a DurableRunManifest into the run identity component. */\nexport function manifestHash(manifest: DurableRunManifest): string {\n return canonicalHash({\n projectId: manifest.projectId,\n scenarioId: manifest.scenarioId ?? null,\n taskId: manifest.task.id,\n taskIntent: manifest.task.intent,\n taskDomain: manifest.task.domain,\n input: manifest.input,\n })\n}\n\n/** Stable per-step identifier — hash of (runId, position, intent). */\nexport function stepId(runId: string, stepIndex: number, intent: string): string {\n return canonicalHash({ runId, stepIndex, intent })\n}\n\nlet counter = 0\n/**\n * Stable worker id for a single process. Format: `host:pid:rand`. Random\n * suffix prevents collisions when the host/pid pair is short-lived (e.g.,\n * Cloudflare isolates that recycle fast).\n */\nexport function deriveWorkerId(): string {\n const host = process.env.HOSTNAME ?? 'host'\n const pid = process.pid ?? 0\n const rand = Math.random().toString(36).slice(2, 10)\n counter += 1\n return `${host}:${pid}:${rand}:${counter}`\n}\n","/**\n * Durable-run substrate: the typed contract for checkpointed agent runs that\n * survive worker crashes, deploy rolls, OOM, and transient transport errors.\n *\n * The model — directly inspired by Absurd (Postgres-backed) and Cloudflare\n * Workflows — splits a run into ordered, idempotent **steps**. Each step's\n * result is persisted before the next step runs. On resume, the runner reads\n * the prior steps from a `DurableRunStore` and fast-replays them (returning\n * cached values) until it reaches the first unfinished step, where execution\n * actually resumes.\n *\n * Three boundary disciplines:\n *\n * 1. Step results MUST be JSON-serializable. No closures, no class\n * instances, no live streams. The store treats results as opaque JSON.\n *\n * 2. Step intents MUST be stable across replays. The runner derives a\n * stable step id from (runId, stepIndex, intent). Mismatched intent at\n * the same index = `DurableRunDivergenceError`.\n *\n * 3. Non-determinism (now / uuid / random) MUST flow through the\n * `DurableContext` helpers — `ctx.now()`, `ctx.uuid()` — so the values\n * are checkpointed and identical on replay. Bare `Date.now()` /\n * `crypto.randomUUID()` inside a task fn breaks replay equality.\n */\n\nimport type { AgentTaskSpec } from '../types'\n\n/** Caller-facing kinds. The runner uses these for telemetry + querying. */\nexport type StepKind =\n /** Logical step that ran user code (the default for ctx.step). */\n | 'logic'\n /** A wrapped LLM call. */\n | 'llm'\n /** A wrapped tool call. */\n | 'tool'\n /** A wrapped readiness probe. */\n | 'readiness'\n /** A deterministic clock or uuid read. */\n | 'deterministic'\n /** A suspend-for-event boundary. */\n | 'event'\n\nexport type StepStatus = 'pending' | 'running' | 'completed' | 'failed'\n\nexport interface StepError {\n message: string\n code?: string\n /** Optional stack — stored for diagnostics, NEVER replayed as an exception. */\n stack?: string\n}\n\nexport interface StepRecord<T = unknown> {\n runId: string\n /** Monotonic 0-based index. Position is the load-bearing identifier — the\n * same intent string at different positions is a different step. */\n stepIndex: number\n /** Caller-supplied label; intended for human reading + log correlation. */\n intent: string\n kind: StepKind\n /** sha256 of the canonical input fingerprint at begin-time. Used to detect\n * divergence (caller changed inputs across replays). Empty for steps where\n * the input cannot be canonicalized (e.g. ctx.now()). */\n inputHash: string\n status: StepStatus\n /** Re-entry count. Increments each time the step begins. */\n attempts: number\n /** JSON-serializable result. Present when status === 'completed'. */\n result?: T\n error?: StepError\n startedAt?: string\n completedAt?: string\n}\n\nexport interface EventRecord {\n runId: string\n key: string\n payload: unknown\n emittedAt: string\n}\n\nexport type RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'suspended'\n\nexport interface RunOutcome {\n pass?: boolean\n score?: number\n notes?: string\n /** Free-form bag of run-level metrics — surfaced in OTLP / TraceStore. */\n metadata?: Record<string, unknown>\n}\n\nexport interface DurableRunManifest {\n /** Stable per-product id (e.g. 'legal-agent', 'creative-agent'). */\n projectId: string\n /** Optional scenario / persona / session id — surfaced in telemetry. */\n scenarioId?: string\n task: AgentTaskSpec\n /** Input payload. Hashed into the run identity so two runs with the same\n * runId but different inputs raise DurableRunInputMismatchError. */\n input: Record<string, unknown>\n /** Free-form tags surfaced into RunRecord / OTLP. */\n tags?: Record<string, string>\n}\n\nexport interface RunRecord {\n runId: string\n manifestHash: string\n projectId: string\n scenarioId?: string\n status: RunStatus\n createdAt: string\n updatedAt: string\n completedAt?: string\n /** Stable per-worker id holding the lease. */\n leaseHolderId?: string\n leaseExpiresAt?: string\n outcome?: RunOutcome\n stepCount: number\n}\n\n/**\n * The durable-run substrate. Implementations: in-memory (dev), file-system\n * (eval harness), D1 (Cloudflare prod). All stores share this exact contract\n * — swap by changing one factory call.\n *\n * Concurrency model: at most one worker holds a run's lease at a time. Lease\n * renewal happens on a heartbeat; on lease expiry, another worker can\n * `startOrResume` and pick up. Steps committed by the prior worker survive.\n */\nexport interface DurableRunStore {\n /**\n * Begin or resume a run. Returns the canonical RunRecord, all previously\n * completed steps (in order), and the lease deadline.\n *\n * If the run did not exist, creates it with status='running'. If it existed\n * with a different manifest hash, throws DurableRunInputMismatchError.\n * If it existed with a live lease held by a different worker, throws\n * DurableRunLeaseHeldError (caller can retry or back off).\n */\n startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): Promise<{\n run: RunRecord\n completedSteps: ReadonlyArray<StepRecord>\n leaseExpiresAt: string\n }>\n\n /** Renew the lease. Returns false if another worker now holds it. */\n renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }>\n\n /** Load a step by position. Returns undefined if not yet begun. */\n loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined>\n\n /** Record step start (intent + input hash + kind). Bumps attempt count. */\n beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord>\n\n /** Mark step completed with a JSON-serializable result. */\n completeStep(input: { runId: string; stepIndex: number; result: unknown }): Promise<StepRecord>\n\n /** Mark step failed with a captured error. */\n failStep(input: { runId: string; stepIndex: number; error: StepError }): Promise<StepRecord>\n\n /** End the run; releases lease. */\n endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord>\n\n /**\n * Emit an event. First emit wins; subsequent emits return the existing\n * record under `existing` and accepted=false. Caller can treat that as\n * idempotency-by-design — never double-fire a downstream side effect.\n */\n emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): Promise<{ accepted: boolean; record: EventRecord }>\n\n /** Load the cached event payload if it has been emitted. */\n loadEvent(runId: string, key: string): Promise<EventRecord | undefined>\n\n /** Cleanup hook for in-memory / fs stores; no-op for D1. Idempotent. */\n close(): Promise<void>\n}\n\n// ── Public error contract ────────────────────────────────────────────────\n\n/** Base class for durable-run errors. */\nexport class DurableRunError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'lease_held'\n | 'manifest_mismatch'\n | 'step_divergence'\n | 'step_input_mismatch'\n | 'await_event_timeout'\n | 'event_emit_race',\n ) {\n super(message)\n this.name = this.constructor.name\n }\n}\n\n/** Thrown when another worker holds the lease for this runId. */\nexport class DurableRunLeaseHeldError extends DurableRunError {\n constructor(message: string) {\n super(message, 'lease_held')\n }\n}\n\n/** Thrown when the manifest hash differs from a prior run with the same id. */\nexport class DurableRunInputMismatchError extends DurableRunError {\n constructor(message: string) {\n super(message, 'manifest_mismatch')\n }\n}\n\n/** Thrown when the same stepIndex re-runs with a different intent string. */\nexport class DurableRunDivergenceError extends DurableRunError {\n constructor(message: string) {\n super(message, 'step_divergence')\n }\n}\n\n/** Thrown when `awaitEvent` times out. */\nexport class DurableAwaitEventTimeoutError extends DurableRunError {\n constructor(message: string) {\n super(message, 'await_event_timeout')\n }\n}\n","/**\n * D1DurableRunStore — the production path for Cloudflare Workers. Backed by\n * a D1 (SQLite-compatible) database via the binding the worker already holds.\n *\n * Apply `./schema.sql` once before use; the store itself does not run DDL.\n * Migration version is recorded in `durable_schema_info`; consumers can\n * inspect `getSchemaVersion()` if they ship a migration tool.\n *\n * Why structural typing: agent-runtime stays Cloudflare-free at the dep\n * level. Consumers pass their `D1Database` binding — TypeScript matches the\n * minimal `D1DatabaseLike` surface below. Tests use the same interface with\n * a fake.\n */\n\nimport { manifestHash } from './identity'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n type DurableRunManifest,\n type DurableRunStore,\n type EventRecord,\n type RunOutcome,\n type RunRecord,\n type StepError,\n type StepKind,\n type StepRecord,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\n/**\n * Minimal D1 surface this store uses. Compatible with Cloudflare's\n * `D1Database` from `@cloudflare/workers-types`. Defined locally so\n * agent-runtime does not depend on workers-types at the package level.\n */\nexport interface D1DatabaseLike {\n prepare(query: string): D1PreparedStatementLike\n batch(statements: D1PreparedStatementLike[]): Promise<unknown[]>\n}\n\nexport interface D1PreparedStatementLike {\n bind(...values: unknown[]): D1PreparedStatementLike\n first<T = unknown>(): Promise<T | null>\n all<T = unknown>(): Promise<{ results: T[] }>\n run(): Promise<{ success: boolean; meta?: { changes?: number } }>\n}\n\ninterface RunRow {\n run_id: string\n manifest_hash: string\n project_id: string\n scenario_id: string | null\n status: RunRecord['status']\n created_at: string\n updated_at: string\n completed_at: string | null\n lease_holder_id: string | null\n lease_expires_at: string | null\n outcome_json: string | null\n step_count: number\n}\n\ninterface StepRow {\n run_id: string\n step_index: number\n intent: string\n kind: string\n input_hash: string\n status: StepRecord['status']\n attempts: number\n result_json: string | null\n error_json: string | null\n started_at: string | null\n completed_at: string | null\n}\n\ninterface EventRow {\n run_id: string\n key: string\n payload_json: string | null\n emitted_at: string\n}\n\nexport class D1DurableRunStore implements DurableRunStore {\n constructor(private readonly db: D1DatabaseLike) {}\n\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + leaseMs).toISOString()\n\n const existing = await this.db\n .prepare('SELECT * FROM durable_runs WHERE run_id = ?')\n .bind(input.runId)\n .first<RunRow>()\n\n if (!existing) {\n await this.db\n .prepare(\n `INSERT INTO durable_runs\n (run_id, manifest_hash, project_id, scenario_id, status,\n created_at, updated_at, lease_holder_id, lease_expires_at, step_count)\n VALUES (?, ?, ?, ?, 'running', ?, ?, ?, ?, 0)`,\n )\n .bind(\n input.runId,\n hash,\n input.manifest.projectId,\n input.manifest.scenarioId ?? null,\n nowIso,\n nowIso,\n input.workerId,\n leaseExpiresAt,\n )\n .run()\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n return { run: record, completedSteps: [], leaseExpiresAt }\n }\n\n if (existing.manifest_hash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n // Lease takeover — conditional UPDATE.\n const claim = await this.db\n .prepare(\n `UPDATE durable_runs\n SET lease_holder_id = ?,\n lease_expires_at = ?,\n updated_at = ?,\n status = CASE WHEN status IN ('completed','failed') THEN status ELSE 'running' END\n WHERE run_id = ?\n AND (\n lease_holder_id = ? OR\n lease_holder_id IS NULL OR\n lease_expires_at IS NULL OR\n lease_expires_at < ?\n )`,\n )\n .bind(input.workerId, leaseExpiresAt, nowIso, input.runId, input.workerId, nowIso)\n .run()\n const changes = claim.meta?.changes ?? 0\n if (changes === 0) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} leased by ${existing.lease_holder_id} until ${existing.lease_expires_at}`,\n )\n }\n const completedSteps = await this.readSteps(input.runId, 'completed')\n const record: RunRecord = rowToRunRecord({\n ...existing,\n lease_holder_id: input.workerId,\n lease_expires_at: leaseExpiresAt,\n updated_at: nowIso,\n status:\n existing.status === 'completed' || existing.status === 'failed'\n ? existing.status\n : 'running',\n })\n return { run: record, completedSteps, leaseExpiresAt }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)).toISOString()\n const res = await this.db\n .prepare(\n `UPDATE durable_runs\n SET lease_expires_at = ?, updated_at = ?\n WHERE run_id = ?\n AND (lease_holder_id = ? OR lease_expires_at IS NULL OR lease_expires_at < ?)`,\n )\n .bind(leaseExpiresAt, nowIso, input.runId, input.workerId, nowIso)\n .run()\n const ok = (res.meta?.changes ?? 0) > 0\n return ok ? { ok: true, leaseExpiresAt } : { ok: false }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const row = await this.db\n .prepare('SELECT * FROM durable_steps WHERE run_id = ? AND step_index = ?')\n .bind(runId, stepIndex)\n .first<StepRow>()\n return row ? rowToStepRecord(row) : undefined\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n const prior = await this.loadStep(input.runId, input.stepIndex)\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='running', attempts = attempts + 1, started_at = ?, error_json = NULL\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n return {\n ...prior,\n attempts: prior.attempts + 1,\n status: 'running',\n startedAt: nowIso,\n error: undefined,\n }\n }\n await this.db\n .prepare(\n `INSERT INTO durable_steps\n (run_id, step_index, intent, kind, input_hash, status, attempts, started_at)\n VALUES (?, ?, ?, ?, ?, 'running', 1, ?)`,\n )\n .bind(input.runId, input.stepIndex, input.intent, input.kind, input.inputHash, nowIso)\n .run()\n await this.db\n .prepare(\n `UPDATE durable_runs\n SET step_count = MAX(step_count, ?), updated_at = ?\n WHERE run_id = ?`,\n )\n .bind(input.stepIndex + 1, nowIso, input.runId)\n .run()\n return {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='completed', result_json = ?, completed_at = ?, error_json = NULL\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(JSON.stringify(input.result ?? null), nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n const row = await this.loadStep(input.runId, input.stepIndex)\n if (!row) {\n throw new Error(`durable-runs: completeStep cannot find step ${input.stepIndex}`)\n }\n return row\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='failed', error_json = ?, completed_at = ?\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(JSON.stringify(input.error), nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n const row = await this.loadStep(input.runId, input.stepIndex)\n if (!row) {\n throw new Error(`durable-runs: failStep cannot find step ${input.stepIndex}`)\n }\n return row\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_runs\n SET status = ?, completed_at = ?, updated_at = ?,\n outcome_json = ?,\n lease_holder_id = CASE WHEN lease_holder_id = ? THEN NULL ELSE lease_holder_id END,\n lease_expires_at = CASE WHEN lease_holder_id = ? THEN NULL ELSE lease_expires_at END\n WHERE run_id = ?`,\n )\n .bind(\n input.status,\n nowIso,\n nowIso,\n input.outcome ? JSON.stringify(input.outcome) : null,\n input.workerId,\n input.workerId,\n input.runId,\n )\n .run()\n const row = await this.db\n .prepare('SELECT * FROM durable_runs WHERE run_id = ?')\n .bind(input.runId)\n .first<RunRow>()\n if (!row) throw new Error(`durable-runs: endRun cannot find run ${input.runId}`)\n return rowToRunRecord(row)\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const nowIso = new Date(this.now()).toISOString()\n // INSERT OR IGNORE — first emit wins; subsequent inserts no-op.\n const res = await this.db\n .prepare(\n `INSERT OR IGNORE INTO durable_events (run_id, key, payload_json, emitted_at)\n VALUES (?, ?, ?, ?)`,\n )\n .bind(input.runId, input.key, JSON.stringify(input.payload ?? null), nowIso)\n .run()\n const accepted = (res.meta?.changes ?? 0) > 0\n const row = await this.db\n .prepare('SELECT * FROM durable_events WHERE run_id = ? AND key = ?')\n .bind(input.runId, input.key)\n .first<EventRow>()\n if (!row) throw new Error('durable-runs: emitEvent failed to persist or read back')\n return {\n accepted,\n record: rowToEventRecord(row),\n }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const row = await this.db\n .prepare('SELECT * FROM durable_events WHERE run_id = ? AND key = ?')\n .bind(runId, key)\n .first<EventRow>()\n return row ? rowToEventRecord(row) : undefined\n }\n\n async close(): Promise<void> {\n // D1 binding lifecycle is owned by the runtime; no-op.\n }\n\n /** Inspect the currently-applied schema version. */\n async getSchemaVersion(): Promise<number | undefined> {\n const row = await this.db\n .prepare('SELECT MAX(version) AS version FROM durable_schema_info')\n .first<{ version: number | null }>()\n return row?.version ?? undefined\n }\n\n // ── internals ──────────────────────────────────────────────────────\n\n private async readSteps(\n runId: string,\n status: StepRecord['status'],\n ): Promise<ReadonlyArray<StepRecord>> {\n const { results } = await this.db\n .prepare('SELECT * FROM durable_steps WHERE run_id = ? AND status = ? ORDER BY step_index')\n .bind(runId, status)\n .all<StepRow>()\n return results.map(rowToStepRecord)\n }\n\n private async bumpUpdated(runId: string, nowIso: string): Promise<void> {\n await this.db\n .prepare('UPDATE durable_runs SET updated_at = ? WHERE run_id = ?')\n .bind(nowIso, runId)\n .run()\n }\n}\n\n// ── row → record helpers ───────────────────────────────────────────────\n\nfunction rowToRunRecord(row: RunRow): RunRecord {\n return {\n runId: row.run_id,\n manifestHash: row.manifest_hash,\n projectId: row.project_id,\n scenarioId: row.scenario_id ?? undefined,\n status: row.status,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n completedAt: row.completed_at ?? undefined,\n leaseHolderId: row.lease_holder_id ?? undefined,\n leaseExpiresAt: row.lease_expires_at ?? undefined,\n outcome: row.outcome_json ? (JSON.parse(row.outcome_json) as RunOutcome) : undefined,\n stepCount: row.step_count,\n }\n}\n\nfunction rowToStepRecord(row: StepRow): StepRecord {\n return {\n runId: row.run_id,\n stepIndex: row.step_index,\n intent: row.intent,\n kind: row.kind as StepKind,\n inputHash: row.input_hash,\n status: row.status,\n attempts: row.attempts,\n result: row.result_json ? JSON.parse(row.result_json) : undefined,\n error: row.error_json ? (JSON.parse(row.error_json) as StepError) : undefined,\n startedAt: row.started_at ?? undefined,\n completedAt: row.completed_at ?? undefined,\n }\n}\n\nfunction rowToEventRecord(row: EventRow): EventRecord {\n return {\n runId: row.run_id,\n key: row.key,\n payload: row.payload_json ? JSON.parse(row.payload_json) : null,\n emittedAt: row.emitted_at,\n }\n}\n","/**\n * FileSystemDurableRunStore — durable-run substrate backed by a directory\n * tree under a single root. One subdir per run:\n *\n * <root>/<runId>/\n * run.json — RunRecord (rewritten on every mutation; the only\n * scalar fields are status/lease, so this stays small)\n * steps.jsonl — append-only StepRecord stream; one JSON per line\n * events.jsonl — append-only EventRecord stream\n * lease.json — current leaseholder + deadline (separate from\n * run.json so renewLease writes one tiny file\n * instead of round-tripping the whole run record)\n *\n * Concurrency: the eval harness is single-process — we rely on Node's\n * append-mode semantics for atomicity of step / event writes (single-line\n * writes < PIPE_BUF are atomic on POSIX). For run.json / lease.json we write\n * to a `<file>.tmp` then `rename` to make replacement atomic. This is\n * sufficient for the single-process eval harness use case. Multi-process\n * concurrency on the SAME filesystem requires a flock-based extension;\n * for that path use D1DurableRunStore.\n */\n\nimport { existsSync, mkdirSync } from 'node:fs'\nimport { appendFile, readdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nimport { manifestHash } from './identity'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n type DurableRunManifest,\n type DurableRunStore,\n type EventRecord,\n type RunOutcome,\n type RunRecord,\n type StepError,\n type StepKind,\n type StepRecord,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\ninterface LeaseFile {\n workerId: string\n leaseExpiresAt: string\n}\n\nexport class FileSystemDurableRunStore implements DurableRunStore {\n constructor(private readonly root: string) {\n mkdirSync(root, { recursive: true })\n }\n\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + leaseMs).toISOString()\n const dir = this.runDir(input.runId)\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n await this.writeRun(record)\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n // Touch the jsonl files so listing them later doesn't ENOENT.\n await appendFile(join(dir, 'steps.jsonl'), '', 'utf8')\n await appendFile(join(dir, 'events.jsonl'), '', 'utf8')\n return { run: record, completedSteps: [], leaseExpiresAt }\n }\n\n const record = await this.readRun(input.runId)\n if (record.manifestHash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n const lease = await this.readLeaseSafe(input.runId)\n const leaseStillLive =\n lease && lease.workerId !== input.workerId && new Date(lease.leaseExpiresAt).getTime() > nowMs\n if (leaseStillLive) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} leased by ${lease.workerId} until ${lease.leaseExpiresAt}`,\n )\n }\n const completedSteps = await this.readSteps(input.runId)\n const nextRecord: RunRecord = {\n ...record,\n status:\n record.status === 'completed' || record.status === 'failed' ? record.status : 'running',\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n }\n await this.writeRun(nextRecord)\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n return { run: nextRecord, completedSteps, leaseExpiresAt }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const lease = await this.readLeaseSafe(input.runId)\n const nowMs = this.now()\n if (lease && lease.workerId !== input.workerId) {\n if (new Date(lease.leaseExpiresAt).getTime() > nowMs) {\n return { ok: false }\n }\n }\n const leaseExpiresAt = new Date(nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)).toISOString()\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n return { ok: true, leaseExpiresAt }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const steps = await this.readSteps(runId, { includeFailed: true, includeRunning: true })\n return steps.find((s) => s.stepIndex === stepIndex)\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n const nowIso = new Date(this.now()).toISOString()\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n const rec: StepRecord = {\n ...prior,\n attempts: prior.attempts + 1,\n status: 'running',\n startedAt: nowIso,\n error: undefined,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n const rec: StepRecord = {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n await this.appendStep(input.runId, rec)\n // Bump run.stepCount opportunistically.\n const record = await this.readRun(input.runId)\n record.stepCount = Math.max(record.stepCount, input.stepIndex + 1)\n record.updatedAt = nowIso\n await this.writeRun(record)\n return rec\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n if (!prior) {\n throw new Error(\n `durable-runs: completeStep called before beginStep (step ${input.stepIndex})`,\n )\n }\n const nowIso = new Date(this.now()).toISOString()\n const rec: StepRecord = {\n ...prior,\n status: 'completed',\n result: input.result,\n completedAt: nowIso,\n error: undefined,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n if (!prior) {\n throw new Error(`durable-runs: failStep called before beginStep (step ${input.stepIndex})`)\n }\n const nowIso = new Date(this.now()).toISOString()\n const rec: StepRecord = {\n ...prior,\n status: 'failed',\n error: input.error,\n completedAt: nowIso,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const record = await this.readRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n record.status = input.status\n record.outcome = input.outcome\n record.completedAt = nowIso\n record.updatedAt = nowIso\n const lease = await this.readLeaseSafe(input.runId)\n if (lease && lease.workerId === input.workerId) {\n record.leaseHolderId = undefined\n record.leaseExpiresAt = undefined\n await this.writeLease(input.runId, null)\n }\n await this.writeRun(record)\n return record\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const existing = await this.loadEvent(input.runId, input.key)\n if (existing) return { accepted: false, record: existing }\n const rec: EventRecord = {\n runId: input.runId,\n key: input.key,\n payload: input.payload,\n emittedAt: new Date(this.now()).toISOString(),\n }\n await appendFile(\n join(this.runDir(input.runId), 'events.jsonl'),\n `${JSON.stringify(rec)}\\n`,\n 'utf8',\n )\n return { accepted: true, record: rec }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const path = join(this.runDir(runId), 'events.jsonl')\n if (!existsSync(path)) return undefined\n const content = await readFile(path, 'utf8')\n for (const line of content.split('\\n').reverse()) {\n if (!line) continue\n const rec = JSON.parse(line) as EventRecord\n if (rec.key === key) return rec\n }\n return undefined\n }\n\n async close(): Promise<void> {\n // No persistent handles to close.\n }\n\n /** @internal — used by tests to list runs in the store. */\n async _listRunIds(): Promise<string[]> {\n if (!existsSync(this.root)) return []\n const entries = await readdir(this.root, { withFileTypes: true })\n return entries.filter((e) => e.isDirectory()).map((e) => e.name)\n }\n\n // ── internals ──────────────────────────────────────────────────────\n\n private runDir(runId: string): string {\n return join(this.root, runId)\n }\n\n private async readRun(runId: string): Promise<RunRecord> {\n const path = join(this.runDir(runId), 'run.json')\n const content = await readFile(path, 'utf8')\n return JSON.parse(content) as RunRecord\n }\n\n private async writeRun(record: RunRecord): Promise<void> {\n const dir = this.runDir(record.runId)\n const path = join(dir, 'run.json')\n const tmp = `${path}.tmp`\n await writeFile(tmp, JSON.stringify(record, null, 2), 'utf8')\n await rename(tmp, path)\n }\n\n private async readLeaseSafe(runId: string): Promise<LeaseFile | undefined> {\n const path = join(this.runDir(runId), 'lease.json')\n if (!existsSync(path)) return undefined\n try {\n const content = await readFile(path, 'utf8')\n if (!content.trim()) return undefined\n return JSON.parse(content) as LeaseFile\n } catch {\n return undefined\n }\n }\n\n private async writeLease(runId: string, lease: LeaseFile | null): Promise<void> {\n const path = join(this.runDir(runId), 'lease.json')\n const tmp = `${path}.tmp`\n await writeFile(tmp, lease ? JSON.stringify(lease) : '', 'utf8')\n await rename(tmp, path)\n }\n\n private async readSteps(\n runId: string,\n opts: { includeFailed?: boolean; includeRunning?: boolean } = {},\n ): Promise<StepRecord[]> {\n const path = join(this.runDir(runId), 'steps.jsonl')\n if (!existsSync(path)) return []\n const content = await readFile(path, 'utf8')\n // Append-only log: later writes for the same stepIndex override earlier\n // ones. Walk forward and keep the latest per index.\n const latest = new Map<number, StepRecord>()\n for (const line of content.split('\\n')) {\n if (!line) continue\n const rec = JSON.parse(line) as StepRecord\n latest.set(rec.stepIndex, rec)\n }\n const out = [...latest.values()].sort((a, b) => a.stepIndex - b.stepIndex)\n return out.filter((s) => {\n if (s.status === 'completed') return true\n if (s.status === 'failed') return opts.includeFailed ?? false\n if (s.status === 'running') return opts.includeRunning ?? false\n return false\n })\n }\n\n private async appendStep(runId: string, rec: StepRecord): Promise<void> {\n await appendFile(join(this.runDir(runId), 'steps.jsonl'), `${JSON.stringify(rec)}\\n`, 'utf8')\n }\n\n private async bumpRunUpdated(runId: string, nowIso: string): Promise<void> {\n const record = await this.readRun(runId)\n record.updatedAt = nowIso\n await this.writeRun(record)\n }\n}\n","/**\n * In-memory DurableRunStore for dev + tests. Single-process. All state lives\n * in maps. Lease enforcement is real (Date.now() vs lease deadline) so the\n * crash-recovery + multi-worker race tests run identically against this and\n * the file-system / D1 stores.\n */\n\nimport { manifestHash } from './identity'\nimport type {\n DurableRunManifest,\n DurableRunStore,\n EventRecord,\n RunOutcome,\n RunRecord,\n StepError,\n StepKind,\n StepRecord,\n} from './types'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\ninterface RunState {\n record: RunRecord\n steps: Map<number, StepRecord>\n events: Map<string, EventRecord>\n}\n\nexport class InMemoryDurableRunStore implements DurableRunStore {\n private readonly runs = new Map<string, RunState>()\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresMs = nowMs + leaseMs\n const leaseExpiresAt = new Date(leaseExpiresMs).toISOString()\n\n let state = this.runs.get(input.runId)\n if (!state) {\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n state = { record, steps: new Map(), events: new Map() }\n this.runs.set(input.runId, state)\n return { run: { ...record }, completedSteps: [], leaseExpiresAt }\n }\n\n if (state.record.manifestHash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n // Lease check — held by another worker with a non-expired lease.\n const leaseStillLive =\n state.record.leaseHolderId !== undefined &&\n state.record.leaseHolderId !== input.workerId &&\n state.record.leaseExpiresAt !== undefined &&\n new Date(state.record.leaseExpiresAt).getTime() > nowMs\n if (leaseStillLive) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} is leased by ${state.record.leaseHolderId} until ${state.record.leaseExpiresAt}`,\n )\n }\n // Acquire / renew.\n state.record.leaseHolderId = input.workerId\n state.record.leaseExpiresAt = leaseExpiresAt\n state.record.status =\n state.record.status === 'completed' || state.record.status === 'failed'\n ? state.record.status\n : 'running'\n state.record.updatedAt = nowIso\n const completed = [...state.steps.values()]\n .filter((s) => s.status === 'completed')\n .sort((a, b) => a.stepIndex - b.stepIndex)\n return {\n run: { ...state.record },\n completedSteps: completed.map((s) => ({ ...s })),\n leaseExpiresAt,\n }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const state = this.runs.get(input.runId)\n if (!state) return { ok: false }\n const nowMs = this.now()\n if (state.record.leaseHolderId !== input.workerId) {\n // Lease lapsed — another worker may have taken over.\n if (state.record.leaseExpiresAt && new Date(state.record.leaseExpiresAt).getTime() > nowMs) {\n return { ok: false }\n }\n }\n const leaseExpiresMs = nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)\n const leaseExpiresAt = new Date(leaseExpiresMs).toISOString()\n state.record.leaseHolderId = input.workerId\n state.record.leaseExpiresAt = leaseExpiresAt\n state.record.updatedAt = new Date(nowMs).toISOString()\n return { ok: true, leaseExpiresAt }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const state = this.runs.get(runId)\n return state ? cloneStep(state.steps.get(stepIndex)) : undefined\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n const prior = state.steps.get(input.stepIndex)\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed across replays ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n // Begin called again — bump attempts. A prior failed or running step\n // can re-execute; a prior completed step would be filtered before begin\n // is called (the runner short-circuits on cached results).\n prior.attempts += 1\n prior.status = 'running'\n prior.startedAt = nowIso\n prior.error = undefined\n state.record.updatedAt = nowIso\n return cloneStep(prior)!\n }\n const rec: StepRecord = {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n state.steps.set(input.stepIndex, rec)\n state.record.stepCount = Math.max(state.record.stepCount, input.stepIndex + 1)\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const rec = state.steps.get(input.stepIndex)\n if (!rec) {\n throw new Error(\n `durable-runs: completeStep called before beginStep (step ${input.stepIndex})`,\n )\n }\n const nowIso = new Date(this.now()).toISOString()\n rec.status = 'completed'\n rec.result = input.result\n rec.completedAt = nowIso\n rec.error = undefined\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const rec = state.steps.get(input.stepIndex)\n if (!rec) {\n throw new Error(`durable-runs: failStep called before beginStep (step ${input.stepIndex})`)\n }\n const nowIso = new Date(this.now()).toISOString()\n rec.status = 'failed'\n rec.error = input.error\n rec.completedAt = nowIso\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const state = this.requireRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n state.record.status = input.status\n state.record.outcome = input.outcome\n state.record.completedAt = nowIso\n state.record.updatedAt = nowIso\n // Release lease iff caller still holds it.\n if (state.record.leaseHolderId === input.workerId) {\n state.record.leaseHolderId = undefined\n state.record.leaseExpiresAt = undefined\n }\n return { ...state.record }\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const state = this.requireRun(input.runId)\n const existing = state.events.get(input.key)\n if (existing) {\n return { accepted: false, record: { ...existing } }\n }\n const rec: EventRecord = {\n runId: input.runId,\n key: input.key,\n payload: input.payload,\n emittedAt: new Date(this.now()).toISOString(),\n }\n state.events.set(input.key, rec)\n return { accepted: true, record: { ...rec } }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const state = this.runs.get(runId)\n if (!state) return undefined\n const rec = state.events.get(key)\n return rec ? { ...rec } : undefined\n }\n\n async close(): Promise<void> {\n this.runs.clear()\n }\n\n // ── test helpers ───────────────────────────────────────────────────\n /** @internal — used by tests to inspect lease metadata. */\n _inspect(runId: string): RunRecord | undefined {\n const s = this.runs.get(runId)\n return s ? { ...s.record } : undefined\n }\n\n /** @internal — used by tests to simulate lease expiry. */\n _expireLease(runId: string): void {\n const s = this.runs.get(runId)\n if (s) {\n s.record.leaseHolderId = undefined\n s.record.leaseExpiresAt = undefined\n }\n }\n\n private requireRun(runId: string): RunState {\n const s = this.runs.get(runId)\n if (!s) {\n throw new Error(`durable-runs: run ${runId} not found (must call startOrResume first)`)\n }\n return s\n }\n}\n\nfunction cloneStep(rec: StepRecord | undefined): StepRecord | undefined {\n if (!rec) return undefined\n return { ...rec, error: rec.error ? { ...rec.error } : undefined }\n}\n","/**\n * Durable runner — wraps a user-supplied async function in checkpoint /\n * resume / lease semantics. The user writes plain async code, awaiting\n * `ctx.step(intent, fn)` boundaries. On worker crash, the next caller with\n * the same `runId` skips completed steps and resumes from the first unfinished\n * one.\n *\n * Invariants:\n *\n * - Step positions are derived from a monotonic counter on the ctx. The\n * same intent at position N is the same step across replays. If the user\n * reorders steps, position N changes intent and we raise\n * DurableRunDivergenceError fail-loud.\n *\n * - `ctx.now()` and `ctx.uuid()` are checkpointed as zero-input logic steps\n * with kind='deterministic'. On replay they return the recorded value.\n *\n * - `awaitEvent` writes a 'event' step that records the event payload on\n * first awaited completion. On replay, the cached payload returns\n * synchronously. If the event has not been emitted and the runner is in\n * a fresh execution, it polls the store until timeout.\n *\n * - Lease renewal happens on a wall-clock interval (every leaseMs/3). If\n * the store reports a lost lease, the runner aborts the current step\n * execution and throws — letting whichever worker holds the lease pick\n * up. Committed steps survive.\n */\n\nimport { canonicalHash, deriveWorkerId, manifestHash } from './identity'\nimport type {\n DurableRunManifest,\n DurableRunStore,\n RunOutcome,\n RunRecord,\n StepKind,\n StepRecord,\n} from './types'\nimport { DurableAwaitEventTimeoutError, DurableRunDivergenceError } from './types'\n\nexport interface DurableContext {\n readonly runId: string\n readonly projectId: string\n readonly scenarioId?: string\n\n /**\n * Execute a checkpointed step. The step is identified by its **position**\n * (monotonic counter on this ctx); `intent` is a human-readable label that\n * must stay stable across replays.\n *\n * On first execution: runs `fn`, records the result, returns it.\n * On replay: returns the recorded result WITHOUT calling `fn`.\n *\n * The `inputFingerprint` (optional) lets the runner detect \"same intent,\n * different inputs\" — it gets hashed and compared. If you don't supply\n * one, drift is allowed (input not checked).\n */\n step<T>(\n intent: string,\n fn: () => Promise<T>,\n opts?: { kind?: StepKind; inputFingerprint?: unknown },\n ): Promise<T>\n\n /** Race-free first-emit-wins event wait. */\n awaitEvent<T = unknown>(key: string, opts?: { timeoutMs?: number; pollMs?: number }): Promise<T>\n\n /** Emit an event. First emit wins. Subsequent emits no-op. */\n emitEvent(key: string, payload: unknown): Promise<{ accepted: boolean }>\n\n /** Deterministic clock — checkpointed once per call. */\n now(): Promise<Date>\n\n /** Deterministic uuid — checkpointed once per call. */\n uuid(): Promise<string>\n}\n\nconst DEFAULT_LEASE_MS = 30_000\nconst DEFAULT_AWAIT_POLL_MS = 250\n\nexport interface RunDurableInput<TResult> {\n runId: string\n manifest: DurableRunManifest\n store: DurableRunStore\n workerId?: string\n leaseMs?: number\n /** Total time budget for the run. Used for awaitEvent timeouts; runner\n * itself doesn't kill long-running steps (the step fn must respect\n * AbortSignal if it cares). */\n signal?: AbortSignal\n taskFn: (ctx: DurableContext) => Promise<TResult>\n /** Default outcome on successful completion. */\n defaultOutcome?: RunOutcome\n}\n\nexport interface RunDurableResult<TResult> {\n result: TResult\n record: RunRecord\n /** All steps captured this run (replayed + freshly executed). */\n steps: ReadonlyArray<StepRecord>\n}\n\nexport async function runDurable<TResult>(\n input: RunDurableInput<TResult>,\n): Promise<RunDurableResult<TResult>> {\n const workerId = input.workerId ?? deriveWorkerId()\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const { completedSteps } = await input.store.startOrResume({\n runId: input.runId,\n manifest: input.manifest,\n workerId,\n leaseMs,\n })\n\n // Pre-compute a position-indexed view of prior steps for O(1) replay\n // lookups. We DON'T trust that the store returned them in order — sort.\n const priorByIndex = new Map<number, StepRecord>()\n for (const s of completedSteps) priorByIndex.set(s.stepIndex, s)\n\n const collected: StepRecord[] = [...completedSteps].sort((a, b) => a.stepIndex - b.stepIndex)\n\n // Lease renewal heartbeat — best-effort. Errors are surfaced via\n // `leaseLost` so steps can short-circuit.\n let leaseLost = false\n const heartbeatIntervalMs = Math.max(1_000, Math.floor(leaseMs / 3))\n const heartbeat = setInterval(() => {\n void input.store\n .renewLease({ runId: input.runId, workerId, leaseMs })\n .then((res) => {\n if (!res.ok) leaseLost = true\n })\n .catch(() => {\n leaseLost = true\n })\n }, heartbeatIntervalMs)\n // unref() so the heartbeat doesn't keep the process alive on test exit.\n if (typeof heartbeat.unref === 'function') heartbeat.unref()\n\n let positionCounter = 0\n\n const ctx: DurableContext = {\n runId: input.runId,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n async step<T>(\n intent: string,\n fn: () => Promise<T>,\n opts?: { kind?: StepKind; inputFingerprint?: unknown },\n ): Promise<T> {\n checkAbortAndLease(input.signal, leaseLost)\n const stepIndex = positionCounter++\n const prior = priorByIndex.get(stepIndex)\n const inputHash =\n opts?.inputFingerprint !== undefined ? canonicalHash(opts.inputFingerprint) : ''\n if (prior && prior.status === 'completed') {\n // Replay path — return cached result.\n if (prior.intent !== intent) {\n throw new DurableRunDivergenceError(\n `step ${stepIndex}: intent changed across replays ('${prior.intent}' -> '${intent}')`,\n )\n }\n return prior.result as T\n }\n // Begin a fresh attempt (either net-new or retry of a failed step).\n const begun = await input.store.beginStep({\n runId: input.runId,\n stepIndex,\n intent,\n kind: opts?.kind ?? 'logic',\n inputHash,\n })\n try {\n const result = await fn()\n const completed = await input.store.completeStep({\n runId: input.runId,\n stepIndex,\n result,\n })\n upsertCollected(collected, completed)\n priorByIndex.set(stepIndex, completed)\n return result\n } catch (err) {\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n throw err\n } finally {\n // The `begun` reference suppresses \"unused\" warnings without an\n // eslint-disable comment.\n void begun\n }\n },\n async awaitEvent<T>(key: string, opts?: { timeoutMs?: number; pollMs?: number }): Promise<T> {\n const stepIndex = positionCounter++\n const prior = priorByIndex.get(stepIndex)\n if (prior && prior.status === 'completed') {\n if (prior.intent !== `event:${key}`) {\n throw new DurableRunDivergenceError(\n `step ${stepIndex}: awaitEvent key changed across replays`,\n )\n }\n return prior.result as T\n }\n const beginAt = Date.now()\n const timeoutMs = opts?.timeoutMs ?? 60_000\n const pollMs = opts?.pollMs ?? DEFAULT_AWAIT_POLL_MS\n await input.store.beginStep({\n runId: input.runId,\n stepIndex,\n intent: `event:${key}`,\n kind: 'event',\n inputHash: '',\n })\n try {\n for (;;) {\n checkAbortAndLease(input.signal, leaseLost)\n const evt = await input.store.loadEvent(input.runId, key)\n if (evt) {\n const completed = await input.store.completeStep({\n runId: input.runId,\n stepIndex,\n result: evt.payload,\n })\n upsertCollected(collected, completed)\n priorByIndex.set(stepIndex, completed)\n return evt.payload as T\n }\n if (Date.now() - beginAt > timeoutMs) {\n const err = new DurableAwaitEventTimeoutError(\n `awaitEvent('${key}') timed out after ${timeoutMs}ms`,\n )\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n throw err\n }\n await sleep(pollMs, input.signal)\n }\n } catch (err) {\n // Any non-timeout error: mark failed (if not already), surface.\n if (!(err instanceof DurableAwaitEventTimeoutError)) {\n const existing = priorByIndex.get(stepIndex)\n if (!existing || existing.status !== 'failed') {\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n }\n }\n throw err\n }\n },\n async emitEvent(key: string, payload: unknown): Promise<{ accepted: boolean }> {\n const res = await input.store.emitEvent({ runId: input.runId, key, payload })\n return { accepted: res.accepted }\n },\n async now(): Promise<Date> {\n const v = await this.step(`deterministic:now`, async () => new Date().toISOString(), {\n kind: 'deterministic',\n })\n return new Date(v)\n },\n async uuid(): Promise<string> {\n return this.step(`deterministic:uuid`, async () => cryptoRandomUuid(), {\n kind: 'deterministic',\n })\n },\n }\n\n try {\n const result = await input.taskFn(ctx)\n const finalRecord = await input.store.endRun({\n runId: input.runId,\n workerId,\n status: 'completed',\n outcome: input.defaultOutcome,\n })\n return { result, record: finalRecord, steps: collected }\n } catch (err) {\n const finalRecord = await input.store.endRun({\n runId: input.runId,\n workerId,\n status: 'failed',\n outcome: {\n ...input.defaultOutcome,\n notes: err instanceof Error ? err.message : String(err),\n },\n })\n void finalRecord\n throw err\n } finally {\n clearInterval(heartbeat)\n }\n}\n\nfunction checkAbortAndLease(signal: AbortSignal | undefined, leaseLost: boolean): void {\n if (signal?.aborted) throw signal.reason ?? new Error('aborted')\n if (leaseLost) throw new Error('durable-runs: lease lost; another worker has taken over this run')\n}\n\nfunction upsertCollected(list: StepRecord[], rec: StepRecord): void {\n const i = list.findIndex((s) => s.stepIndex === rec.stepIndex)\n if (i === -1) list.push(rec)\n else list[i] = rec\n}\n\nfunction toStepError(err: unknown): { message: string; code?: string; stack?: string } {\n if (err instanceof Error) {\n return {\n message: err.message,\n code: (err as { code?: string }).code,\n stack: err.stack,\n }\n }\n return { message: String(err) }\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\nfunction cryptoRandomUuid(): string {\n // Defensive: globalThis.crypto.randomUUID may not be available in older\n // Node — fall back to a manual v4 derivation.\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return globalThis.crypto.randomUUID()\n }\n const bytes = new Uint8Array(16)\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256)\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n}\n\n// Re-export for callers that want manifestHash without reaching into identity.\nexport { manifestHash }\n","/**\n * Cloudflare Workflows integration for the durable-run substrate.\n *\n * Two valid deployment patterns on Cloudflare:\n *\n * A. **Plain Worker + D1DurableRunStore.** Each request invokes\n * `runDurable(...)` directly against a D1 binding. Survives worker\n * isolate restarts; lease takeover happens via D1 row-level\n * conditional UPDATE. The default path; no Workflows binding needed.\n *\n * B. **Cloudflare Workflows entrypoint.** Wrap an entire `runDurable(...)`\n * call inside a single Workflow `step.do(...)`. Workflows gives you\n * retry-on-throw with platform-managed exponential backoff and\n * survives full Workers deploy rolls. Use it when the task can take\n * minutes to hours, or when you want the Workflows dashboard for\n * observability. Inside the step, `runDurable` still uses D1 for\n * step-level checkpoints — so a half-completed run resumes from\n * its last checkpoint on retry rather than restarting from scratch.\n *\n * This module provides the surface for pattern B: a thin helper that\n * converts a Workflows `WorkflowStep` into a `DurableContext`. We do not\n * take a runtime dep on `cloudflare:workers` — the integration is purely\n * structural typing.\n *\n * Example (pattern B):\n *\n * import { WorkflowEntrypoint } from 'cloudflare:workers'\n * import { runOnWorkflowStep } from '@tangle-network/agent-runtime'\n *\n * export class LegalChatWorkflow extends WorkflowEntrypoint<Env, ChatParams> {\n * async run(event, step) {\n * return runOnWorkflowStep(step, {\n * workflowName: 'legal-chat',\n * taskFn: async (ctx) => {\n * const ready = await ctx.step('readiness', () => probeKnowledge(...))\n * const answer = await ctx.step('llm:turn-1', () => callLlm(...))\n * const shipped = await ctx.awaitEvent('shipped', { timeoutMs: 5 * 60_000 })\n * return { answer, shipped }\n * },\n * })\n * }\n * }\n *\n * Step ordering, replay semantics, and divergence detection inside the\n * `taskFn` are inherited from Cloudflare's Workflows engine — we\n * intentionally do NOT layer a second durable store inside this path.\n * Pick pattern A or pattern B per agent; do not mix.\n */\n\nimport type { DurableContext } from './runner'\n\n/**\n * Structural subset of Cloudflare's `WorkflowStep`. Mirrors the public surface\n * documented at https://developers.cloudflare.com/workflows/build/. Defined\n * here so this module imposes zero `cloudflare:workers` runtime dependency.\n */\nexport interface WorkflowStepLike {\n do<T>(name: string, opts: WorkflowStepConfig, fn: () => Promise<T>): Promise<T>\n do<T>(name: string, fn: () => Promise<T>): Promise<T>\n sleep(name: string, duration: string | number): Promise<void>\n waitForEvent<T = unknown>(\n name: string,\n opts: { type: string; timeout?: string },\n ): Promise<{\n payload: T\n timestamp: number\n type: string\n }>\n}\n\nexport interface WorkflowStepConfig {\n retries?: {\n limit: number\n delay: string | number\n backoff?: 'constant' | 'linear' | 'exponential'\n }\n timeout?: string | number\n}\n\nexport interface RunOnWorkflowStepInput<TResult> {\n /** Logical workflow name; used as a prefix on step ids for filtering. */\n workflowName: string\n /** User task — same shape as runDurable's taskFn. */\n taskFn: (ctx: DurableContext) => Promise<TResult>\n /** Optional per-step retry / timeout policy applied to ctx.step calls. */\n stepConfig?: WorkflowStepConfig\n /** Optional clock — defaults to Date.now. */\n now?: () => number\n}\n\n/**\n * Adapt a Cloudflare `WorkflowStep` into a `DurableContext` and run a task.\n *\n * Every `ctx.step(intent, fn)` becomes `step.do(<name>, fn)` with stable\n * names — Workflows checkpoints + replays based on step name + position,\n * matching our model.\n *\n * `ctx.awaitEvent(key)` becomes `step.waitForEvent(key, { type: key })`.\n * Caller is responsible for emitting from the platform side (e.g. via the\n * Workflows REST API or a sibling worker that publishes events).\n *\n * `ctx.now()` and `ctx.uuid()` go through `step.do` so the values are\n * captured in the platform's checkpoint state and remain stable across\n * replay — same invariant as our own stores.\n */\nexport async function runOnWorkflowStep<TResult>(\n workflowStep: WorkflowStepLike,\n input: RunOnWorkflowStepInput<TResult>,\n): Promise<TResult> {\n const stepCfg = input.stepConfig\n let counter = 0\n const stepName = (intent: string) => `${input.workflowName}/${counter++}:${intent}`\n\n const ctx: DurableContext = {\n runId: `cf-workflow:${input.workflowName}`,\n projectId: input.workflowName,\n async step<T>(intent: string, fn: () => Promise<T>): Promise<T> {\n const name = stepName(intent)\n if (stepCfg) {\n return workflowStep.do<T>(name, stepCfg, fn)\n }\n return workflowStep.do<T>(name, fn)\n },\n async awaitEvent<T = unknown>(key: string, opts?: { timeoutMs?: number }): Promise<T> {\n const timeout = opts?.timeoutMs ? `${Math.ceil(opts.timeoutMs / 1000)}s` : undefined\n const ev = await workflowStep.waitForEvent<T>(stepName(`event:${key}`), {\n type: key,\n timeout,\n })\n return ev.payload\n },\n async emitEvent(): Promise<{ accepted: boolean }> {\n // Workflows events are emitted from OUTSIDE the workflow (via the\n // platform API). A workflow that emits its own events is an\n // anti-pattern — surface that fail-loud rather than silently no-op.\n throw new Error(\n 'runOnWorkflowStep: ctx.emitEvent is not available inside a Workflows entrypoint. ' +\n 'Emit from the sibling worker that drives the workflow.',\n )\n },\n async now(): Promise<Date> {\n const iso = await this.step('deterministic:now', async () => new Date().toISOString())\n return new Date(iso)\n },\n async uuid(): Promise<string> {\n return this.step('deterministic:uuid', async () => {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return globalThis.crypto.randomUUID()\n }\n // Cloudflare runtime always has Web Crypto; fallback is defensive.\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n })\n },\n }\n\n return input.taskFn(ctx)\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 => 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 * 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 metadata: options.includeMetadata ? event.metadata : undefined,\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 '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","nowIso","record","DEFAULT_LEASE_MS","nowIso","record","rec","DEFAULT_LEASE_MS","nowIso","DEFAULT_LEASE_MS","sleep","counter","counter"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/sessions.ts","../src/backends.ts","../src/chat-turn.ts","../src/durable/identity.ts","../src/durable/turn.ts","../src/durable/chat-engine.ts","../src/durable/types.ts","../src/durable/d1-store.ts","../src/durable/file-system-store.ts","../src/durable/in-memory-store.ts","../src/durable/runner.ts","../src/durable/schema.ts","../src/durable/workflows.ts","../src/intent-router.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\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\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 }\n return {\n kind,\n start(_input, context) {\n return newRuntimeSession(kind, context.requestedSessionId)\n },\n async *stream(input, context) {\n let response: Response | undefined\n let lastStatus = 0\n for (let attempt = 1; attempt <= retryPolicy.maxAttempts; attempt++) {\n response = await fetcher(`${options.baseUrl.replace(/\\/$/, '')}/chat/completions`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${options.apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: 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 signal: context.signal,\n })\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 || !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 === '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/<id>`. */\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 * Identity + canonical-hash helpers for the durable-runs substrate.\n *\n * Two boundary disciplines:\n *\n * 1. **Manifest hash** — sha256 over a sorted-key JSON of (projectId,\n * scenarioId, task.id, task.intent, task.domain, input). Same hash =\n * same run identity. Used to detect \"same runId, different inputs.\"\n *\n * 2. **Step input hash** — sha256 over a sorted-key JSON of the step's\n * input fingerprint. Used to detect drift across replays.\n *\n * Sorted-key JSON makes hashes deterministic regardless of object insertion\n * order. NaN / Infinity / undefined / functions / symbols / class instances\n * are rejected — pure JSON only at the boundary, so the hash matches whatever\n * the store round-trips.\n */\n\nimport { createHash } from 'node:crypto'\n\nimport type { DurableRunManifest } from './types'\n\n/** sha256-hex over a JSON-canonicalized value. */\nexport function canonicalHash(value: unknown): string {\n const json = canonicalJson(value)\n return createHash('sha256').update(json).digest('hex')\n}\n\n/** Canonical JSON: object keys sorted lexicographically; arrays preserved. */\nexport function canonicalJson(value: unknown): string {\n return JSON.stringify(canonicalize(value))\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null) return null\n if (Array.isArray(value)) return value.map(canonicalize)\n const t = typeof value\n if (t === 'string' || t === 'boolean') return value\n if (t === 'number') {\n if (!Number.isFinite(value as number)) {\n throw new TypeError(`canonicalJson: non-finite number ${String(value)} not serializable`)\n }\n return value\n }\n if (t === 'undefined' || t === 'function' || t === 'symbol') {\n throw new TypeError(`canonicalJson: ${t} is not JSON-serializable`)\n }\n if (t === 'bigint') {\n // BigInts have no JSON representation. Encode as string; tag for\n // disambiguation so consumers can choose to reject or decode.\n return { __bigint: String(value) }\n }\n if (t === 'object') {\n const obj = value as Record<string, unknown>\n // Reject class instances — Date / Error / Map / Set / TypedArray — to\n // force callers to project to plain JSON at the boundary. Errors round-\n // tripped silently are the #1 source of \"looks the same but differs\"\n // bugs.\n const proto = Object.getPrototypeOf(obj)\n if (proto !== null && proto !== Object.prototype) {\n const ctor = obj.constructor?.name ?? 'unknown'\n throw new TypeError(\n `canonicalJson: class instance (${ctor}) is not JSON-serializable. Project to plain { ... } at the boundary.`,\n )\n }\n const keys = Object.keys(obj).sort()\n const out: Record<string, unknown> = {}\n for (const k of keys) out[k] = canonicalize(obj[k])\n return out\n }\n throw new TypeError(`canonicalJson: unsupported type ${t}`)\n}\n\n/** Hash a DurableRunManifest into the run identity component. */\nexport function manifestHash(manifest: DurableRunManifest): string {\n return canonicalHash({\n projectId: manifest.projectId,\n scenarioId: manifest.scenarioId ?? null,\n taskId: manifest.task.id,\n taskIntent: manifest.task.intent,\n taskDomain: manifest.task.domain,\n input: manifest.input,\n })\n}\n\n/** Stable per-step identifier — hash of (runId, position, intent). */\nexport function stepId(runId: string, stepIndex: number, intent: string): string {\n return canonicalHash({ runId, stepIndex, intent })\n}\n\nlet counter = 0\n/**\n * Stable worker id for a single process. Format: `host:pid:rand`. Random\n * suffix prevents collisions when the host/pid pair is short-lived (e.g.,\n * Cloudflare isolates that recycle fast).\n */\nexport function deriveWorkerId(): string {\n const host = process.env.HOSTNAME ?? 'host'\n const pid = process.pid ?? 0\n const rand = Math.random().toString(36).slice(2, 10)\n counter += 1\n return `${host}:${pid}:${rand}:${counter}`\n}\n","/**\n * `runDurableTurn` — a streaming, backend-agnostic, checkpoint+replay durable\n * turn. The single reusable primitive every product's chat handler routes\n * through, so per-product durability code drops to zero.\n *\n * A **turn** is one request→response unit: a producer yields a stream of\n * events and, once drained, exposes the turn's final text. `runDurableTurn`\n * wraps that with a `DurableRunStore`:\n *\n * - **Fresh run** — no completed step for this `(runId)`. The producer\n * runs; its events forward live to the caller (streaming preserved)\n * while final text accumulates; on drain the text is checkpointed.\n *\n * - **Replay** — a completed step already exists (the worker died after\n * the turn finished but before the response reached the client, and the\n * client retried the same turn). The cached text is emitted as a single\n * synthetic event; the producer is never constructed — no LLM call, no\n * double-billing.\n *\n * - **Mid-stream crash** — a turn that died *while streaming* leaves step 0\n * in `running`/`failed`. There is no partial-stream checkpoint (the\n * substrate checkpoints JSON values at step granularity), so the turn\n * re-runs from the top. This is the honest durability ceiling: a\n * *completed* turn is free to replay; an *interrupted* turn re-runs.\n *\n * Generic over the event type `TEvent` so a product can stream its own NDJSON\n * shape or the runtime's `RuntimeStreamEvent` — `runDurableTurn` never\n * inspects events, it only forwards them and reads `finalText()` after drain.\n *\n * Lease: a turn is a single step, fast enough that the heartbeat in\n * `runDurable` is unnecessary — `runDurableTurn` claims the lease once via\n * `startOrResume` and releases it on `endRun`. Concurrent workers on the same\n * `runId` are rejected with `DurableRunLeaseHeldError` (the client retried\n * before the first attempt finished); callers surface that as \"turn already\n * in flight.\"\n */\n\nimport { canonicalHash } from './identity'\nimport type { DurableRunManifest, DurableRunStore, RunRecord } from './types'\n\n/** The live side of a turn — what a fresh run produces. */\nexport interface DurableTurnProducer<TEvent> {\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 RunDurableTurnOptions<TEvent> {\n store: DurableRunStore\n /** Stable per-turn run id. Convention: `chat:<threadId>:<turnIndex>`. The\n * same id on a retry is what enables replay. */\n runId: string\n manifest: DurableRunManifest\n /** Stable per-isolate worker id. Defaults to a fresh `deriveWorkerId()`\n * per call when omitted — fine for single-attempt turns. */\n workerId: string\n /** Lease window in ms. Default 60_000 — a turn rarely runs longer. */\n leaseMs?: number\n /** Human-readable step label. Default `turn`. */\n intent?: string\n /** Builds the live producer. Called exactly once, on a fresh run; never\n * called on the replay path. */\n produce: () => DurableTurnProducer<TEvent>\n /** Synthesizes the single event emitted on the replay path from the\n * cached final text (e.g. a product's `{ type: 'result', data: {...} }`). */\n replayEvent: (finalText: string) => TEvent\n /** Optional live accumulator. When the producer's `finalText()` is only\n * valid after drain, this lets `runDurableTurn` also observe each event\n * to build the text — return the running text or `undefined` to ignore\n * an event. When omitted, `producer.finalText()` is the sole source. */\n accumulate?: (event: TEvent, current: string) => string | undefined\n}\n\nexport interface DurableTurnHandle<TEvent> {\n /** Drop-in stream. Fresh runs forward producer events live; replays emit\n * exactly one `replayEvent(cachedText)`. */\n stream: AsyncGenerator<TEvent, void, unknown>\n /** The turn's final text. Valid after `stream` drains. */\n finalText(): string\n /** True iff this turn replayed a cached result (no producer ran). Valid\n * after `stream` drains. */\n replayed(): boolean\n /** The durable `RunRecord` for this turn. Valid after `stream` drains. */\n record(): RunRecord | undefined\n}\n\nconst STEP_INDEX = 0\n\nexport function runDurableTurn<TEvent>(\n options: RunDurableTurnOptions<TEvent>,\n): DurableTurnHandle<TEvent> {\n const { store, runId, manifest, workerId } = options\n const leaseMs = options.leaseMs ?? 60_000\n const intent = options.intent ?? 'turn'\n const inputHash = canonicalHash(manifest.input)\n\n let accumulated = ''\n let didReplay = false\n let finalRecord: RunRecord | undefined\n\n async function* stream(): AsyncGenerator<TEvent, void, unknown> {\n const { completedSteps } = await store.startOrResume({\n runId,\n manifest,\n workerId,\n leaseMs,\n })\n const prior = completedSteps.find((s) => s.stepIndex === STEP_INDEX)\n\n if (prior && prior.status === 'completed') {\n // ── Replay path — producer never constructed ──────────────────\n didReplay = true\n const cached = prior.result as { finalText?: string } | undefined\n accumulated = cached?.finalText ?? ''\n yield options.replayEvent(accumulated)\n finalRecord = await store.endRun({ runId, workerId, status: 'completed' })\n return\n }\n\n // ── Fresh run — produce live, forward, checkpoint ────────────────\n await store.beginStep({\n runId,\n stepIndex: STEP_INDEX,\n intent,\n kind: 'llm',\n inputHash,\n })\n try {\n const producer = options.produce()\n for await (const event of producer.stream) {\n if (options.accumulate) {\n const next = options.accumulate(event, accumulated)\n if (typeof next === 'string') accumulated = next\n }\n yield event\n }\n // Producer's own finalText wins when it is populated; otherwise the\n // live accumulator's value stands.\n const producerText = producer.finalText()\n if (producerText) accumulated = producerText\n await store.completeStep({\n runId,\n stepIndex: STEP_INDEX,\n result: { finalText: accumulated },\n })\n finalRecord = await store.endRun({\n runId,\n workerId,\n status: 'completed',\n outcome: { notes: intent, metadata: { chars: accumulated.length } },\n })\n } catch (err) {\n await store.failStep({\n runId,\n stepIndex: STEP_INDEX,\n error: { message: err instanceof Error ? err.message : String(err) },\n })\n finalRecord = await store.endRun({ runId, workerId, status: 'failed' })\n throw err\n }\n }\n\n return {\n stream: stream(),\n finalText: () => accumulated,\n replayed: () => didReplay,\n record: () => finalRecord,\n }\n}\n","/**\n * `DurableChatTurnEngine` — the framework-neutral chat-turn orchestrator every\n * product chat handler routes through. It owns the parts that were copy-pasted\n * across legal / gtm / creative / tax: durable checkpointing, the NDJSON\n * `StreamEvent` line protocol, the `session.run.*` lifecycle vocabulary, the\n * runtime-run cost ledger, and trace flush. Everything genuinely\n * product-specific is a hook the product supplies.\n *\n * What the engine owns:\n * - durable turn (`runDurableTurn`): completed turns replay free, no re-bill\n * - the `session.run.started` / `session.run.completed` / `session.run.failed`\n * event envelope around the producer's events\n * - NDJSON encoding into a `ReadableStream<Uint8Array>` (the body every\n * product returns, React Router or Hono alike)\n * - calling the product's persist / post-process hooks in the right order,\n * after the stream drains, with the assembled final text\n * - never throwing into the HTTP layer — a producer failure becomes an\n * `error` + `session.run.failed` event pair, the stream still closes\n *\n * What the product supplies (`ChatTurnHooks`):\n * - `produce` — build the backend stream for this turn (sandbox / router\n * / tcloud / runtime — the engine does not care which)\n * - `persistAssistantMessage` — write the assistant turn to the product DB\n * - `onTurnComplete` (optional) — post-process (proposals, citations, …)\n * - `onEvent` (optional) — per-event side-channel (e.g. DO broadcast)\n * - `transformFinalText` (optional) — pre-persist transform (e.g. PII redact)\n *\n * Framework neutrality: the engine takes already-resolved values\n * (`userId`, identity tuple, parsed message, a `DurableRunStore`, a\n * `waitUntil`), never a `Request` or a `Context`. The product's thin route\n * adapter does auth + parse + access-control, then calls `engine.runTurn(...)`\n * and returns `result.body` as its platform `Response`.\n */\n\nimport { deriveWorkerId } from './identity'\nimport { type DurableTurnProducer, runDurableTurn } from './turn'\nimport type { DurableRunManifest, DurableRunStore, RunRecord } from './types'\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 — the durable run is keyed on this + `turnIndex`. */\n sessionId: string\n userId: string\n /** Monotonic 0-based turn index within the session. */\n turnIndex: number\n}\n\nexport interface ChatTurnHooks {\n /**\n * Build the backend stream for this turn. The engine never inspects which\n * backend this is — sandbox container, tcloud router, direct runtime, a\n * test double — it only forwards the events and reads `finalText()`.\n */\n produce(): DurableTurnProducer<ChatStreamEvent>\n /**\n * Persist the completed assistant message to the product's own store.\n * Called once, after the stream drains, on a fresh (non-replay) run.\n * Receives the assembled (and `transformFinalText`-transformed) text.\n */\n persistAssistantMessage(input: {\n identity: ChatTurnIdentity\n finalText: string\n record: RunRecord | undefined\n }): Promise<void>\n /**\n * Optional post-processing after persistence — proposal extraction,\n * citation validation, credit metering, etc. Product policy; the engine\n * has no shared logic here. Errors are swallowed + logged (post-process\n * must never fail the turn that already streamed successfully).\n */\n onTurnComplete?(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /**\n * Optional per-event side channel (e.g. Durable Object broadcast). Runs\n * for every event the engine emits, lifecycle envelope included. Errors\n * are swallowed — a broadcast failure must not break the chat stream.\n */\n onEvent?(event: ChatStreamEvent): void | Promise<void>\n /**\n * Optional pre-persist transform of the final text (e.g. PII redaction).\n * Affects only what is persisted; the live stream is never altered.\n */\n transformFinalText?(text: string): string | Promise<string>\n /**\n * Optional trace flush — resolves when OTLP export completes. The engine\n * hands it to `waitUntil` so the worker isolate stays alive for the POST.\n */\n traceFlush?(): Promise<void>\n}\n\nexport interface RunChatTurnInput {\n identity: ChatTurnIdentity\n /** The user's message for this turn. Hashed into the durable run identity. */\n userMessage: string\n /** Product id for telemetry / the durable manifest (`legal-agent`, …). */\n projectId: string\n /** Domain tag for the task spec (`legal`, `gtm`, …). */\n domain: string\n /** Model id, when known — recorded on the manifest. */\n model?: string\n store: DurableRunStore\n hooks: ChatTurnHooks\n /** Worker liveness hook (`ctx.waitUntil` / `executionCtx.waitUntil`). When\n * omitted, trace flush is awaited inline before the stream closes. */\n waitUntil?: (p: Promise<unknown>) => void\n /** Stable per-isolate worker id. Defaults to a fresh `deriveWorkerId()`. */\n workerId?: string\n /** Lease window in ms. Default 60_000. */\n leaseMs?: number\n /** Optional structured logger for swallowed hook errors. */\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\n/**\n * The engine. One instance is stateless and reusable across requests — all\n * per-turn state lives in `runTurn`'s closure.\n */\nexport class DurableChatTurnEngine {\n /**\n * Run one durable chat turn. Returns immediately with a `ReadableStream`\n * body; the turn executes as the body is pulled. Never rejects — backend\n * failures surface as `error` + `session.run.failed` events.\n */\n runTurn(input: RunChatTurnInput): ChatTurnResult {\n const workerId = input.workerId ?? deriveWorkerId()\n const log = input.log ?? (() => undefined)\n const { identity } = input\n const runId = `chat:${identity.sessionId}:${identity.turnIndex}`\n\n const manifest: DurableRunManifest = {\n projectId: input.projectId,\n scenarioId: identity.sessionId,\n task: {\n id: `${input.projectId}:chat:${identity.sessionId}:${identity.turnIndex}`,\n intent: `Run a ${input.domain} chat turn with workspace context.`,\n domain: input.domain,\n requiredKnowledge: [],\n metadata: {\n tenantId: identity.tenantId,\n sessionId: identity.sessionId,\n turnIndex: identity.turnIndex,\n },\n },\n input: {\n userMessage: input.userMessage,\n model: input.model ?? null,\n },\n tags: {\n session_id: identity.sessionId,\n tenant_id: identity.tenantId,\n },\n }\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 (input.hooks.onEvent) {\n try {\n await input.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 let turnFailed = false\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 turn = runDurableTurn<ChatStreamEvent>({\n store: input.store,\n runId,\n manifest,\n workerId,\n leaseMs: input.leaseMs,\n intent: `chat:turn-${identity.turnIndex}`,\n produce: input.hooks.produce,\n replayEvent: (finalText) => ({ type: 'result', data: { finalText } }),\n accumulate: (event, current) => {\n // Accumulate from the same event shapes products already emit:\n // `message.part.updated` text deltas and a trailing `result`.\n if (event.type === 'message.part.updated') {\n const data = event.data ?? {}\n const delta = typeof data.delta === 'string' ? data.delta : ''\n const part = data.part as { type?: string; text?: string } | undefined\n if (delta) return current + delta\n if (part?.type === 'text' && typeof part.text === 'string') return part.text\n return undefined\n }\n if (event.type === 'result') {\n const data = event.data ?? {}\n if (typeof data.finalText === 'string') return data.finalText\n }\n return undefined\n },\n })\n\n for await (const event of turn.stream) {\n await emit(event)\n }\n\n const rawFinal = turn.finalText()\n const finalText = input.hooks.transformFinalText\n ? await input.hooks.transformFinalText(rawFinal)\n : rawFinal\n\n // Persist + post-process only on a fresh run. On replay the\n // assistant message + side effects already landed on the first\n // (completed) attempt — re-persisting would double-write.\n if (!turn.replayed()) {\n try {\n await input.hooks.persistAssistantMessage({\n identity,\n finalText,\n record: turn.record(),\n })\n } catch (err) {\n log('[chat-engine] persistAssistantMessage threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n if (input.hooks.onTurnComplete) {\n try {\n await input.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\n await emit({\n type: 'session.run.completed',\n data: { sessionId: identity.sessionId, replayed: turn.replayed() },\n })\n } catch (err) {\n turnFailed = true\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 // Trace flush: hand to waitUntil so the isolate survives the POST;\n // await inline when no waitUntil is available (local / tests).\n if (input.hooks.traceFlush) {\n const flush = input.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 void turnFailed\n }\n },\n })\n\n return { body, contentType: 'application/x-ndjson' }\n }\n}\n\n/** Convenience singleton — the engine is stateless, one instance is enough. */\nexport const durableChatTurnEngine = new DurableChatTurnEngine()\n","/**\n * Durable-run substrate: the typed contract for checkpointed agent runs that\n * survive worker crashes, deploy rolls, OOM, and transient transport errors.\n *\n * The model — directly inspired by Absurd (Postgres-backed) and Cloudflare\n * Workflows — splits a run into ordered, idempotent **steps**. Each step's\n * result is persisted before the next step runs. On resume, the runner reads\n * the prior steps from a `DurableRunStore` and fast-replays them (returning\n * cached values) until it reaches the first unfinished step, where execution\n * actually resumes.\n *\n * Three boundary disciplines:\n *\n * 1. Step results MUST be JSON-serializable. No closures, no class\n * instances, no live streams. The store treats results as opaque JSON.\n *\n * 2. Step intents MUST be stable across replays. The runner derives a\n * stable step id from (runId, stepIndex, intent). Mismatched intent at\n * the same index = `DurableRunDivergenceError`.\n *\n * 3. Non-determinism (now / uuid / random) MUST flow through the\n * `DurableContext` helpers — `ctx.now()`, `ctx.uuid()` — so the values\n * are checkpointed and identical on replay. Bare `Date.now()` /\n * `crypto.randomUUID()` inside a task fn breaks replay equality.\n */\n\nimport type { AgentTaskSpec } from '../types'\n\n/** Caller-facing kinds. The runner uses these for telemetry + querying. */\nexport type StepKind =\n /** Logical step that ran user code (the default for ctx.step). */\n | 'logic'\n /** A wrapped LLM call. */\n | 'llm'\n /** A wrapped tool call. */\n | 'tool'\n /** A wrapped readiness probe. */\n | 'readiness'\n /** A deterministic clock or uuid read. */\n | 'deterministic'\n /** A suspend-for-event boundary. */\n | 'event'\n\nexport type StepStatus = 'pending' | 'running' | 'completed' | 'failed'\n\nexport interface StepError {\n message: string\n code?: string\n /** Optional stack — stored for diagnostics, NEVER replayed as an exception. */\n stack?: string\n}\n\nexport interface StepRecord<T = unknown> {\n runId: string\n /** Monotonic 0-based index. Position is the load-bearing identifier — the\n * same intent string at different positions is a different step. */\n stepIndex: number\n /** Caller-supplied label; intended for human reading + log correlation. */\n intent: string\n kind: StepKind\n /** sha256 of the canonical input fingerprint at begin-time. Used to detect\n * divergence (caller changed inputs across replays). Empty for steps where\n * the input cannot be canonicalized (e.g. ctx.now()). */\n inputHash: string\n status: StepStatus\n /** Re-entry count. Increments each time the step begins. */\n attempts: number\n /** JSON-serializable result. Present when status === 'completed'. */\n result?: T\n error?: StepError\n startedAt?: string\n completedAt?: string\n}\n\nexport interface EventRecord {\n runId: string\n key: string\n payload: unknown\n emittedAt: string\n}\n\nexport type RunStatus = 'pending' | 'running' | 'completed' | 'failed' | 'suspended'\n\nexport interface RunOutcome {\n pass?: boolean\n score?: number\n notes?: string\n /** Free-form bag of run-level metrics — surfaced in OTLP / TraceStore. */\n metadata?: Record<string, unknown>\n}\n\nexport interface DurableRunManifest {\n /** Stable per-product id (e.g. 'legal-agent', 'creative-agent'). */\n projectId: string\n /** Optional scenario / persona / session id — surfaced in telemetry. */\n scenarioId?: string\n task: AgentTaskSpec\n /** Input payload. Hashed into the run identity so two runs with the same\n * runId but different inputs raise DurableRunInputMismatchError. */\n input: Record<string, unknown>\n /** Free-form tags surfaced into RunRecord / OTLP. */\n tags?: Record<string, string>\n}\n\nexport interface RunRecord {\n runId: string\n manifestHash: string\n projectId: string\n scenarioId?: string\n status: RunStatus\n createdAt: string\n updatedAt: string\n completedAt?: string\n /** Stable per-worker id holding the lease. */\n leaseHolderId?: string\n leaseExpiresAt?: string\n outcome?: RunOutcome\n stepCount: number\n}\n\n/**\n * The durable-run substrate. Implementations: in-memory (dev), file-system\n * (eval harness), D1 (Cloudflare prod). All stores share this exact contract\n * — swap by changing one factory call.\n *\n * Concurrency model: at most one worker holds a run's lease at a time. Lease\n * renewal happens on a heartbeat; on lease expiry, another worker can\n * `startOrResume` and pick up. Steps committed by the prior worker survive.\n */\nexport interface DurableRunStore {\n /**\n * Begin or resume a run. Returns the canonical RunRecord, all previously\n * completed steps (in order), and the lease deadline.\n *\n * If the run did not exist, creates it with status='running'. If it existed\n * with a different manifest hash, throws DurableRunInputMismatchError.\n * If it existed with a live lease held by a different worker, throws\n * DurableRunLeaseHeldError (caller can retry or back off).\n */\n startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): Promise<{\n run: RunRecord\n completedSteps: ReadonlyArray<StepRecord>\n leaseExpiresAt: string\n }>\n\n /** Renew the lease. Returns false if another worker now holds it. */\n renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }>\n\n /** Load a step by position. Returns undefined if not yet begun. */\n loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined>\n\n /** Record step start (intent + input hash + kind). Bumps attempt count. */\n beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord>\n\n /** Mark step completed with a JSON-serializable result. */\n completeStep(input: { runId: string; stepIndex: number; result: unknown }): Promise<StepRecord>\n\n /** Mark step failed with a captured error. */\n failStep(input: { runId: string; stepIndex: number; error: StepError }): Promise<StepRecord>\n\n /** End the run; releases lease. */\n endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord>\n\n /**\n * Emit an event. First emit wins; subsequent emits return the existing\n * record under `existing` and accepted=false. Caller can treat that as\n * idempotency-by-design — never double-fire a downstream side effect.\n */\n emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): Promise<{ accepted: boolean; record: EventRecord }>\n\n /** Load the cached event payload if it has been emitted. */\n loadEvent(runId: string, key: string): Promise<EventRecord | undefined>\n\n /** Cleanup hook for in-memory / fs stores; no-op for D1. Idempotent. */\n close(): Promise<void>\n}\n\n// ── Public error contract ────────────────────────────────────────────────\n\n/** Base class for durable-run errors. */\nexport class DurableRunError extends Error {\n constructor(\n message: string,\n public readonly code:\n | 'lease_held'\n | 'manifest_mismatch'\n | 'step_divergence'\n | 'step_input_mismatch'\n | 'await_event_timeout'\n | 'event_emit_race',\n ) {\n super(message)\n this.name = this.constructor.name\n }\n}\n\n/** Thrown when another worker holds the lease for this runId. */\nexport class DurableRunLeaseHeldError extends DurableRunError {\n constructor(message: string) {\n super(message, 'lease_held')\n }\n}\n\n/** Thrown when the manifest hash differs from a prior run with the same id. */\nexport class DurableRunInputMismatchError extends DurableRunError {\n constructor(message: string) {\n super(message, 'manifest_mismatch')\n }\n}\n\n/** Thrown when the same stepIndex re-runs with a different intent string. */\nexport class DurableRunDivergenceError extends DurableRunError {\n constructor(message: string) {\n super(message, 'step_divergence')\n }\n}\n\n/** Thrown when `awaitEvent` times out. */\nexport class DurableAwaitEventTimeoutError extends DurableRunError {\n constructor(message: string) {\n super(message, 'await_event_timeout')\n }\n}\n","/**\n * D1DurableRunStore — the production path for Cloudflare Workers. Backed by\n * a D1 (SQLite-compatible) database via the binding the worker already holds.\n *\n * Apply `./schema.sql` once before use; the store itself does not run DDL.\n * Migration version is recorded in `durable_schema_info`; consumers can\n * inspect `getSchemaVersion()` if they ship a migration tool.\n *\n * Why structural typing: agent-runtime stays Cloudflare-free at the dep\n * level. Consumers pass their `D1Database` binding — TypeScript matches the\n * minimal `D1DatabaseLike` surface below. Tests use the same interface with\n * a fake.\n */\n\nimport { manifestHash } from './identity'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n type DurableRunManifest,\n type DurableRunStore,\n type EventRecord,\n type RunOutcome,\n type RunRecord,\n type StepError,\n type StepKind,\n type StepRecord,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\n/**\n * Minimal D1 surface this store uses. Compatible with Cloudflare's\n * `D1Database` from `@cloudflare/workers-types`. Defined locally so\n * agent-runtime does not depend on workers-types at the package level.\n */\nexport interface D1DatabaseLike {\n prepare(query: string): D1PreparedStatementLike\n batch(statements: D1PreparedStatementLike[]): Promise<unknown[]>\n}\n\nexport interface D1PreparedStatementLike {\n bind(...values: unknown[]): D1PreparedStatementLike\n first<T = unknown>(): Promise<T | null>\n all<T = unknown>(): Promise<{ results: T[] }>\n run(): Promise<{ success: boolean; meta?: { changes?: number } }>\n}\n\ninterface RunRow {\n run_id: string\n manifest_hash: string\n project_id: string\n scenario_id: string | null\n status: RunRecord['status']\n created_at: string\n updated_at: string\n completed_at: string | null\n lease_holder_id: string | null\n lease_expires_at: string | null\n outcome_json: string | null\n step_count: number\n}\n\ninterface StepRow {\n run_id: string\n step_index: number\n intent: string\n kind: string\n input_hash: string\n status: StepRecord['status']\n attempts: number\n result_json: string | null\n error_json: string | null\n started_at: string | null\n completed_at: string | null\n}\n\ninterface EventRow {\n run_id: string\n key: string\n payload_json: string | null\n emitted_at: string\n}\n\nexport class D1DurableRunStore implements DurableRunStore {\n constructor(private readonly db: D1DatabaseLike) {}\n\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + leaseMs).toISOString()\n\n const existing = await this.db\n .prepare('SELECT * FROM durable_runs WHERE run_id = ?')\n .bind(input.runId)\n .first<RunRow>()\n\n if (!existing) {\n await this.db\n .prepare(\n `INSERT INTO durable_runs\n (run_id, manifest_hash, project_id, scenario_id, status,\n created_at, updated_at, lease_holder_id, lease_expires_at, step_count)\n VALUES (?, ?, ?, ?, 'running', ?, ?, ?, ?, 0)`,\n )\n .bind(\n input.runId,\n hash,\n input.manifest.projectId,\n input.manifest.scenarioId ?? null,\n nowIso,\n nowIso,\n input.workerId,\n leaseExpiresAt,\n )\n .run()\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n return { run: record, completedSteps: [], leaseExpiresAt }\n }\n\n if (existing.manifest_hash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n // Lease takeover — conditional UPDATE.\n const claim = await this.db\n .prepare(\n `UPDATE durable_runs\n SET lease_holder_id = ?,\n lease_expires_at = ?,\n updated_at = ?,\n status = CASE WHEN status IN ('completed','failed') THEN status ELSE 'running' END\n WHERE run_id = ?\n AND (\n lease_holder_id = ? OR\n lease_holder_id IS NULL OR\n lease_expires_at IS NULL OR\n lease_expires_at < ?\n )`,\n )\n .bind(input.workerId, leaseExpiresAt, nowIso, input.runId, input.workerId, nowIso)\n .run()\n const changes = claim.meta?.changes ?? 0\n if (changes === 0) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} leased by ${existing.lease_holder_id} until ${existing.lease_expires_at}`,\n )\n }\n const completedSteps = await this.readSteps(input.runId, 'completed')\n const record: RunRecord = rowToRunRecord({\n ...existing,\n lease_holder_id: input.workerId,\n lease_expires_at: leaseExpiresAt,\n updated_at: nowIso,\n status:\n existing.status === 'completed' || existing.status === 'failed'\n ? existing.status\n : 'running',\n })\n return { run: record, completedSteps, leaseExpiresAt }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)).toISOString()\n const res = await this.db\n .prepare(\n `UPDATE durable_runs\n SET lease_expires_at = ?, updated_at = ?\n WHERE run_id = ?\n AND (lease_holder_id = ? OR lease_expires_at IS NULL OR lease_expires_at < ?)`,\n )\n .bind(leaseExpiresAt, nowIso, input.runId, input.workerId, nowIso)\n .run()\n const ok = (res.meta?.changes ?? 0) > 0\n return ok ? { ok: true, leaseExpiresAt } : { ok: false }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const row = await this.db\n .prepare('SELECT * FROM durable_steps WHERE run_id = ? AND step_index = ?')\n .bind(runId, stepIndex)\n .first<StepRow>()\n return row ? rowToStepRecord(row) : undefined\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n const prior = await this.loadStep(input.runId, input.stepIndex)\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='running', attempts = attempts + 1, started_at = ?, error_json = NULL\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n return {\n ...prior,\n attempts: prior.attempts + 1,\n status: 'running',\n startedAt: nowIso,\n error: undefined,\n }\n }\n await this.db\n .prepare(\n `INSERT INTO durable_steps\n (run_id, step_index, intent, kind, input_hash, status, attempts, started_at)\n VALUES (?, ?, ?, ?, ?, 'running', 1, ?)`,\n )\n .bind(input.runId, input.stepIndex, input.intent, input.kind, input.inputHash, nowIso)\n .run()\n await this.db\n .prepare(\n `UPDATE durable_runs\n SET step_count = MAX(step_count, ?), updated_at = ?\n WHERE run_id = ?`,\n )\n .bind(input.stepIndex + 1, nowIso, input.runId)\n .run()\n return {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='completed', result_json = ?, completed_at = ?, error_json = NULL\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(JSON.stringify(input.result ?? null), nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n const row = await this.loadStep(input.runId, input.stepIndex)\n if (!row) {\n throw new Error(`durable-runs: completeStep cannot find step ${input.stepIndex}`)\n }\n return row\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_steps\n SET status='failed', error_json = ?, completed_at = ?\n WHERE run_id = ? AND step_index = ?`,\n )\n .bind(JSON.stringify(input.error), nowIso, input.runId, input.stepIndex)\n .run()\n await this.bumpUpdated(input.runId, nowIso)\n const row = await this.loadStep(input.runId, input.stepIndex)\n if (!row) {\n throw new Error(`durable-runs: failStep cannot find step ${input.stepIndex}`)\n }\n return row\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const nowIso = new Date(this.now()).toISOString()\n await this.db\n .prepare(\n `UPDATE durable_runs\n SET status = ?, completed_at = ?, updated_at = ?,\n outcome_json = ?,\n lease_holder_id = CASE WHEN lease_holder_id = ? THEN NULL ELSE lease_holder_id END,\n lease_expires_at = CASE WHEN lease_holder_id = ? THEN NULL ELSE lease_expires_at END\n WHERE run_id = ?`,\n )\n .bind(\n input.status,\n nowIso,\n nowIso,\n input.outcome ? JSON.stringify(input.outcome) : null,\n input.workerId,\n input.workerId,\n input.runId,\n )\n .run()\n const row = await this.db\n .prepare('SELECT * FROM durable_runs WHERE run_id = ?')\n .bind(input.runId)\n .first<RunRow>()\n if (!row) throw new Error(`durable-runs: endRun cannot find run ${input.runId}`)\n return rowToRunRecord(row)\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const nowIso = new Date(this.now()).toISOString()\n // INSERT OR IGNORE — first emit wins; subsequent inserts no-op.\n const res = await this.db\n .prepare(\n `INSERT OR IGNORE INTO durable_events (run_id, key, payload_json, emitted_at)\n VALUES (?, ?, ?, ?)`,\n )\n .bind(input.runId, input.key, JSON.stringify(input.payload ?? null), nowIso)\n .run()\n const accepted = (res.meta?.changes ?? 0) > 0\n const row = await this.db\n .prepare('SELECT * FROM durable_events WHERE run_id = ? AND key = ?')\n .bind(input.runId, input.key)\n .first<EventRow>()\n if (!row) throw new Error('durable-runs: emitEvent failed to persist or read back')\n return {\n accepted,\n record: rowToEventRecord(row),\n }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const row = await this.db\n .prepare('SELECT * FROM durable_events WHERE run_id = ? AND key = ?')\n .bind(runId, key)\n .first<EventRow>()\n return row ? rowToEventRecord(row) : undefined\n }\n\n async close(): Promise<void> {\n // D1 binding lifecycle is owned by the runtime; no-op.\n }\n\n /** Inspect the currently-applied schema version. */\n async getSchemaVersion(): Promise<number | undefined> {\n const row = await this.db\n .prepare('SELECT MAX(version) AS version FROM durable_schema_info')\n .first<{ version: number | null }>()\n return row?.version ?? undefined\n }\n\n // ── internals ──────────────────────────────────────────────────────\n\n private async readSteps(\n runId: string,\n status: StepRecord['status'],\n ): Promise<ReadonlyArray<StepRecord>> {\n const { results } = await this.db\n .prepare('SELECT * FROM durable_steps WHERE run_id = ? AND status = ? ORDER BY step_index')\n .bind(runId, status)\n .all<StepRow>()\n return results.map(rowToStepRecord)\n }\n\n private async bumpUpdated(runId: string, nowIso: string): Promise<void> {\n await this.db\n .prepare('UPDATE durable_runs SET updated_at = ? WHERE run_id = ?')\n .bind(nowIso, runId)\n .run()\n }\n}\n\n// ── row → record helpers ───────────────────────────────────────────────\n\nfunction rowToRunRecord(row: RunRow): RunRecord {\n return {\n runId: row.run_id,\n manifestHash: row.manifest_hash,\n projectId: row.project_id,\n scenarioId: row.scenario_id ?? undefined,\n status: row.status,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n completedAt: row.completed_at ?? undefined,\n leaseHolderId: row.lease_holder_id ?? undefined,\n leaseExpiresAt: row.lease_expires_at ?? undefined,\n outcome: row.outcome_json ? (JSON.parse(row.outcome_json) as RunOutcome) : undefined,\n stepCount: row.step_count,\n }\n}\n\nfunction rowToStepRecord(row: StepRow): StepRecord {\n return {\n runId: row.run_id,\n stepIndex: row.step_index,\n intent: row.intent,\n kind: row.kind as StepKind,\n inputHash: row.input_hash,\n status: row.status,\n attempts: row.attempts,\n result: row.result_json ? JSON.parse(row.result_json) : undefined,\n error: row.error_json ? (JSON.parse(row.error_json) as StepError) : undefined,\n startedAt: row.started_at ?? undefined,\n completedAt: row.completed_at ?? undefined,\n }\n}\n\nfunction rowToEventRecord(row: EventRow): EventRecord {\n return {\n runId: row.run_id,\n key: row.key,\n payload: row.payload_json ? JSON.parse(row.payload_json) : null,\n emittedAt: row.emitted_at,\n }\n}\n","/**\n * FileSystemDurableRunStore — durable-run substrate backed by a directory\n * tree under a single root. One subdir per run:\n *\n * <root>/<runId>/\n * run.json — RunRecord (rewritten on every mutation; the only\n * scalar fields are status/lease, so this stays small)\n * steps.jsonl — append-only StepRecord stream; one JSON per line\n * events.jsonl — append-only EventRecord stream\n * lease.json — current leaseholder + deadline (separate from\n * run.json so renewLease writes one tiny file\n * instead of round-tripping the whole run record)\n *\n * Concurrency: the eval harness is single-process — we rely on Node's\n * append-mode semantics for atomicity of step / event writes (single-line\n * writes < PIPE_BUF are atomic on POSIX). For run.json / lease.json we write\n * to a `<file>.tmp` then `rename` to make replacement atomic. This is\n * sufficient for the single-process eval harness use case. Multi-process\n * concurrency on the SAME filesystem requires a flock-based extension;\n * for that path use D1DurableRunStore.\n */\n\nimport { existsSync, mkdirSync } from 'node:fs'\nimport { appendFile, readdir, readFile, rename, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nimport { manifestHash } from './identity'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n type DurableRunManifest,\n type DurableRunStore,\n type EventRecord,\n type RunOutcome,\n type RunRecord,\n type StepError,\n type StepKind,\n type StepRecord,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\ninterface LeaseFile {\n workerId: string\n leaseExpiresAt: string\n}\n\nexport class FileSystemDurableRunStore implements DurableRunStore {\n constructor(private readonly root: string) {\n mkdirSync(root, { recursive: true })\n }\n\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresAt = new Date(nowMs + leaseMs).toISOString()\n const dir = this.runDir(input.runId)\n\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n await this.writeRun(record)\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n // Touch the jsonl files so listing them later doesn't ENOENT.\n await appendFile(join(dir, 'steps.jsonl'), '', 'utf8')\n await appendFile(join(dir, 'events.jsonl'), '', 'utf8')\n return { run: record, completedSteps: [], leaseExpiresAt }\n }\n\n const record = await this.readRun(input.runId)\n if (record.manifestHash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n const lease = await this.readLeaseSafe(input.runId)\n const leaseStillLive =\n lease && lease.workerId !== input.workerId && new Date(lease.leaseExpiresAt).getTime() > nowMs\n if (leaseStillLive) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} leased by ${lease.workerId} until ${lease.leaseExpiresAt}`,\n )\n }\n const completedSteps = await this.readSteps(input.runId)\n const nextRecord: RunRecord = {\n ...record,\n status:\n record.status === 'completed' || record.status === 'failed' ? record.status : 'running',\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n }\n await this.writeRun(nextRecord)\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n return { run: nextRecord, completedSteps, leaseExpiresAt }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const lease = await this.readLeaseSafe(input.runId)\n const nowMs = this.now()\n if (lease && lease.workerId !== input.workerId) {\n if (new Date(lease.leaseExpiresAt).getTime() > nowMs) {\n return { ok: false }\n }\n }\n const leaseExpiresAt = new Date(nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)).toISOString()\n await this.writeLease(input.runId, { workerId: input.workerId, leaseExpiresAt })\n return { ok: true, leaseExpiresAt }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const steps = await this.readSteps(runId, { includeFailed: true, includeRunning: true })\n return steps.find((s) => s.stepIndex === stepIndex)\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n const nowIso = new Date(this.now()).toISOString()\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n const rec: StepRecord = {\n ...prior,\n attempts: prior.attempts + 1,\n status: 'running',\n startedAt: nowIso,\n error: undefined,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n const rec: StepRecord = {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n await this.appendStep(input.runId, rec)\n // Bump run.stepCount opportunistically.\n const record = await this.readRun(input.runId)\n record.stepCount = Math.max(record.stepCount, input.stepIndex + 1)\n record.updatedAt = nowIso\n await this.writeRun(record)\n return rec\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n if (!prior) {\n throw new Error(\n `durable-runs: completeStep called before beginStep (step ${input.stepIndex})`,\n )\n }\n const nowIso = new Date(this.now()).toISOString()\n const rec: StepRecord = {\n ...prior,\n status: 'completed',\n result: input.result,\n completedAt: nowIso,\n error: undefined,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const all = await this.readSteps(input.runId, { includeFailed: true, includeRunning: true })\n const prior = all.find((s) => s.stepIndex === input.stepIndex)\n if (!prior) {\n throw new Error(`durable-runs: failStep called before beginStep (step ${input.stepIndex})`)\n }\n const nowIso = new Date(this.now()).toISOString()\n const rec: StepRecord = {\n ...prior,\n status: 'failed',\n error: input.error,\n completedAt: nowIso,\n }\n await this.appendStep(input.runId, rec)\n await this.bumpRunUpdated(input.runId, nowIso)\n return rec\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const record = await this.readRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n record.status = input.status\n record.outcome = input.outcome\n record.completedAt = nowIso\n record.updatedAt = nowIso\n const lease = await this.readLeaseSafe(input.runId)\n if (lease && lease.workerId === input.workerId) {\n record.leaseHolderId = undefined\n record.leaseExpiresAt = undefined\n await this.writeLease(input.runId, null)\n }\n await this.writeRun(record)\n return record\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const existing = await this.loadEvent(input.runId, input.key)\n if (existing) return { accepted: false, record: existing }\n const rec: EventRecord = {\n runId: input.runId,\n key: input.key,\n payload: input.payload,\n emittedAt: new Date(this.now()).toISOString(),\n }\n await appendFile(\n join(this.runDir(input.runId), 'events.jsonl'),\n `${JSON.stringify(rec)}\\n`,\n 'utf8',\n )\n return { accepted: true, record: rec }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const path = join(this.runDir(runId), 'events.jsonl')\n if (!existsSync(path)) return undefined\n const content = await readFile(path, 'utf8')\n for (const line of content.split('\\n').reverse()) {\n if (!line) continue\n const rec = JSON.parse(line) as EventRecord\n if (rec.key === key) return rec\n }\n return undefined\n }\n\n async close(): Promise<void> {\n // No persistent handles to close.\n }\n\n /** @internal — used by tests to list runs in the store. */\n async _listRunIds(): Promise<string[]> {\n if (!existsSync(this.root)) return []\n const entries = await readdir(this.root, { withFileTypes: true })\n return entries.filter((e) => e.isDirectory()).map((e) => e.name)\n }\n\n // ── internals ──────────────────────────────────────────────────────\n\n private runDir(runId: string): string {\n return join(this.root, runId)\n }\n\n private async readRun(runId: string): Promise<RunRecord> {\n const path = join(this.runDir(runId), 'run.json')\n const content = await readFile(path, 'utf8')\n return JSON.parse(content) as RunRecord\n }\n\n private async writeRun(record: RunRecord): Promise<void> {\n const dir = this.runDir(record.runId)\n const path = join(dir, 'run.json')\n const tmp = `${path}.tmp`\n await writeFile(tmp, JSON.stringify(record, null, 2), 'utf8')\n await rename(tmp, path)\n }\n\n private async readLeaseSafe(runId: string): Promise<LeaseFile | undefined> {\n const path = join(this.runDir(runId), 'lease.json')\n if (!existsSync(path)) return undefined\n try {\n const content = await readFile(path, 'utf8')\n if (!content.trim()) return undefined\n return JSON.parse(content) as LeaseFile\n } catch {\n return undefined\n }\n }\n\n private async writeLease(runId: string, lease: LeaseFile | null): Promise<void> {\n const path = join(this.runDir(runId), 'lease.json')\n const tmp = `${path}.tmp`\n await writeFile(tmp, lease ? JSON.stringify(lease) : '', 'utf8')\n await rename(tmp, path)\n }\n\n private async readSteps(\n runId: string,\n opts: { includeFailed?: boolean; includeRunning?: boolean } = {},\n ): Promise<StepRecord[]> {\n const path = join(this.runDir(runId), 'steps.jsonl')\n if (!existsSync(path)) return []\n const content = await readFile(path, 'utf8')\n // Append-only log: later writes for the same stepIndex override earlier\n // ones. Walk forward and keep the latest per index.\n const latest = new Map<number, StepRecord>()\n for (const line of content.split('\\n')) {\n if (!line) continue\n const rec = JSON.parse(line) as StepRecord\n latest.set(rec.stepIndex, rec)\n }\n const out = [...latest.values()].sort((a, b) => a.stepIndex - b.stepIndex)\n return out.filter((s) => {\n if (s.status === 'completed') return true\n if (s.status === 'failed') return opts.includeFailed ?? false\n if (s.status === 'running') return opts.includeRunning ?? false\n return false\n })\n }\n\n private async appendStep(runId: string, rec: StepRecord): Promise<void> {\n await appendFile(join(this.runDir(runId), 'steps.jsonl'), `${JSON.stringify(rec)}\\n`, 'utf8')\n }\n\n private async bumpRunUpdated(runId: string, nowIso: string): Promise<void> {\n const record = await this.readRun(runId)\n record.updatedAt = nowIso\n await this.writeRun(record)\n }\n}\n","/**\n * In-memory DurableRunStore for dev + tests. Single-process. All state lives\n * in maps. Lease enforcement is real (Date.now() vs lease deadline) so the\n * crash-recovery + multi-worker race tests run identically against this and\n * the file-system / D1 stores.\n */\n\nimport { manifestHash } from './identity'\nimport type {\n DurableRunManifest,\n DurableRunStore,\n EventRecord,\n RunOutcome,\n RunRecord,\n StepError,\n StepKind,\n StepRecord,\n} from './types'\nimport {\n DurableRunDivergenceError,\n DurableRunInputMismatchError,\n DurableRunLeaseHeldError,\n} from './types'\n\nconst DEFAULT_LEASE_MS = 30_000\n\ninterface RunState {\n record: RunRecord\n steps: Map<number, StepRecord>\n events: Map<string, EventRecord>\n}\n\nexport class InMemoryDurableRunStore implements DurableRunStore {\n private readonly runs = new Map<string, RunState>()\n /** Override for tests — defaults to Date.now(). */\n public now: () => number = () => Date.now()\n\n async startOrResume(input: {\n runId: string\n manifest: DurableRunManifest\n workerId: string\n leaseMs?: number\n }): ReturnType<DurableRunStore['startOrResume']> {\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const hash = manifestHash(input.manifest)\n const nowMs = this.now()\n const nowIso = new Date(nowMs).toISOString()\n const leaseExpiresMs = nowMs + leaseMs\n const leaseExpiresAt = new Date(leaseExpiresMs).toISOString()\n\n let state = this.runs.get(input.runId)\n if (!state) {\n const record: RunRecord = {\n runId: input.runId,\n manifestHash: hash,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n status: 'running',\n createdAt: nowIso,\n updatedAt: nowIso,\n leaseHolderId: input.workerId,\n leaseExpiresAt,\n stepCount: 0,\n }\n state = { record, steps: new Map(), events: new Map() }\n this.runs.set(input.runId, state)\n return { run: { ...record }, completedSteps: [], leaseExpiresAt }\n }\n\n if (state.record.manifestHash !== hash) {\n throw new DurableRunInputMismatchError(\n `runId ${input.runId} exists with a different manifest hash; refuse to corrupt prior steps`,\n )\n }\n // Lease check — held by another worker with a non-expired lease.\n const leaseStillLive =\n state.record.leaseHolderId !== undefined &&\n state.record.leaseHolderId !== input.workerId &&\n state.record.leaseExpiresAt !== undefined &&\n new Date(state.record.leaseExpiresAt).getTime() > nowMs\n if (leaseStillLive) {\n throw new DurableRunLeaseHeldError(\n `runId ${input.runId} is leased by ${state.record.leaseHolderId} until ${state.record.leaseExpiresAt}`,\n )\n }\n // Acquire / renew.\n state.record.leaseHolderId = input.workerId\n state.record.leaseExpiresAt = leaseExpiresAt\n state.record.status =\n state.record.status === 'completed' || state.record.status === 'failed'\n ? state.record.status\n : 'running'\n state.record.updatedAt = nowIso\n const completed = [...state.steps.values()]\n .filter((s) => s.status === 'completed')\n .sort((a, b) => a.stepIndex - b.stepIndex)\n return {\n run: { ...state.record },\n completedSteps: completed.map((s) => ({ ...s })),\n leaseExpiresAt,\n }\n }\n\n async renewLease(input: {\n runId: string\n workerId: string\n leaseMs?: number\n }): Promise<{ ok: boolean; leaseExpiresAt?: string }> {\n const state = this.runs.get(input.runId)\n if (!state) return { ok: false }\n const nowMs = this.now()\n if (state.record.leaseHolderId !== input.workerId) {\n // Lease lapsed — another worker may have taken over.\n if (state.record.leaseExpiresAt && new Date(state.record.leaseExpiresAt).getTime() > nowMs) {\n return { ok: false }\n }\n }\n const leaseExpiresMs = nowMs + (input.leaseMs ?? DEFAULT_LEASE_MS)\n const leaseExpiresAt = new Date(leaseExpiresMs).toISOString()\n state.record.leaseHolderId = input.workerId\n state.record.leaseExpiresAt = leaseExpiresAt\n state.record.updatedAt = new Date(nowMs).toISOString()\n return { ok: true, leaseExpiresAt }\n }\n\n async loadStep(runId: string, stepIndex: number): Promise<StepRecord | undefined> {\n const state = this.runs.get(runId)\n return state ? cloneStep(state.steps.get(stepIndex)) : undefined\n }\n\n async beginStep(input: {\n runId: string\n stepIndex: number\n intent: string\n kind: StepKind\n inputHash: string\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n const prior = state.steps.get(input.stepIndex)\n if (prior) {\n if (prior.intent !== input.intent) {\n throw new DurableRunDivergenceError(\n `step ${input.stepIndex}: intent changed across replays ('${prior.intent}' -> '${input.intent}')`,\n )\n }\n // Begin called again — bump attempts. A prior failed or running step\n // can re-execute; a prior completed step would be filtered before begin\n // is called (the runner short-circuits on cached results).\n prior.attempts += 1\n prior.status = 'running'\n prior.startedAt = nowIso\n prior.error = undefined\n state.record.updatedAt = nowIso\n return cloneStep(prior)!\n }\n const rec: StepRecord = {\n runId: input.runId,\n stepIndex: input.stepIndex,\n intent: input.intent,\n kind: input.kind,\n inputHash: input.inputHash,\n status: 'running',\n attempts: 1,\n startedAt: nowIso,\n }\n state.steps.set(input.stepIndex, rec)\n state.record.stepCount = Math.max(state.record.stepCount, input.stepIndex + 1)\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async completeStep(input: {\n runId: string\n stepIndex: number\n result: unknown\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const rec = state.steps.get(input.stepIndex)\n if (!rec) {\n throw new Error(\n `durable-runs: completeStep called before beginStep (step ${input.stepIndex})`,\n )\n }\n const nowIso = new Date(this.now()).toISOString()\n rec.status = 'completed'\n rec.result = input.result\n rec.completedAt = nowIso\n rec.error = undefined\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async failStep(input: {\n runId: string\n stepIndex: number\n error: StepError\n }): Promise<StepRecord> {\n const state = this.requireRun(input.runId)\n const rec = state.steps.get(input.stepIndex)\n if (!rec) {\n throw new Error(`durable-runs: failStep called before beginStep (step ${input.stepIndex})`)\n }\n const nowIso = new Date(this.now()).toISOString()\n rec.status = 'failed'\n rec.error = input.error\n rec.completedAt = nowIso\n state.record.updatedAt = nowIso\n return cloneStep(rec)!\n }\n\n async endRun(input: {\n runId: string\n workerId: string\n status: 'completed' | 'failed'\n outcome?: RunOutcome\n }): Promise<RunRecord> {\n const state = this.requireRun(input.runId)\n const nowIso = new Date(this.now()).toISOString()\n state.record.status = input.status\n state.record.outcome = input.outcome\n state.record.completedAt = nowIso\n state.record.updatedAt = nowIso\n // Release lease iff caller still holds it.\n if (state.record.leaseHolderId === input.workerId) {\n state.record.leaseHolderId = undefined\n state.record.leaseExpiresAt = undefined\n }\n return { ...state.record }\n }\n\n async emitEvent(input: {\n runId: string\n key: string\n payload: unknown\n }): ReturnType<DurableRunStore['emitEvent']> {\n const state = this.requireRun(input.runId)\n const existing = state.events.get(input.key)\n if (existing) {\n return { accepted: false, record: { ...existing } }\n }\n const rec: EventRecord = {\n runId: input.runId,\n key: input.key,\n payload: input.payload,\n emittedAt: new Date(this.now()).toISOString(),\n }\n state.events.set(input.key, rec)\n return { accepted: true, record: { ...rec } }\n }\n\n async loadEvent(runId: string, key: string): Promise<EventRecord | undefined> {\n const state = this.runs.get(runId)\n if (!state) return undefined\n const rec = state.events.get(key)\n return rec ? { ...rec } : undefined\n }\n\n async close(): Promise<void> {\n this.runs.clear()\n }\n\n // ── test helpers ───────────────────────────────────────────────────\n /** @internal — used by tests to inspect lease metadata. */\n _inspect(runId: string): RunRecord | undefined {\n const s = this.runs.get(runId)\n return s ? { ...s.record } : undefined\n }\n\n /** @internal — used by tests to simulate lease expiry. */\n _expireLease(runId: string): void {\n const s = this.runs.get(runId)\n if (s) {\n s.record.leaseHolderId = undefined\n s.record.leaseExpiresAt = undefined\n }\n }\n\n private requireRun(runId: string): RunState {\n const s = this.runs.get(runId)\n if (!s) {\n throw new Error(`durable-runs: run ${runId} not found (must call startOrResume first)`)\n }\n return s\n }\n}\n\nfunction cloneStep(rec: StepRecord | undefined): StepRecord | undefined {\n if (!rec) return undefined\n return { ...rec, error: rec.error ? { ...rec.error } : undefined }\n}\n","/**\n * Durable runner — wraps a user-supplied async function in checkpoint /\n * resume / lease semantics. The user writes plain async code, awaiting\n * `ctx.step(intent, fn)` boundaries. On worker crash, the next caller with\n * the same `runId` skips completed steps and resumes from the first unfinished\n * one.\n *\n * Invariants:\n *\n * - Step positions are derived from a monotonic counter on the ctx. The\n * same intent at position N is the same step across replays. If the user\n * reorders steps, position N changes intent and we raise\n * DurableRunDivergenceError fail-loud.\n *\n * - `ctx.now()` and `ctx.uuid()` are checkpointed as zero-input logic steps\n * with kind='deterministic'. On replay they return the recorded value.\n *\n * - `awaitEvent` writes a 'event' step that records the event payload on\n * first awaited completion. On replay, the cached payload returns\n * synchronously. If the event has not been emitted and the runner is in\n * a fresh execution, it polls the store until timeout.\n *\n * - Lease renewal happens on a wall-clock interval (every leaseMs/3). If\n * the store reports a lost lease, the runner aborts the current step\n * execution and throws — letting whichever worker holds the lease pick\n * up. Committed steps survive.\n */\n\nimport { canonicalHash, deriveWorkerId, manifestHash } from './identity'\nimport type {\n DurableRunManifest,\n DurableRunStore,\n RunOutcome,\n RunRecord,\n StepKind,\n StepRecord,\n} from './types'\nimport { DurableAwaitEventTimeoutError, DurableRunDivergenceError } from './types'\n\nexport interface DurableContext {\n readonly runId: string\n readonly projectId: string\n readonly scenarioId?: string\n\n /**\n * Execute a checkpointed step. The step is identified by its **position**\n * (monotonic counter on this ctx); `intent` is a human-readable label that\n * must stay stable across replays.\n *\n * On first execution: runs `fn`, records the result, returns it.\n * On replay: returns the recorded result WITHOUT calling `fn`.\n *\n * The `inputFingerprint` (optional) lets the runner detect \"same intent,\n * different inputs\" — it gets hashed and compared. If you don't supply\n * one, drift is allowed (input not checked).\n */\n step<T>(\n intent: string,\n fn: () => Promise<T>,\n opts?: { kind?: StepKind; inputFingerprint?: unknown },\n ): Promise<T>\n\n /** Race-free first-emit-wins event wait. */\n awaitEvent<T = unknown>(key: string, opts?: { timeoutMs?: number; pollMs?: number }): Promise<T>\n\n /** Emit an event. First emit wins. Subsequent emits no-op. */\n emitEvent(key: string, payload: unknown): Promise<{ accepted: boolean }>\n\n /** Deterministic clock — checkpointed once per call. */\n now(): Promise<Date>\n\n /** Deterministic uuid — checkpointed once per call. */\n uuid(): Promise<string>\n}\n\nconst DEFAULT_LEASE_MS = 30_000\nconst DEFAULT_AWAIT_POLL_MS = 250\n\nexport interface RunDurableInput<TResult> {\n runId: string\n manifest: DurableRunManifest\n store: DurableRunStore\n workerId?: string\n leaseMs?: number\n /** Total time budget for the run. Used for awaitEvent timeouts; runner\n * itself doesn't kill long-running steps (the step fn must respect\n * AbortSignal if it cares). */\n signal?: AbortSignal\n taskFn: (ctx: DurableContext) => Promise<TResult>\n /** Default outcome on successful completion. */\n defaultOutcome?: RunOutcome\n}\n\nexport interface RunDurableResult<TResult> {\n result: TResult\n record: RunRecord\n /** All steps captured this run (replayed + freshly executed). */\n steps: ReadonlyArray<StepRecord>\n}\n\nexport async function runDurable<TResult>(\n input: RunDurableInput<TResult>,\n): Promise<RunDurableResult<TResult>> {\n const workerId = input.workerId ?? deriveWorkerId()\n const leaseMs = input.leaseMs ?? DEFAULT_LEASE_MS\n const { completedSteps } = await input.store.startOrResume({\n runId: input.runId,\n manifest: input.manifest,\n workerId,\n leaseMs,\n })\n\n // Pre-compute a position-indexed view of prior steps for O(1) replay\n // lookups. We DON'T trust that the store returned them in order — sort.\n const priorByIndex = new Map<number, StepRecord>()\n for (const s of completedSteps) priorByIndex.set(s.stepIndex, s)\n\n const collected: StepRecord[] = [...completedSteps].sort((a, b) => a.stepIndex - b.stepIndex)\n\n // Lease renewal heartbeat — best-effort. Errors are surfaced via\n // `leaseLost` so steps can short-circuit.\n let leaseLost = false\n const heartbeatIntervalMs = Math.max(1_000, Math.floor(leaseMs / 3))\n const heartbeat = setInterval(() => {\n void input.store\n .renewLease({ runId: input.runId, workerId, leaseMs })\n .then((res) => {\n if (!res.ok) leaseLost = true\n })\n .catch(() => {\n leaseLost = true\n })\n }, heartbeatIntervalMs)\n // unref() so the heartbeat doesn't keep the process alive on test exit.\n if (typeof heartbeat.unref === 'function') heartbeat.unref()\n\n let positionCounter = 0\n\n const ctx: DurableContext = {\n runId: input.runId,\n projectId: input.manifest.projectId,\n scenarioId: input.manifest.scenarioId,\n async step<T>(\n intent: string,\n fn: () => Promise<T>,\n opts?: { kind?: StepKind; inputFingerprint?: unknown },\n ): Promise<T> {\n checkAbortAndLease(input.signal, leaseLost)\n const stepIndex = positionCounter++\n const prior = priorByIndex.get(stepIndex)\n const inputHash =\n opts?.inputFingerprint !== undefined ? canonicalHash(opts.inputFingerprint) : ''\n if (prior && prior.status === 'completed') {\n // Replay path — return cached result.\n if (prior.intent !== intent) {\n throw new DurableRunDivergenceError(\n `step ${stepIndex}: intent changed across replays ('${prior.intent}' -> '${intent}')`,\n )\n }\n return prior.result as T\n }\n // Begin a fresh attempt (either net-new or retry of a failed step).\n const begun = await input.store.beginStep({\n runId: input.runId,\n stepIndex,\n intent,\n kind: opts?.kind ?? 'logic',\n inputHash,\n })\n try {\n const result = await fn()\n const completed = await input.store.completeStep({\n runId: input.runId,\n stepIndex,\n result,\n })\n upsertCollected(collected, completed)\n priorByIndex.set(stepIndex, completed)\n return result\n } catch (err) {\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n throw err\n } finally {\n // The `begun` reference suppresses \"unused\" warnings without an\n // eslint-disable comment.\n void begun\n }\n },\n async awaitEvent<T>(key: string, opts?: { timeoutMs?: number; pollMs?: number }): Promise<T> {\n const stepIndex = positionCounter++\n const prior = priorByIndex.get(stepIndex)\n if (prior && prior.status === 'completed') {\n if (prior.intent !== `event:${key}`) {\n throw new DurableRunDivergenceError(\n `step ${stepIndex}: awaitEvent key changed across replays`,\n )\n }\n return prior.result as T\n }\n const beginAt = Date.now()\n const timeoutMs = opts?.timeoutMs ?? 60_000\n const pollMs = opts?.pollMs ?? DEFAULT_AWAIT_POLL_MS\n await input.store.beginStep({\n runId: input.runId,\n stepIndex,\n intent: `event:${key}`,\n kind: 'event',\n inputHash: '',\n })\n try {\n for (;;) {\n checkAbortAndLease(input.signal, leaseLost)\n const evt = await input.store.loadEvent(input.runId, key)\n if (evt) {\n const completed = await input.store.completeStep({\n runId: input.runId,\n stepIndex,\n result: evt.payload,\n })\n upsertCollected(collected, completed)\n priorByIndex.set(stepIndex, completed)\n return evt.payload as T\n }\n if (Date.now() - beginAt > timeoutMs) {\n const err = new DurableAwaitEventTimeoutError(\n `awaitEvent('${key}') timed out after ${timeoutMs}ms`,\n )\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n throw err\n }\n await sleep(pollMs, input.signal)\n }\n } catch (err) {\n // Any non-timeout error: mark failed (if not already), surface.\n if (!(err instanceof DurableAwaitEventTimeoutError)) {\n const existing = priorByIndex.get(stepIndex)\n if (!existing || existing.status !== 'failed') {\n const failed = await input.store.failStep({\n runId: input.runId,\n stepIndex,\n error: toStepError(err),\n })\n upsertCollected(collected, failed)\n priorByIndex.set(stepIndex, failed)\n }\n }\n throw err\n }\n },\n async emitEvent(key: string, payload: unknown): Promise<{ accepted: boolean }> {\n const res = await input.store.emitEvent({ runId: input.runId, key, payload })\n return { accepted: res.accepted }\n },\n async now(): Promise<Date> {\n const v = await this.step(`deterministic:now`, async () => new Date().toISOString(), {\n kind: 'deterministic',\n })\n return new Date(v)\n },\n async uuid(): Promise<string> {\n return this.step(`deterministic:uuid`, async () => cryptoRandomUuid(), {\n kind: 'deterministic',\n })\n },\n }\n\n try {\n const result = await input.taskFn(ctx)\n const finalRecord = await input.store.endRun({\n runId: input.runId,\n workerId,\n status: 'completed',\n outcome: input.defaultOutcome,\n })\n return { result, record: finalRecord, steps: collected }\n } catch (err) {\n const finalRecord = await input.store.endRun({\n runId: input.runId,\n workerId,\n status: 'failed',\n outcome: {\n ...input.defaultOutcome,\n notes: err instanceof Error ? err.message : String(err),\n },\n })\n void finalRecord\n throw err\n } finally {\n clearInterval(heartbeat)\n }\n}\n\nfunction checkAbortAndLease(signal: AbortSignal | undefined, leaseLost: boolean): void {\n if (signal?.aborted) throw signal.reason ?? new Error('aborted')\n if (leaseLost) throw new Error('durable-runs: lease lost; another worker has taken over this run')\n}\n\nfunction upsertCollected(list: StepRecord[], rec: StepRecord): void {\n const i = list.findIndex((s) => s.stepIndex === rec.stepIndex)\n if (i === -1) list.push(rec)\n else list[i] = rec\n}\n\nfunction toStepError(err: unknown): { message: string; code?: string; stack?: string } {\n if (err instanceof Error) {\n return {\n message: err.message,\n code: (err as { code?: string }).code,\n stack: err.stack,\n }\n }\n return { message: String(err) }\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\nfunction cryptoRandomUuid(): string {\n // Defensive: globalThis.crypto.randomUUID may not be available in older\n // Node — fall back to a manual v4 derivation.\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return globalThis.crypto.randomUUID()\n }\n const bytes = new Uint8Array(16)\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256)\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n}\n\n// Re-export for callers that want manifestHash without reaching into identity.\nexport { manifestHash }\n","/**\n * The durable-runs SQL schema as a string constant. Inlined so consumers\n * (Cloudflare Workers via D1) can apply it without bundling a `.sql` file:\n *\n * import { DURABLE_SCHEMA_SQL } from '@tangle-network/agent-runtime'\n * await env.DB.exec(DURABLE_SCHEMA_SQL)\n *\n * The canonical source is `src/durable/schema.sql` — this string MUST stay\n * byte-identical to it. The build does not copy `.sql` files into `dist/`,\n * so the constant is the only path consumers have. A unit test asserts the\n * two stay in sync (`durable-schema.test.ts`).\n *\n * `DURABLE_SCHEMA_VERSION` reflects the latest migration version applied by\n * this string. Bump it on every backwards-incompatible change AND add a new\n * migration entry to durable_schema_info instead of mutating prior rows.\n */\n\nexport const DURABLE_SCHEMA_VERSION = 1\n\nexport const DURABLE_SCHEMA_SQL = `-- Durable-run substrate — versioned schema for D1 / SQLite.\n--\n-- Apply once per database. Subsequent migrations append; never rewrite a\n-- prior version. See \\`durable_schema_info\\` for the migration trail.\n--\n-- Concurrency notes for D1:\n-- - SQLite supports UNIQUE constraints for first-emit-wins (\\`durable_events\\`\n-- PK is (run_id, key) — duplicate insert raises, caller treats as \"already\n-- emitted\").\n-- - Lease takeover happens via a conditional UPDATE: we only claim the lease\n-- if (lease_holder_id IS NULL OR lease_expires_at < :now) — atomic under\n-- SQLite's row-level locking.\n-- - All timestamps stored as ISO-8601 TEXT for cross-platform consistency.\n-- - \\`result_json\\` / \\`error_json\\` / \\`outcome_json\\` / \\`payload_json\\` are\n-- JSON-encoded TEXT; the application enforces canonical-JSON discipline at\n-- the boundary so the store stays type-agnostic.\n\nCREATE TABLE IF NOT EXISTS durable_schema_info (\n version INTEGER PRIMARY KEY,\n applied_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS durable_runs (\n run_id TEXT PRIMARY KEY,\n manifest_hash TEXT NOT NULL,\n project_id TEXT NOT NULL,\n scenario_id TEXT,\n status TEXT NOT NULL CHECK (status IN ('pending','running','completed','failed','suspended')),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n completed_at TEXT,\n lease_holder_id TEXT,\n lease_expires_at TEXT,\n outcome_json TEXT,\n step_count INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE INDEX IF NOT EXISTS idx_durable_runs_project_status ON durable_runs(project_id, status);\nCREATE INDEX IF NOT EXISTS idx_durable_runs_lease_expires ON durable_runs(lease_expires_at);\n\nCREATE TABLE IF NOT EXISTS durable_steps (\n run_id TEXT NOT NULL,\n step_index INTEGER NOT NULL,\n intent TEXT NOT NULL,\n kind TEXT NOT NULL,\n input_hash TEXT NOT NULL DEFAULT '',\n status TEXT NOT NULL CHECK (status IN ('pending','running','completed','failed')),\n attempts INTEGER NOT NULL DEFAULT 0,\n result_json TEXT,\n error_json TEXT,\n started_at TEXT,\n completed_at TEXT,\n PRIMARY KEY (run_id, step_index)\n);\n\nCREATE INDEX IF NOT EXISTS idx_durable_steps_status ON durable_steps(run_id, status);\n\nCREATE TABLE IF NOT EXISTS durable_events (\n run_id TEXT NOT NULL,\n key TEXT NOT NULL,\n payload_json TEXT,\n emitted_at TEXT NOT NULL,\n PRIMARY KEY (run_id, key)\n);\n\nINSERT OR IGNORE INTO durable_schema_info (version, applied_at)\nVALUES (1, strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));\n`\n","/**\n * Cloudflare Workflows integration for the durable-run substrate.\n *\n * Two valid deployment patterns on Cloudflare:\n *\n * A. **Plain Worker + D1DurableRunStore.** Each request invokes\n * `runDurable(...)` directly against a D1 binding. Survives worker\n * isolate restarts; lease takeover happens via D1 row-level\n * conditional UPDATE. The default path; no Workflows binding needed.\n *\n * B. **Cloudflare Workflows entrypoint.** Wrap an entire `runDurable(...)`\n * call inside a single Workflow `step.do(...)`. Workflows gives you\n * retry-on-throw with platform-managed exponential backoff and\n * survives full Workers deploy rolls. Use it when the task can take\n * minutes to hours, or when you want the Workflows dashboard for\n * observability. Inside the step, `runDurable` still uses D1 for\n * step-level checkpoints — so a half-completed run resumes from\n * its last checkpoint on retry rather than restarting from scratch.\n *\n * This module provides the surface for pattern B: a thin helper that\n * converts a Workflows `WorkflowStep` into a `DurableContext`. We do not\n * take a runtime dep on `cloudflare:workers` — the integration is purely\n * structural typing.\n *\n * Example (pattern B):\n *\n * import { WorkflowEntrypoint } from 'cloudflare:workers'\n * import { runOnWorkflowStep } from '@tangle-network/agent-runtime'\n *\n * export class LegalChatWorkflow extends WorkflowEntrypoint<Env, ChatParams> {\n * async run(event, step) {\n * return runOnWorkflowStep(step, {\n * workflowName: 'legal-chat',\n * taskFn: async (ctx) => {\n * const ready = await ctx.step('readiness', () => probeKnowledge(...))\n * const answer = await ctx.step('llm:turn-1', () => callLlm(...))\n * const shipped = await ctx.awaitEvent('shipped', { timeoutMs: 5 * 60_000 })\n * return { answer, shipped }\n * },\n * })\n * }\n * }\n *\n * Step ordering, replay semantics, and divergence detection inside the\n * `taskFn` are inherited from Cloudflare's Workflows engine — we\n * intentionally do NOT layer a second durable store inside this path.\n * Pick pattern A or pattern B per agent; do not mix.\n */\n\nimport type { DurableContext } from './runner'\n\n/**\n * Structural subset of Cloudflare's `WorkflowStep`. Mirrors the public surface\n * documented at https://developers.cloudflare.com/workflows/build/. Defined\n * here so this module imposes zero `cloudflare:workers` runtime dependency.\n */\nexport interface WorkflowStepLike {\n do<T>(name: string, opts: WorkflowStepConfig, fn: () => Promise<T>): Promise<T>\n do<T>(name: string, fn: () => Promise<T>): Promise<T>\n sleep(name: string, duration: string | number): Promise<void>\n waitForEvent<T = unknown>(\n name: string,\n opts: { type: string; timeout?: string },\n ): Promise<{\n payload: T\n timestamp: number\n type: string\n }>\n}\n\nexport interface WorkflowStepConfig {\n retries?: {\n limit: number\n delay: string | number\n backoff?: 'constant' | 'linear' | 'exponential'\n }\n timeout?: string | number\n}\n\nexport interface RunOnWorkflowStepInput<TResult> {\n /** Logical workflow name; used as a prefix on step ids for filtering. */\n workflowName: string\n /** User task — same shape as runDurable's taskFn. */\n taskFn: (ctx: DurableContext) => Promise<TResult>\n /** Optional per-step retry / timeout policy applied to ctx.step calls. */\n stepConfig?: WorkflowStepConfig\n /** Optional clock — defaults to Date.now. */\n now?: () => number\n}\n\n/**\n * Adapt a Cloudflare `WorkflowStep` into a `DurableContext` and run a task.\n *\n * Every `ctx.step(intent, fn)` becomes `step.do(<name>, fn)` with stable\n * names — Workflows checkpoints + replays based on step name + position,\n * matching our model.\n *\n * `ctx.awaitEvent(key)` becomes `step.waitForEvent(key, { type: key })`.\n * Caller is responsible for emitting from the platform side (e.g. via the\n * Workflows REST API or a sibling worker that publishes events).\n *\n * `ctx.now()` and `ctx.uuid()` go through `step.do` so the values are\n * captured in the platform's checkpoint state and remain stable across\n * replay — same invariant as our own stores.\n */\nexport async function runOnWorkflowStep<TResult>(\n workflowStep: WorkflowStepLike,\n input: RunOnWorkflowStepInput<TResult>,\n): Promise<TResult> {\n const stepCfg = input.stepConfig\n let counter = 0\n const stepName = (intent: string) => `${input.workflowName}/${counter++}:${intent}`\n\n const ctx: DurableContext = {\n runId: `cf-workflow:${input.workflowName}`,\n projectId: input.workflowName,\n async step<T>(intent: string, fn: () => Promise<T>): Promise<T> {\n const name = stepName(intent)\n if (stepCfg) {\n return workflowStep.do<T>(name, stepCfg, fn)\n }\n return workflowStep.do<T>(name, fn)\n },\n async awaitEvent<T = unknown>(key: string, opts?: { timeoutMs?: number }): Promise<T> {\n const timeout = opts?.timeoutMs ? `${Math.ceil(opts.timeoutMs / 1000)}s` : undefined\n const ev = await workflowStep.waitForEvent<T>(stepName(`event:${key}`), {\n type: key,\n timeout,\n })\n return ev.payload\n },\n async emitEvent(): Promise<{ accepted: boolean }> {\n // Workflows events are emitted from OUTSIDE the workflow (via the\n // platform API). A workflow that emits its own events is an\n // anti-pattern — surface that fail-loud rather than silently no-op.\n throw new Error(\n 'runOnWorkflowStep: ctx.emitEvent is not available inside a Workflows entrypoint. ' +\n 'Emit from the sibling worker that drives the workflow.',\n )\n },\n async now(): Promise<Date> {\n const iso = await this.step('deterministic:now', async () => new Date().toISOString())\n return new Date(iso)\n },\n async uuid(): Promise<string> {\n return this.step('deterministic:uuid', async () => {\n if (typeof globalThis.crypto?.randomUUID === 'function') {\n return globalThis.crypto.randomUUID()\n }\n // Cloudflare runtime always has Web Crypto; fallback is defensive.\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n })\n },\n }\n\n return input.taskFn(ctx)\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 => 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 * 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 metadata: options.includeMetadata ? event.metadata : undefined,\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 '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","finalText","nowIso","record","DEFAULT_LEASE_MS","nowIso","record","rec","DEFAULT_LEASE_MS","nowIso","DEFAULT_LEASE_MS","sleep","counter","counter"]}
|