@tangle-network/agent-runtime 0.101.0 → 0.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/agent.js +4 -3
  3. package/dist/agent.js.map +1 -1
  4. package/dist/chunk-2VZYRB55.js +834 -0
  5. package/dist/chunk-2VZYRB55.js.map +1 -0
  6. package/dist/{chunk-Y3SRWZMP.js → chunk-AYU35OTU.js} +2 -2
  7. package/dist/chunk-DI677IPX.js +200 -0
  8. package/dist/chunk-DI677IPX.js.map +1 -0
  9. package/dist/{chunk-HZDEXTSL.js → chunk-IKGCKPDX.js} +2 -833
  10. package/dist/chunk-IKGCKPDX.js.map +1 -0
  11. package/dist/{chunk-WYC2XJF2.js → chunk-KSBUSEUA.js} +2 -2
  12. package/dist/{chunk-UQ6PNNXM.js → chunk-KVJQV342.js} +5 -3
  13. package/dist/{chunk-UQ6PNNXM.js.map → chunk-KVJQV342.js.map} +1 -1
  14. package/dist/{chunk-FXF2OL34.js → chunk-MAONWP4R.js} +2 -2
  15. package/dist/{chunk-SGQ4YIQW.js → chunk-N2CEE5Q3.js} +3 -3
  16. package/dist/{chunk-VOPHC4LB.js → chunk-RJPQLUDA.js} +5 -187
  17. package/dist/chunk-RJPQLUDA.js.map +1 -0
  18. package/dist/{chunk-LV6WCT43.js → chunk-TA4RBJLE.js} +3 -3
  19. package/dist/index.js +9 -7
  20. package/dist/index.js.map +1 -1
  21. package/dist/intelligence.js +8 -5
  22. package/dist/intelligence.js.map +1 -1
  23. package/dist/knowledge.js +6 -4
  24. package/dist/loop-runner-bin.js +5 -4
  25. package/dist/loops.js +4 -3
  26. package/dist/mcp/bin.js +4 -3
  27. package/dist/mcp/bin.js.map +1 -1
  28. package/dist/mcp/index.js +6 -5
  29. package/dist/mcp/index.js.map +1 -1
  30. package/dist/testing.d.ts +6 -0
  31. package/dist/testing.js +2596 -0
  32. package/dist/testing.js.map +1 -0
  33. package/package.json +9 -2
  34. package/dist/chunk-HZDEXTSL.js.map +0 -1
  35. package/dist/chunk-VOPHC4LB.js.map +0 -1
  36. /package/dist/{chunk-Y3SRWZMP.js.map → chunk-AYU35OTU.js.map} +0 -0
  37. /package/dist/{chunk-WYC2XJF2.js.map → chunk-KSBUSEUA.js.map} +0 -0
  38. /package/dist/{chunk-FXF2OL34.js.map → chunk-MAONWP4R.js.map} +0 -0
  39. /package/dist/{chunk-SGQ4YIQW.js.map → chunk-N2CEE5Q3.js.map} +0 -0
  40. /package/dist/{chunk-LV6WCT43.js.map → chunk-TA4RBJLE.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/durable/chat-engine.ts","../src/durable/execution-handle.ts","../src/improvement/build-prompts.ts","../src/improvement/mcp-serve-verifier.ts","../src/improvement/profile-diff-proposer.ts","../src/improvement/reflective-generator.ts","../src/readiness.ts","../src/resolve-agent-backend.ts","../src/run.ts","../src/runtime-run.ts","../src/sse.ts","../src/tool-loop.ts"],"sourcesContent":["/**\n * `handleChatTurn` — framework-neutral chat-turn HTTP orchestrator.\n * Owns the NDJSON `ChatStreamEvent` line protocol, the `session.run.*`\n * lifecycle vocabulary, and the persist / post-process / trace-flush\n * hook order. Returns a `ReadableStream` body the product hands to its\n * platform `Response`.\n *\n * Execution durability is the substrate's concern: `box.streamPrompt`\n * auto-reconnects in-call; cross-process reconnect via `X-Execution-ID`\n * is the product's job. The producer this engine wraps already speaks\n * that protocol — the engine just frames the events.\n *\n * Hooks (`ChatTurnHooks`):\n * - `produce` — build the backend event stream\n * - `persistAssistantMessage` — write the assistant turn to the product DB\n * - `onTurnComplete?` — post-process (proposals, citations, …)\n * - `onEvent?` — per-event side channel (e.g. DO broadcast)\n * - `transformFinalText?` — pre-persist transform (e.g. PII redact)\n * - `traceFlush?` — handed to waitUntil so OTLP export lands\n *\n * Framework neutrality: takes already-resolved values (`identity` tuple,\n * a `waitUntil`), never a `Request` or a `Context`. The product's thin\n * route adapter does auth + parse + access-control, then calls\n * `handleChatTurn(...)` and returns `result.body` as its platform `Response`.\n */\n\n/** The NDJSON line protocol every product chat client already speaks. */\nexport interface ChatStreamEvent {\n type: string\n data?: Record<string, unknown>\n}\n\n/** Identity of a chat turn. `tenantId` is the workspace id for workspace-\n * scoped products and the user id for session-scoped products. */\nexport interface ChatTurnIdentity {\n tenantId: string\n /** Thread / session id. */\n sessionId: string\n userId: string\n /** Monotonic 0-based turn index within the session. */\n turnIndex: number\n}\n\n/** The live side of a turn — what the product's `produce` hook returns. */\nexport interface ChatTurnProducer<TEvent extends ChatStreamEvent = ChatStreamEvent> {\n /** The turn's event stream. Forwarded verbatim to the caller. */\n stream: AsyncGenerator<TEvent, void, unknown>\n /** The turn's final assistant text. Read once, after `stream` drains. */\n finalText(): string\n}\n\nexport interface ChatTurnHooks {\n /** Build the backend stream. The engine forwards events verbatim and\n * reads `finalText()` once the stream drains. */\n produce(): ChatTurnProducer\n /** Persist the assistant message to the product's own store. Called\n * once, after drain, with the assembled (transform-applied) text. */\n persistAssistantMessage(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional post-processing (proposals, citations, credit metering …).\n * Errors are swallowed + logged — post-process must never fail a turn\n * that already streamed successfully. */\n onTurnComplete?(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional per-event side channel (e.g. DO broadcast). Runs for every\n * emitted event, lifecycle envelope included. Errors swallowed — a\n * broadcast failure must not break the chat stream. */\n onEvent?(event: ChatStreamEvent): void | Promise<void>\n /** Optional pre-persist transform of the final text (e.g. PII\n * redaction). Affects only what is persisted; the live stream is\n * never altered. */\n transformFinalText?(text: string): string | Promise<string>\n /** Optional trace flush — resolves when OTLP export completes. Handed\n * to `waitUntil` so the worker isolate stays alive for the POST. */\n traceFlush?(): Promise<void>\n}\n\nexport interface RunChatTurnInput {\n identity: ChatTurnIdentity\n hooks: ChatTurnHooks\n /** Worker liveness hook. When omitted, trace flush is awaited inline\n * before the stream closes. */\n waitUntil?: (p: Promise<unknown>) => void\n /** Structured logger for swallowed hook errors. Defaults to\n * `console.error` so failures surface without product wiring. */\n log?: (message: string, meta?: Record<string, unknown>) => void\n}\n\nexport interface ChatTurnResult {\n /** NDJSON body — return this as the platform `Response` body. */\n body: ReadableStream<Uint8Array>\n /** Content type for the response. */\n contentType: 'application/x-ndjson'\n}\n\nconst encoder = new TextEncoder()\n\nfunction encodeLine(event: ChatStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`)\n}\n\nfunction defaultLog(message: string, meta?: Record<string, unknown>): void {\n if (meta) console.error(message, meta)\n else console.error(message)\n}\n\n/**\n * Run one chat turn. Returns immediately with a `ReadableStream` body;\n * the turn executes as the body is pulled. Never rejects — backend\n * failures surface as `error` + `session.run.failed` events.\n */\nexport function handleChatTurn(input: RunChatTurnInput): ChatTurnResult {\n const log = input.log ?? defaultLog\n const { identity, hooks } = input\n\n const body = new ReadableStream<Uint8Array>({\n start: async (controller) => {\n const emit = async (event: ChatStreamEvent): Promise<void> => {\n controller.enqueue(encodeLine(event))\n if (hooks.onEvent) {\n try {\n await hooks.onEvent(event)\n } catch (err) {\n log('[chat-engine] onEvent hook threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n }\n\n try {\n await emit({\n type: 'session.run.started',\n data: {\n sessionId: identity.sessionId,\n tenantId: identity.tenantId,\n turnIndex: identity.turnIndex,\n },\n })\n\n const producer = hooks.produce()\n for await (const event of producer.stream) {\n await emit(event)\n }\n const rawFinal = producer.finalText()\n const finalText = hooks.transformFinalText\n ? await hooks.transformFinalText(rawFinal)\n : rawFinal\n\n await hooks.persistAssistantMessage({ identity, finalText })\n if (hooks.onTurnComplete) {\n try {\n await hooks.onTurnComplete({ identity, finalText })\n } catch (err) {\n log('[chat-engine] onTurnComplete threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n await emit({\n type: 'session.run.completed',\n data: { sessionId: identity.sessionId },\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n log('[chat-engine] turn failed', { error: message })\n await emit({ type: 'error', data: { message } })\n await emit({\n type: 'session.run.failed',\n data: { sessionId: identity.sessionId, message },\n })\n } finally {\n if (hooks.traceFlush) {\n const flush = hooks.traceFlush().catch((err) =>\n log('[chat-engine] traceFlush threw', {\n error: err instanceof Error ? err.message : String(err),\n }),\n )\n if (input.waitUntil) input.waitUntil(flush)\n else await flush\n }\n controller.close()\n }\n },\n })\n\n return { body, contentType: 'application/x-ndjson' }\n}\n","/**\n * Derive a stable executionId from the run identity. The same\n * `(projectId, sessionId, turnIndex)` tuple yields the same id — so a\n * client retry of the same turn lands on the same substrate execution\n * and the orchestrator's buffer replays instead of starting a second\n * prompt.\n *\n * Format is readable, not hashed: operators grepping orchestrator logs\n * for `gtm-agent:thread-abc:3` find the run without translating an\n * opaque id. Substrate executionIds are not a secrecy boundary.\n *\n * Wire integration:\n * - Sandbox PromptOptions accepts `executionId` and `lastEventId`.\n * Products pass this id to make cross-process reconnect land on the\n * same substrate execution instead of spawning a duplicate run.\n */\nexport function deriveExecutionId(input: {\n projectId: string\n sessionId: string\n turnIndex: number\n}): string {\n return `${input.projectId}:${input.sessionId}:${input.turnIndex}`\n}\n","/**\n * Build-prompt starting points for the two buildable artifact types. There is\n * NO `toolGenerator`/`mcpGenerator` wrapper — the factory is `agenticGenerator`\n * + a verifier (docs/artifact-lifecycle-frontier.md), so a tool or an MCP\n * server is built by composing the pieces directly:\n *\n * // a tool:\n * agenticGenerator({ buildPrompt: toolBuildPrompt, verify: commandVerifier('pnpm', ['test']) })\n * // an MCP server:\n * agenticGenerator({ buildPrompt: mcpBuildPrompt, verify: mcpServeVerifier({ command: 'node', args: ['server.mjs'] }) })\n *\n * These are the only type-specific bit (the phrasing that points the agent at a\n * tool vs. an MCP); the worktree, resume-on-failure loop, and improvement-loop\n * wrapper are shared. MCP is the load-bearing target — it is how a harness\n * acquires tools; raw tools matter where we control the loader.\n */\n\nimport type { AnalystFinding } from '@tangle-network/agent-eval'\n\ntype FindingsArg = { report: unknown; findings: AnalystFinding[] }\n\nfunction findingLines(findings: AnalystFinding[]): string[] {\n return findings.map((f) => {\n const where = f.subject ? ` [${f.subject}]` : ''\n const action = f.recommended_action ? ` → ${f.recommended_action}` : ''\n return `- (${f.severity})${where} ${f.claim}${action}`\n })\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new tool. */\nexport function toolBuildPrompt(args: FindingsArg): string {\n return [\n 'You are building a new TOOL for this codebase to address the gaps below.',\n 'Write the tool as a small, self-contained module PLUS tests that exercise it.',\n 'The tool must compile and its tests must pass — they will be run automatically;',\n 'if verification fails you will get the error and another attempt. Do not commit;',\n 'leave the changes in the working tree.',\n '',\n 'Gaps the tool should close:',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new MCP server. */\nexport function mcpBuildPrompt(args: FindingsArg): string {\n return [\n 'You are building a new MCP SERVER (Model Context Protocol) that exposes',\n 'tool(s) addressing the gaps below, so any harness can mount it.',\n 'Requirements that WILL be checked by booting the server:',\n '- it starts over stdio and answers the MCP `initialize` handshake,',\n '- `tools/list` returns at least one tool with a valid input schema.',\n 'Newline-delimited JSON-RPC 2.0, protocol version 2024-11-05. Include a start',\n 'command (e.g. a package.json `start` script or a clear entrypoint). If the',\n 'boot-and-probe fails you will get the error and another attempt. Do not',\n 'commit; leave the changes in the working tree.',\n '',\n 'Capabilities the server should provide:',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n","/**\n * `mcpServeVerifier` — the intrinsic verifier for a built MCP server: the\n * boot-and-probe checker named in docs/artifact-lifecycle-frontier.md. A\n * generated MCP server is only a candidate if it actually *serves* — so this\n * boots it over stdio (the default local MCP transport) and runs the real\n * handshake: `initialize` → `notifications/initialized` → `tools/list`, and\n * asserts the server answers with at least `minTools` tools.\n *\n * Outcomes follow the `Verifier` contract: a server that fails to start, exits\n * early, errors the handshake, times out, or exposes no tools is a FAILED\n * candidate (`{ok:false}`, fed back into the next generation shot); a missing\n * start binary or spawn fault THROWS (a setup bug, never a silent fallback).\n *\n * Protocol matches the runtime's own stdio MCP server (src/mcp/server.ts):\n * newline-delimited JSON-RPC 2.0, protocol version 2024-11-05.\n */\n\nimport { spawn } from 'node:child_process'\nimport { createInterface } from 'node:readline'\nimport type { Verifier, VerifyResult } from './agentic-generator'\n\nconst PROTOCOL_VERSION = '2024-11-05'\n\nexport interface McpServeSpec {\n /** Command that starts the built MCP server in the worktree (stdio transport). */\n command: string\n args?: string[]\n /** Extra env for the server process (merged over `process.env`). */\n env?: Record<string, string>\n /** Handshake timeout (ms). Default 30s. */\n timeoutMs?: number\n /** Minimum tools the server must expose to pass. Default 1. */\n minTools?: number\n}\n\ninterface JsonRpcResponse {\n jsonrpc?: string\n id?: number | string | null\n result?: unknown\n error?: { code: number; message: string }\n}\n\n/** Build a `Verifier` that boots a generated MCP server over stdio and checks it exposes tools. */\nexport function mcpServeVerifier(spec: McpServeSpec): Verifier {\n const timeoutMs = spec.timeoutMs ?? 30_000\n const minTools = spec.minTools ?? 1\n\n return (worktreePath: string): Promise<VerifyResult> =>\n new Promise<VerifyResult>((resolve, reject) => {\n const child = spawn(spec.command, spec.args ?? [], {\n cwd: worktreePath,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...spec.env },\n })\n\n const stderr: string[] = []\n let settled = false\n let nextId = 1\n const initId = nextId++\n let listId = -1\n\n const settle = (fn: () => void) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n rl.close()\n child.kill('SIGKILL')\n fn()\n }\n const withStderr = (msg: string) =>\n stderr.length > 0 ? `${msg}\\nstderr:\\n${stderr.join('').slice(-2000)}` : msg\n const pass = () => settle(() => resolve({ ok: true }))\n const failCandidate = (msg: string) =>\n settle(() => resolve({ ok: false, feedback: withStderr(msg) }))\n const setupFault = (err: Error) => settle(() => reject(err))\n const failStdin = (err: Error) =>\n failCandidate(`writing to MCP server stdin failed: ${err.message}`)\n\n const send = (msg: Record<string, unknown>): boolean => {\n try {\n child.stdin.write(`${JSON.stringify(msg)}\\n`)\n return true\n } catch (err) {\n // EPIPE: the server died mid-handshake — a failed candidate, not a fault.\n failStdin(err as Error)\n return false\n }\n }\n\n child.on('error', (err) => {\n const code = (err as NodeJS.ErrnoException).code\n setupFault(\n code === 'ENOENT'\n ? new Error(\n `mcpServeVerifier: '${spec.command}' not found in PATH (setup bug, not a failed candidate)`,\n )\n : new Error(`mcpServeVerifier: '${spec.command}' failed to spawn: ${err.message}`),\n )\n })\n child.on('exit', (code, signal) => {\n // An exit before the handshake completes is a failed candidate (the\n // server crashed on boot); after we settle, our own SIGKILL fires here.\n failCandidate(`MCP server exited (code ${code}, signal ${signal}) before serving`)\n })\n // Pipe failures normally arrive asynchronously, outside send()'s try/catch.\n child.stdin.on('error', failStdin)\n child.stderr.on('data', (d) => stderr.push(String(d)))\n\n const rl = createInterface({ input: child.stdout })\n rl.on('line', (line) => {\n let msg: JsonRpcResponse | undefined\n try {\n msg = JSON.parse(line) as JsonRpcResponse\n } catch {\n return // servers log to stdout too; skip non-JSON lines\n }\n if (!msg || typeof msg !== 'object') return\n\n if (msg.id === initId) {\n if (msg.error) return failCandidate(`initialize errored: ${JSON.stringify(msg.error)}`)\n if (!send({ jsonrpc: '2.0', method: 'notifications/initialized' })) return\n listId = nextId++\n send({ jsonrpc: '2.0', id: listId, method: 'tools/list' })\n return\n }\n if (msg.id === listId) {\n if (msg.error) return failCandidate(`tools/list errored: ${JSON.stringify(msg.error)}`)\n const tools = (msg.result as { tools?: unknown[] } | undefined)?.tools\n if (!Array.isArray(tools)) return failCandidate('tools/list result has no tools array')\n if (tools.length < minTools) {\n return failCandidate(`tools/list returned ${tools.length} tool(s), need >= ${minTools}`)\n }\n return pass()\n }\n })\n\n const timer = setTimeout(\n () => failCandidate(`MCP server did not complete the handshake within ${timeoutMs}ms`),\n timeoutMs,\n )\n\n send({\n jsonrpc: '2.0',\n id: initId,\n method: 'initialize',\n params: {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: {},\n clientInfo: { name: 'agent-runtime-mcp-verify', version: '0' },\n },\n })\n })\n}\n","import { canonicalJson } from '@tangle-network/agent-eval'\nimport type {\n MutableSurface,\n ProposeContext,\n ProposedCandidate,\n SurfaceProposer,\n} from '@tangle-network/agent-eval/campaign'\nimport {\n type AgentProfile,\n type AgentProfileDiff,\n changedAgentProfileAxes,\n} from '@tangle-network/agent-interface'\nimport { canonicalCandidateDigest } from '../candidate-execution/digest'\nimport {\n applyExactAgentProfileDiff,\n parseExactAgentProfile,\n parseExactAgentProfileDiff,\n} from '../candidate-execution/profile'\n\nexport type ProfileDiffProposerContext<TFindings = unknown> = ProposeContext<TFindings> & {\n profile: AgentProfile\n}\n\nexport interface ProfileDiffProposerOptions<TFindings = unknown> {\n proposeDiffs(\n context: ProfileDiffProposerContext<TFindings>,\n ): Promise<readonly AgentProfileDiff[]> | readonly AgentProfileDiff[]\n}\n\n/**\n * Turn exact AgentProfileDiffs from any source into full profile candidates for\n * the shared optimization loop. Research, catalogs, humans, and trace miners\n * differ only in `proposeDiffs`; measurement and promotion stay identical.\n */\nexport function profileDiffProposer<TFindings = unknown>(\n options: ProfileDiffProposerOptions<TFindings>,\n): SurfaceProposer<TFindings> {\n return {\n kind: 'agent-profile-diff',\n async propose(ctx): Promise<Array<MutableSurface | ProposedCandidate>> {\n if (typeof ctx.currentSurface !== 'string') {\n throw new Error('profileDiffProposer requires a serialized AgentProfile surface')\n }\n const profile = parseSerializedProfile(ctx.currentSurface)\n const proposals = await options.proposeDiffs({\n ...ctx,\n profile,\n })\n const candidates: ProposedCandidate[] = []\n const normalizedBaseline = applyExactAgentProfileDiff(\n profile,\n { kind: 'agent-profile-diff' },\n 'profile diff baseline',\n )\n const seen = new Set<string>([canonicalJson(normalizedBaseline)])\n for (const [index, proposal] of proposals.entries()) {\n if (candidates.length >= ctx.populationSize || ctx.signal.aborted) break\n const diff = parseExactAgentProfileDiff(proposal, `profile diff proposal ${index}`)\n const axes = changedAgentProfileAxes(diff)\n if (axes.length === 0) continue\n const candidate = applyExactAgentProfileDiff(\n profile,\n diff,\n `profile diff candidate ${index}`,\n )\n const surface = canonicalJson(candidate)\n if (seen.has(surface)) continue\n seen.add(surface)\n candidates.push({\n surface,\n label: diff.title ?? diff.id ?? `Change ${axes.join(', ')}`,\n rationale: candidateRationale(diff, axes),\n })\n }\n return candidates\n },\n }\n}\n\nfunction candidateRationale(diff: AgentProfileDiff, axes: readonly string[]): string {\n const reason = diff.rationale ?? `Changes profile axes: ${axes.join(', ')}.`\n const source = diff.source\n ? [diff.source.kind, ...(diff.source.artifacts ?? [])].join(' · ')\n : 'source unspecified'\n return `${reason} Source: ${source}. Diff: ${canonicalCandidateDigest(diff)}.`\n}\n\nfunction parseSerializedProfile(surface: string): AgentProfile {\n let raw: unknown\n try {\n raw = JSON.parse(surface)\n } catch (cause) {\n throw new Error('profileDiffProposer current surface is not valid AgentProfile JSON', {\n cause,\n })\n }\n return parseExactAgentProfile(raw, 'profileDiffProposer current profile')\n}\n","/**\n *\n * `reflectiveGenerator` — the cheap, no-sandbox `CandidateGenerator`. It drafts\n * surface edits via the existing improvement proposer (`proposeFromFindings`,\n * one LLM patch per finding) and applies them as ONE coherent improvement into\n * the candidate worktree. `maxShots` is ignored — reflection is single-shot by\n * construction (the patches are already drafted).\n *\n * This is the `shots=1, sandbox=off` setting of the one improvement driver.\n * The `agenticGenerator` (a multi-shot verify-in-session loop) is the\n * `shots=N` setting — both plug into the same `improvementDriver`.\n *\n * @experimental\n */\n\nimport { spawnSync } from 'node:child_process'\nimport type { SurfaceImprovementEdit } from '../agent/improvement-adapter'\nimport type { ImprovementProposalSource } from '../analyst-loop/types'\nimport type { CandidateGenerator } from './improvement-driver'\n\nexport interface ReflectiveGeneratorOptions {\n improvementProposalSource: ImprovementProposalSource<SurfaceImprovementEdit>\n}\n\n/** Cheap no-sandbox `CandidateGenerator` (the `shots=1` setting): draft surface edits via the improvement adapter and apply them as one coherent candidate. */\nexport function reflectiveGenerator(opts: ReflectiveGeneratorOptions): CandidateGenerator {\n return {\n kind: 'reflective',\n async generate({ worktreePath, findings }) {\n const batch = await opts.improvementProposalSource.proposeFromFindings(findings)\n if (batch.edits.length === 0) return { applied: false, summary: '' }\n\n let applied = 0\n for (const edit of batch.edits) {\n if (applyPatch(edit.patch, worktreePath)) applied++\n }\n if (applied === 0) return { applied: false, summary: '' }\n\n const summary =\n batch.edits.length === 1\n ? batch.edits[0]!.summary\n : `analyst: ${applied} surface edit${applied === 1 ? '' : 's'}`\n return { applied: true, summary }\n },\n }\n}\n\n/** Apply a proposed patch inside the isolated candidate worktree.\n * candidate worktree (a fresh checkout of baseRef, so `-p0` paths match). */\nfunction applyPatch(patch: string, cwd: string): boolean {\n const result = spawnSync('git', ['apply', '--whitespace=fix', '-p0', '-'], {\n cwd,\n input: patch,\n encoding: 'utf-8',\n })\n return result.status === 0\n}\n","/**\n *\n * Pure readiness-decision helper. Maps a `KnowledgeReadinessReport` from\n * `@tangle-network/agent-eval` to a three-state branch (`ready` / `blocked` /\n * `caveat`) the runtime, route handlers, and UI shells can all switch on.\n *\n * Default `minimumScore` of 0.7 mirrors the readiness scoring scale in\n * agent-eval; callers tightening or loosening this should keep it consistent\n * across all entry points for the same product so the UI / metrics agree on\n * what \"caveat\" means.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { ValidationError } from './errors'\nimport type { KnowledgeReadinessDecision } from './types'\n\nconst DEFAULT_MINIMUM_READINESS_SCORE = 0.7\n\n/**\n * Map a `KnowledgeReadinessReport` to a three-state branch (`ready` / `blocked` / `caveat`) the runtime, route handlers, and UI shells all switch on.\n *\n * @stable\n */\nexport function decideKnowledgeReadiness(\n report: KnowledgeReadinessReport,\n options: { minimumScore?: number } = {},\n): KnowledgeReadinessDecision {\n const minimumScore = options.minimumScore ?? DEFAULT_MINIMUM_READINESS_SCORE\n if (!Number.isFinite(minimumScore) || minimumScore < 0 || minimumScore > 1) {\n throw new ValidationError(\n `minimumScore must be a finite number in [0, 1]; received ${String(minimumScore)}`,\n )\n }\n const blockingGapIds = report.blockingMissingRequirements.map((requirement) => requirement.id)\n const nonBlockingGapIds = report.nonBlockingGaps.map((requirement) => requirement.id)\n if (blockingGapIds.length > 0) {\n return {\n passed: false,\n status: 'blocked',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n if (report.readinessScore < minimumScore) {\n return {\n passed: false,\n status: 'caveat',\n reason: `Knowledge readiness score ${report.readinessScore.toFixed(3)} is below minimum ${minimumScore.toFixed(3)}.`,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n return {\n passed: true,\n status: 'ready',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n}\n","/**\n * The product-facing backend selector for `runChatThroughRuntime` /\n * `runAgentTaskStream`: one call turns a `--backend {router,tcloud,cli-bridge,\n * sandbox}` choice into the `AgentExecutionBackend` the chat leg runs on.\n *\n * It is the `AgentExecutionBackend` sibling of `resolveSandboxClient` (which\n * resolves the `SandboxClient` a `runLoop` drives). Both exist for the same\n * reason: every in-process eval product hand-rolled the identical\n * \"`backend-name` → `createOpenAICompatibleBackend`\" branch, and the copies\n * drift. This is the single generic resolver they share.\n *\n * - `router` / `tcloud` / `cli-bridge` → OpenAI-compatible chat completions.\n * All three speak `POST {baseUrl}/chat/completions` in OpenAI's SSE shape —\n * the router (a.k.a. tcloud) IS that endpoint, and cli-bridge fronts a\n * harness CLI behind the same protocol at its own `/v1`. They differ only\n * in `baseUrl` / `apiKey` and the `kind` label a product wants on its\n * traces. cli-bridge REQUIRES `model` in the request body, so it MUST route\n * through `createOpenAICompatibleBackend` (which sends it), never a\n * transport that drops the field.\n * - `sandbox` → the caller's own domain backend. The sandbox variant carries\n * product specifics (system prompt, workspace id, in-box D1 executor) that\n * do NOT belong in the substrate, so the product passes a `sandboxBackend()`\n * seam that this resolver simply invokes.\n *\n * This resolver is PURE backend selection. Product concerns — credit hard-cuts,\n * fetch-capture shims, D1 platform wiring — stay as product-side WRAPPERS\n * around the returned backend. The OpenAI-compat passthrough fields (`tools`,\n * `toolChoice`, `responseFormat`, `temperature`, `maxTokens`, `fetchImpl`,\n * `retry`) are forwarded verbatim so a product can advertise its app tools,\n * preserve generation settings, or install a capturing fetch without\n * re-opening the branch this consolidation closes.\n */\n\nimport { createOpenAICompatibleBackend } from './backends'\nimport type { AgentBackendInput, AgentExecutionBackend } from './types'\n\n/** The transport a chat backend runs on. */\nexport type AgentBackendKind = 'router' | 'tcloud' | 'cli-bridge' | 'sandbox'\n\n/**\n * OpenAI-compat passthrough forwarded to `createOpenAICompatibleBackend` for\n * the `router` / `tcloud` / `cli-bridge` kinds. Mirrors that factory's optional\n * inputs so a product keeps its tool advertising / capture-fetch without\n * re-implementing the backend branch.\n */\ntype OpenAICompatPassthrough = Pick<\n Parameters<typeof createOpenAICompatibleBackend>[0],\n 'tools' | 'toolChoice' | 'responseFormat' | 'temperature' | 'maxTokens' | 'fetchImpl' | 'retry'\n>\n\nexport interface ResolveAgentBackendOptions<TInput extends AgentBackendInput = AgentBackendInput>\n extends OpenAICompatPassthrough {\n /** The chat transport to resolve. */\n kind: AgentBackendKind\n /**\n * Bearer credential for the OpenAI-compat kinds. Empty string is valid for a\n * loopback-anonymous cli-bridge; a `router`/`tcloud` route with an empty key\n * is a caller bug the product surfaces before calling in.\n */\n apiKey: string\n /** Base URL for the OpenAI-compat kinds. cli-bridge's is its `/v1`. */\n baseUrl: string\n /** Model id sent on every request. cli-bridge rejects a request without it. */\n model: string\n /** `kind` label stamped on the resolved backend + its traces. Defaults to `kind`. */\n label?: string\n /**\n * `sandbox` kind: the product's own domain backend. Required for that kind —\n * the substrate owns no product sandbox shape, so a `sandbox` resolution with\n * no seam is a caller bug, not a silent fallback.\n */\n sandboxBackend?: () => AgentExecutionBackend<TInput>\n}\n\n/**\n * Resolve the `AgentExecutionBackend` for the chosen `kind`. Reuse this instead\n * of hand-rolling the `createOpenAICompatibleBackend` branch in each product.\n */\nexport function resolveAgentBackend<TInput extends AgentBackendInput = AgentBackendInput>(\n opts: ResolveAgentBackendOptions<TInput>,\n): AgentExecutionBackend<TInput> {\n switch (opts.kind) {\n case 'router':\n case 'tcloud':\n case 'cli-bridge': {\n const passthrough: OpenAICompatPassthrough = {}\n // Forward only the fields a caller actually set — an explicit\n // `tools: []` / `undefined` would otherwise reach the factory and change\n // its request shape (some providers reject an empty `tools` array).\n if (opts.tools !== undefined) passthrough.tools = opts.tools\n if (opts.toolChoice !== undefined) passthrough.toolChoice = opts.toolChoice\n if (opts.responseFormat !== undefined) passthrough.responseFormat = opts.responseFormat\n if (opts.temperature !== undefined) passthrough.temperature = opts.temperature\n if (opts.maxTokens !== undefined) passthrough.maxTokens = opts.maxTokens\n if (opts.fetchImpl !== undefined) passthrough.fetchImpl = opts.fetchImpl\n if (opts.retry !== undefined) passthrough.retry = opts.retry\n return createOpenAICompatibleBackend<TInput>({\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n model: opts.model,\n kind: opts.label ?? opts.kind,\n ...passthrough,\n })\n }\n case 'sandbox': {\n if (!opts.sandboxBackend) {\n throw new Error(\"resolveAgentBackend: kind 'sandbox' requires opts.sandboxBackend\")\n }\n return opts.sandboxBackend()\n }\n }\n}\n","/**\n *\n * The two top-level entry points:\n *\n * - `runAgentTask` — single-shot lifecycle for adapter-driven tasks.\n * - `runAgentTaskStream` — streaming lifecycle that delegates execution to an\n * `AgentExecutionBackend` (model API, sandbox, or custom iterable).\n *\n * Both gate the run on `KnowledgeReadinessReport` from `agent-eval`, emit the\n * same lifecycle event vocabulary (under different shapes — see `types.ts`),\n * and route session lifecycle through a pluggable `RuntimeSessionStore`.\n *\n * @stable\n */\n\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n FAILURE_CLASSES,\n type FailureClass,\n type KnowledgeReadinessReport,\n type RunRecord,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nconst FAILURE_CLASS_SET = new Set<string>(FAILURE_CLASSES)\n\n/** True when a free-form control failure string is a canonical taxonomy\n * class — so only real taxonomy tags are promoted to the cross-agent\n * `RunRecord.failureClass` key; novel strings stay as `failureMode` detail. */\nfunction asFailureClass(value: string | undefined): FailureClass | undefined {\n return value && FAILURE_CLASS_SET.has(value) ? (value as FailureClass) : undefined\n}\n\n/** Stamp cross-cutting defaults onto adapter-projected RunRecords without\n * overriding anything the adapter set explicitly:\n * - `scenarioId` — the run's scenario, when the record omits one.\n * - `failureClass` — the control layer's failure classification promoted\n * onto the canonical cross-agent key, but ONLY when it's a real taxonomy\n * class. This is what lets the substrate aggregate failures across every\n * agent in one vocabulary instead of per-agent ad-hoc strings. */\nexport function applyRunRecordDefaults(\n records: RunRecord[],\n scenarioId: string,\n controlFailureClass: string | undefined,\n): RunRecord[] {\n const fc = asFailureClass(controlFailureClass)\n return records.map((record) => {\n let r = record\n if (r.scenarioId === undefined) r = { ...r, scenarioId }\n if (r.failureClass === undefined && fc) r = { ...r, failureClass: fc }\n return r\n })\n}\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { BackendTransportError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { nowIso, startOrResumeRuntimeSession, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskSpec,\n AgentTaskStatus,\n BackendErrorDetail,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeStreamEvent,\n} from './types'\n\n/**\n * Single-shot task lifecycle for adapter-driven tasks: readiness-gated, emits the runtime lifecycle event vocabulary, session-store pluggable.\n *\n * @stable\n */\nexport async function runAgentTask<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RunAgentTaskOptions<TState, TAction, TActionResult, TEval>,\n): Promise<AgentTaskRunResult<TState, TAction, TActionResult, TEval>> {\n const task = options.task\n await emit(options.onEvent, { type: 'task_start', task })\n await emit(options.onEvent, { type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflight(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n options.onEvent,\n )\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n await emit(options.onEvent, { type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n }\n\n await emit(options.onEvent, { type: 'control_start', task, knowledge })\n const scenarioId = options.scenarioId ?? task.id\n const control = await runAgentControlLoop<TState, TAction, TActionResult, TEval>({\n intent: task.intent,\n budget: task.budget,\n signal: options.signal,\n store: options.store,\n scenarioId,\n projectId: options.projectId,\n variantId: options.variantId,\n observe: ({ history, abortSignal }) =>\n options.adapter.observe({ task, knowledge, history, abortSignal }),\n validate: async ({ state, history, abortSignal }) => {\n const readinessEval = blockingKnowledgeEval(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n const evals = await options.adapter.validate({\n task,\n knowledge,\n state,\n history,\n abortSignal,\n })\n return [readinessEval as TEval, ...evals]\n },\n decide: (ctx) => {\n if (isKnowledgeBlocked(ctx.evals)) {\n return (\n options.adapter.onKnowledgeBlocked?.({\n task,\n knowledge,\n questions,\n acquisitionPlans,\n }) ?? {\n type: 'stop',\n pass: false,\n score: knowledge.readinessScore,\n reason: `knowledge readiness blocked: ${knowledge.reason}`,\n }\n )\n }\n return options.adapter.decide(toAgentContext(task, knowledge, ctx))\n },\n act: (action, ctx) => options.adapter.act(action, toAgentContext(task, knowledge, ctx)),\n shouldStop: options.adapter.shouldStop\n ? (ctx) => options.adapter.shouldStop!(toAgentContext(task, knowledge, ctx))\n : undefined,\n getActionCostUsd: options.adapter.getActionCostUsd\n ? ({ action, result, state, evals, history }) =>\n options.adapter.getActionCostUsd!({ action, result, task, state, evals, history })\n : undefined,\n onStep: (step) => emit(options.onEvent, { type: 'control_step', task, step }),\n })\n await emit(options.onEvent, { type: 'control_end', task, control })\n const status = statusFromControl(control)\n await emit(options.onEvent, { type: 'task_end', task, status, reason: control.reason })\n\n return {\n task,\n status,\n knowledge,\n questions,\n acquisitionPlans,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n control,\n runRecords: applyRunRecordDefaults(\n options.adapter.projectRunRecords?.(control, task) ?? [],\n scenarioId,\n control.failureClass,\n ),\n }\n}\n\n/**\n * Streaming task lifecycle: delegates execution to an `AgentExecutionBackend` (model API, sandbox, or custom iterable) and yields lifecycle events as they happen.\n *\n * @stable\n */\nexport async function* runAgentTaskStream<TInput extends AgentBackendInput = AgentBackendInput>(\n options: RunAgentTaskStreamOptions<TInput>,\n): AsyncIterable<RuntimeStreamEvent> {\n const task = options.task\n const input = { task, ...(options.input ?? {}) } as TInput\n yield streamEvent({ type: 'task_start', task })\n\n yield streamEvent({ type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflightStream(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n )\n for (const event of preflight.events) yield event\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n yield streamEvent({ type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n }\n const decision = decideKnowledgeReadiness(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n yield streamEvent({ type: 'readiness_end', task, knowledge, decision })\n if (!decision.passed && decision.status === 'blocked') {\n const reason = `knowledge readiness blocked: ${decision.reason}`\n yield streamEvent({ type: 'task_end', task, status: 'blocked', reason })\n yield streamEvent({ type: 'final', task, status: 'blocked', reason })\n return\n }\n\n const store = options.sessionStore\n const opened = await startOrResumeRuntimeSession({\n backend: options.backend,\n input,\n context: { task, knowledge, signal: options.signal },\n store,\n sessionId: options.sessionId,\n resume: options.resume,\n })\n let session = opened.session\n const shouldResume = opened.resumed\n const sessionEvent = streamEvent({\n type: shouldResume ? 'session_resumed' : 'session_created',\n task,\n session,\n })\n await store?.appendEvent?.(session.id, sessionEvent)\n yield sessionEvent\n\n const backendStart = streamEvent({\n type: 'backend_start',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendStart)\n yield backendStart\n\n let finalText = ''\n try {\n for await (const rawEvent of options.backend.stream(opened.input, {\n task,\n knowledge,\n session,\n signal: options.signal,\n })) {\n const event = normalizeBackendStreamEvent(rawEvent, task, session)\n if (event.type === 'text_delta') finalText += event.text\n await store?.appendEvent?.(session.id, event)\n yield event\n }\n const completedStatus: AgentTaskStatus = 'completed'\n session = touchSession({ ...session, status: completedStatus })\n await store?.put(session)\n const backendEnd = streamEvent({\n type: 'backend_end',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendEnd)\n yield backendEnd\n const reason = 'backend completed'\n const taskEnd = streamEvent({ type: 'task_end', task, status: completedStatus, reason })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status: completedStatus,\n reason,\n text: finalText || undefined,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n session = touchSession({ ...session, status: options.signal?.aborted ? 'aborted' : 'failed' })\n await store?.put(session)\n let stopErrorMessage: string | undefined\n try {\n await options.backend.stop?.(session, message)\n } catch (stopErr) {\n stopErrorMessage = stopErr instanceof Error ? stopErr.message : String(stopErr)\n }\n const combinedMessage = stopErrorMessage\n ? `${message}; backend stop failed: ${stopErrorMessage}`\n : message\n // Typed transport detail — preserves status code + truncated body so\n // consumers can map onto `RunRecord.error` without re-parsing the log\n // string. Required by the runtime's fail-loud contract: silent empty\n // output for a 402 / 401 / 5xx hides the real failure mode.\n const errorDetail: BackendErrorDetail =\n err instanceof BackendTransportError\n ? {\n kind: 'transport',\n message: combinedMessage,\n status: err.status,\n body: err.body,\n }\n : { kind: 'backend', message: combinedMessage }\n const backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: combinedMessage,\n recoverable: !options.signal?.aborted,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, backendError)\n yield backendError\n const status: AgentTaskStatus = options.signal?.aborted ? 'aborted' : 'failed'\n const taskEnd = streamEvent({ type: 'task_end', task, status, reason: message })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status,\n reason: message,\n text: finalText || undefined,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n }\n}\n\nasync function runKnowledgePreflight<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n onEvent: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n): Promise<{ userAnswers: Record<string, string>; acquiredEvidenceIds: string[] }> {\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n await emit(onEvent, { type: 'questions_start', task, questions })\n userAnswers = await provider.answerQuestions(questions, task)\n await emit(onEvent, { type: 'questions_end', task, questions, userAnswers })\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n await emit(onEvent, { type: 'acquisition_start', task, acquisitionPlans })\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n await emit(onEvent, {\n type: 'acquisition_end',\n task,\n acquisitionPlans,\n acquiredEvidenceIds,\n })\n }\n return { userAnswers, acquiredEvidenceIds }\n}\n\nasync function runKnowledgePreflightStream(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n): Promise<{\n userAnswers: Record<string, string>\n acquiredEvidenceIds: string[]\n events: RuntimeStreamEvent[]\n}> {\n const events: RuntimeStreamEvent[] = []\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n events.push(streamEvent({ type: 'questions_start', task, questions }))\n userAnswers = await provider.answerQuestions(questions, task)\n events.push(streamEvent({ type: 'questions_end', task, questions, userAnswers }))\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n events.push(streamEvent({ type: 'acquisition_start', task, acquisitionPlans }))\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n events.push(\n streamEvent({ type: 'acquisition_end', task, acquisitionPlans, acquiredEvidenceIds }),\n )\n }\n return { userAnswers, acquiredEvidenceIds, events }\n}\n\nfunction streamEvent<T extends Omit<RuntimeStreamEvent, 'timestamp'>>(\n event: T,\n): T & { timestamp: string } {\n return { ...event, timestamp: nowIso() }\n}\n\nfunction buildReadiness(\n task: AgentTaskSpec,\n provider: AgentKnowledgeProvider | undefined,\n): Promise<KnowledgeReadinessReport> | KnowledgeReadinessReport {\n if (provider?.buildReadiness) return provider.buildReadiness(task)\n return scoreKnowledgeReadiness({\n taskId: task.id,\n requirements: task.requiredKnowledge ?? [],\n metadata: { domain: task.domain, ...task.metadata },\n })\n}\n\nfunction isKnowledgeBlocked(evals: ControlEvalResult[]): boolean {\n return evals.some((evalResult) => evalResult.id === 'knowledge-ready' && !evalResult.passed)\n}\n\nfunction statusFromControl(\n control: ControlRunResult<unknown, unknown, unknown, ControlEvalResult>,\n): AgentTaskStatus {\n if (control.stoppedBy === 'abort') return 'aborted'\n if (control.reason.includes('knowledge readiness blocked')) return 'blocked'\n if (control.pass) return 'completed'\n return 'failed'\n}\n\nasync function emit<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n sink: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n event: Parameters<AgentRuntimeEventSink<TState, TAction, TActionResult, TEval>>[0],\n): Promise<void> {\n await sink?.(event)\n}\n\nfunction toAgentContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n task: AgentTaskSpec,\n knowledge: KnowledgeReadinessReport,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n): AgentTaskContext<TState, TAction, TActionResult, TEval> {\n return {\n task,\n knowledge,\n state: ctx.state,\n evals: ctx.evals,\n history: ctx.history,\n budget: ctx.budget,\n stepIndex: ctx.stepIndex,\n wallMs: ctx.wallMs,\n spentCostUsd: ctx.spentCostUsd,\n remainingCostUsd: ctx.remainingCostUsd,\n abortSignal: ctx.abortSignal,\n }\n}\n","/**\n *\n * Production-run lifecycle: record what the agent did on behalf of a customer,\n * what it cost, and how it ended.\n *\n * Three concerns live in this module:\n *\n * 1. **Lifecycle state machine** — `running` -> `completed | failed | cancelled`,\n * enforced by `RuntimeRunStateError`. Completion is idempotent for the same\n * status (a second `complete()` call is a no-op so retries / cleanup paths\n * don't double-fire side effects). A different terminal status is a state\n * error.\n *\n * 2. **Cost ledger** — every `llm_call` event the handle observes contributes\n * `tokensIn`, `tokensOut`, `costUsd`, and bumps `llmCalls`. Wall time is\n * measured from `startRuntimeRun()` to `complete()`. Surface via\n * `handle.cost()` for cost-per-task dashboards.\n *\n * 3. **Persistence adapter** — `RuntimeRunPersistenceAdapter` is the seam\n * consumers plug in to write a `RuntimeRunRow` to their D1 / postgres /\n * KV store. The adapter receives a sanitized row shape; no telemetry\n * payload bytes flow through it unless the consumer opts in via\n * `RuntimeRunOptions.telemetryEvents`.\n *\n * @stable\n */\n\nimport { RuntimeRunStateError, ValidationError } from './errors'\nimport type { AgentTaskSpec, RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport type RuntimeRunStatus = 'running' | 'completed' | 'failed' | 'cancelled'\n\n/** @stable */\nexport interface RuntimeRunCost {\n /** Cumulative input tokens across every observed `llm_call` event. */\n tokensIn: number\n /** Cumulative output tokens across every observed `llm_call` event. */\n tokensOut: number\n /** Sum of `costUsd` from every observed `llm_call` event. */\n costUsd: number\n /** Wall time from `startRuntimeRun()` to `complete()` (or `now()` if not yet completed). */\n wallMs: number\n /** Count of `llm_call` events observed during the run. */\n llmCalls: number\n}\n\n/** @stable */\nexport interface RuntimeRunCompleteInput {\n status: Exclude<RuntimeRunStatus, 'running'>\n resultSummary?: string\n /** Optional explicit cost override; if omitted, the accumulated ledger is used. */\n cost?: Partial<RuntimeRunCost>\n /** Stable error message when `status === 'failed'`. */\n error?: string\n /** Additional adapter-specific fields merged into the persisted row. */\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunRow {\n /** Stable runtime-side identifier. Adapters may translate to their own primary key. */\n id: string\n workspaceId: string\n sessionId?: string\n agentId?: string\n domain?: string\n taskId: string\n scenarioId?: string\n status: RuntimeRunStatus\n resultSummary?: string\n error?: string\n cost: RuntimeRunCost\n startedAt: string\n completedAt?: string\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunPersistenceAdapter {\n /**\n * Called once when `handle.persist()` runs. Implementations write `row` to\n * their durable store (D1, postgres, KV) and return whatever the consumer\n * wants the caller to see (often the storage-side row id). Errors thrown\n * here propagate out of `persist()` so the caller can decide whether to\n * retry or log-and-continue.\n */\n upsert(row: RuntimeRunRow): Promise<void> | void\n}\n\n/** @stable */\nexport interface RuntimeRunOptions {\n workspaceId: string\n sessionId?: string\n agentId?: string\n taskSpec: AgentTaskSpec\n scenarioId?: string\n /** Optional persistence adapter; if omitted, `persist()` is a no-op. */\n adapter?: RuntimeRunPersistenceAdapter\n /** Override the row id; default = `${taskSpec.id}:${random suffix}`. */\n id?: string\n /** Override the clock; default = `Date.now()`. Useful for deterministic tests. */\n now?: () => number\n}\n\n/** @stable */\nexport interface RuntimeRunHandle {\n /** Stable id assigned at start. */\n readonly id: string\n readonly workspaceId: string\n readonly sessionId: string | undefined\n readonly taskSpec: AgentTaskSpec\n readonly status: RuntimeRunStatus\n\n /**\n * Observe a single `RuntimeStreamEvent`. The handle ignores non-cost events\n * (text deltas, tool calls) silently so consumers can pipe the whole stream\n * through `handle.observe`. `llm_call` events update the ledger.\n */\n observe(event: RuntimeStreamEvent): void\n\n /** Snapshot of the current cost ledger. Safe to call at any time. */\n cost(): RuntimeRunCost\n\n /**\n * Transition to a terminal state. Idempotent for the same status; throws\n * `RuntimeRunStateError` for a different terminal status (state machines\n * don't time-travel).\n */\n complete(input: RuntimeRunCompleteInput): void\n\n /** Build the current row without writing it. Useful for tests + dry runs. */\n toRow(metadata?: Record<string, unknown>): RuntimeRunRow\n\n /**\n * Persist the current row via the configured adapter. Must be called after\n * `complete()`. Idempotent for the same terminal state (the adapter sees\n * the same row on retry).\n */\n persist(metadata?: Record<string, unknown>): Promise<void>\n}\n\n/**\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\n *\n * @stable\n */\nexport function startRuntimeRun(options: RuntimeRunOptions): RuntimeRunHandle {\n if (!options.workspaceId) {\n throw new ValidationError('startRuntimeRun: workspaceId is required')\n }\n if (!options.taskSpec?.id) {\n throw new ValidationError('startRuntimeRun: taskSpec.id is required')\n }\n const now = options.now ?? Date.now\n const startedAtMs = now()\n const startedAt = new Date(startedAtMs).toISOString()\n const id = options.id ?? `${options.taskSpec.id}:${randomSuffix()}`\n\n let status: RuntimeRunStatus = 'running'\n let completedAtMs: number | undefined\n let resultSummary: string | undefined\n let error: string | undefined\n let completionMetadata: Record<string, unknown> | undefined\n\n const ledger: RuntimeRunCost = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n wallMs: 0,\n llmCalls: 0,\n }\n\n const snapshotCost = (): RuntimeRunCost => ({\n tokensIn: ledger.tokensIn,\n tokensOut: ledger.tokensOut,\n costUsd: ledger.costUsd,\n wallMs: (completedAtMs ?? now()) - startedAtMs,\n llmCalls: ledger.llmCalls,\n })\n\n const buildRow = (extraMetadata?: Record<string, unknown>): RuntimeRunRow => ({\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n agentId: options.agentId,\n domain: options.taskSpec.domain,\n taskId: options.taskSpec.id,\n scenarioId: options.scenarioId,\n status,\n resultSummary,\n error,\n cost: snapshotCost(),\n startedAt,\n completedAt: completedAtMs !== undefined ? new Date(completedAtMs).toISOString() : undefined,\n metadata: mergeMetadata(completionMetadata, extraMetadata),\n })\n\n return {\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n taskSpec: options.taskSpec,\n get status() {\n return status\n },\n observe(event) {\n if (event.type !== 'llm_call') return\n ledger.llmCalls += 1\n if (typeof event.tokensIn === 'number' && Number.isFinite(event.tokensIn)) {\n ledger.tokensIn += event.tokensIn\n }\n if (typeof event.tokensOut === 'number' && Number.isFinite(event.tokensOut)) {\n ledger.tokensOut += event.tokensOut\n }\n if (typeof event.costUsd === 'number' && Number.isFinite(event.costUsd)) {\n ledger.costUsd += event.costUsd\n }\n },\n cost: snapshotCost,\n complete(input) {\n // JS callers can bypass the `Exclude<…, 'running'>` type; enforce the\n // state machine at runtime as well.\n if ((input.status as RuntimeRunStatus) === 'running') {\n throw new ValidationError('complete() requires a terminal status, got \"running\"')\n }\n if (status !== 'running') {\n if (status === input.status) return\n throw new RuntimeRunStateError(\n `Cannot transition runtime run from \"${status}\" to \"${input.status}\"`,\n )\n }\n status = input.status\n completedAtMs = now()\n resultSummary = input.resultSummary\n error = input.error\n completionMetadata = input.metadata\n if (input.cost) {\n if (typeof input.cost.tokensIn === 'number' && Number.isFinite(input.cost.tokensIn)) {\n ledger.tokensIn = input.cost.tokensIn\n }\n if (typeof input.cost.tokensOut === 'number' && Number.isFinite(input.cost.tokensOut)) {\n ledger.tokensOut = input.cost.tokensOut\n }\n if (typeof input.cost.costUsd === 'number' && Number.isFinite(input.cost.costUsd)) {\n ledger.costUsd = input.cost.costUsd\n }\n if (typeof input.cost.llmCalls === 'number' && Number.isFinite(input.cost.llmCalls)) {\n ledger.llmCalls = input.cost.llmCalls\n }\n }\n },\n toRow(metadata) {\n return buildRow(metadata)\n },\n async persist(metadata) {\n if (status === 'running') {\n throw new RuntimeRunStateError('Cannot persist a runtime run before complete() is called')\n }\n if (!options.adapter) return\n await options.adapter.upsert(buildRow(metadata))\n },\n }\n}\n\nfunction mergeMetadata(\n base: Record<string, unknown> | undefined,\n extra: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !extra) return undefined\n return { ...(base ?? {}), ...(extra ?? {}) }\n}\n\nfunction randomSuffix(): string {\n // 8 chars of base36 — sufficient for in-process uniqueness. Callers needing\n // stronger guarantees pass `options.id` explicitly.\n return Math.random().toString(36).slice(2, 10)\n}\n","/**\n *\n * Server-Sent Events serialization for runtime telemetry streams.\n *\n * Newline-safe by construction: any newline in `id` or `event` is collapsed to\n * a space (browsers terminate fields on newline), and multi-line `data`\n * payloads are split into one `data:` line per source line so JSON.stringify\n * output transports cleanly.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\nimport type { RuntimeTelemetryOptions } from './sanitize'\nimport { sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent } from './sanitize'\nimport type { RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport interface ServerSentEventOptions {\n event?: string\n id?: string\n retry?: number\n}\n\n/** @stable */\nexport function encodeServerSentEvent(data: unknown, options: ServerSentEventOptions = {}): string {\n const lines: string[] = []\n if (options.id) lines.push(`id: ${stripNewlines(options.id)}`)\n if (options.event) lines.push(`event: ${stripNewlines(options.event)}`)\n if (typeof options.retry === 'number' && Number.isFinite(options.retry) && options.retry >= 0) {\n lines.push(`retry: ${Math.floor(options.retry)}`)\n }\n\n const payload = typeof data === 'string' ? data : JSON.stringify(data)\n for (const line of payload.split(/\\r?\\n/)) {\n lines.push(`data: ${line}`)\n }\n return `${lines.join('\\n')}\\n\\n`\n}\n\n/** Serialize a `KnowledgeReadinessReport` as a Server-Sent Event string. @stable */\nexport function readinessServerSentEvent(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(\n {\n type: 'readiness',\n readiness: sanitizeKnowledgeReadinessReport(report, telemetryOptions),\n },\n { event, id, retry },\n )\n}\n\n/** Serialize a `RuntimeStreamEvent` as a Server-Sent Event string. @stable */\nexport function runtimeStreamServerSentEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event: sseEvent, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(sanitizeRuntimeStreamEvent(event, telemetryOptions), {\n event: sseEvent,\n id,\n retry,\n })\n}\n\nfunction stripNewlines(value: string): string {\n return value.replace(/[\\r\\n]/g, ' ')\n}\n","/**\n * Bounded turn-level tool-dispatch loop.\n *\n * `runAgentTaskStream` runs ONE model turn; `runLoop` orchestrates DELEGATED\n * multi-agent topologies (refine / fanout-vote). Neither is the everyday\n * interactive shape: a chat turn where the model may emit tool calls, each is\n * executed, the results are folded back, and the turn re-runs until the model\n * stops (or a turn cap). Every agent app hand-rolls that loop — this is it,\n * as a reusable primitive.\n *\n * Substrate-neutral by design: the caller supplies `streamTurn` (wrapping\n * whatever backend / `runAgentTaskStream` it uses) and `executeToolCall`\n * (routing to its executors). This module owns the LOOP; the caller owns the\n * model and the executors. `Raw` (streaming variant) is the caller's own\n * event type. The only imported contract is the runtime hook type: hooks are\n * execution-scoped observers, not part of the agent profile.\n */\n\nimport type { RuntimeDecisionEvidenceRef, RuntimeHooks } from './runtime-hooks'\nimport { notifyRuntimeDecisionPoint, notifyRuntimeHookEvent } from './runtime-hooks'\n\nexport interface ToolLoopCall {\n toolCallId?: string\n toolName: string\n args: Record<string, unknown>\n}\n\n/** Outcome of one tool dispatch — structurally compatible with a hub/integration\n * tool-outcome union, so callers can fold either through the loop. */\nexport type ToolCallOutcome =\n | { ok: true; result: unknown }\n | { ok: false; code: string; message: string; status?: number }\n\n/** Runaway-backstop: stops an infinite tool loop where cost is unmetered. Set\n * far above any legitimate workflow — this is a watchdog, not a policy cap.\n * Legitimate per-call budgets come from `maxCostUsd` + `costOf`. */\nconst RUNAWAY_BACKSTOP_TURNS = 200\nconst DEFAULT_DECISION_CONTEXT_CHARS = 12_000\nconst FAILURE_RECOVERY_ACTIONS = ['retry', 'verify', 'continue', 'stop']\n/** Consecutive identical calls (same tool + canonical-JSON args) that trigger\n * stuck-loop detection. The window resets on any different call. */\nconst STUCK_LOOP_THRESHOLD = 3\n\n/** One OpenAI-shaped tool-call entry carried on an assistant message. */\nexport interface ToolLoopAssistantToolCall {\n id: string\n type: 'function'\n function: { name: string; arguments: string }\n}\n\n/**\n * A message in the running conversation the loop sends to `streamTurn`.\n *\n * The base `{ role, content }` covers `system` / `user` / plain `assistant`\n * turns. Two optional fields carry the OpenAI function-calling contract so a\n * strict model (Claude, and any OpenAI-compatible provider that validates tool\n * history) reads its own tool use back instead of re-issuing the same call:\n *\n * - an assistant turn that emitted tool calls carries `tool_calls`, and its\n * `content` is `null` when the turn was tool-only;\n * - each tool result is its own `{ role: 'tool', tool_call_id, content }`\n * message keyed to the call that produced it.\n *\n * Widening is additive: a `streamTurn` that reads only `role` + `content` still\n * works; one that forwards the whole message to an OpenAI-compatible endpoint\n * now sends correct tool history.\n */\nexport type ToolLoopMessage = {\n role: string\n content: string | null\n tool_calls?: ToolLoopAssistantToolCall[]\n tool_call_id?: string\n}\n\n/** A tool-call id is required to key a `role: 'tool'` result back to its call.\n * When the model omitted one, derive a stable id from the tool name so the\n * assistant `tool_calls` entry and its `tool` result still match. */\nfunction toolCallId(call: ToolLoopCall): string {\n return call.toolCallId ?? `call_${call.toolName}`\n}\n\n/** The assistant turn that emitted `pending`, in OpenAI shape: text content\n * (null when the turn was tool-only) plus its `tool_calls` array. */\nfunction assistantToolCallMessage(turnText: string, pending: ToolLoopCall[]): ToolLoopMessage {\n return {\n role: 'assistant',\n content: turnText.trim() || null,\n tool_calls: pending.map((call) => ({\n id: toolCallId(call),\n type: 'function',\n function: { name: call.toolName, arguments: JSON.stringify(call.args) },\n })),\n }\n}\n\n/** One `role: 'tool'` result message keyed to its call by `tool_call_id`. */\nfunction toolResultMessage(call: ToolLoopCall, content: string): ToolLoopMessage {\n return { role: 'tool', tool_call_id: toolCallId(call), content }\n}\n\nfunction defaultRender(label: string, outcome: ToolCallOutcome): string {\n if (outcome.ok) return `- ${label} → ok: ${JSON.stringify(outcome.result)}`\n return `- ${label} → failed (${outcome.code}): ${outcome.message}`\n}\n\n// ── Awaitable variant (drain-only callers, tests) ──────────────────────────\n\nexport type ToolLoopEvent =\n | { type: 'text'; text: string }\n | { type: 'tool_call'; call: ToolLoopCall }\n | { type: 'other'; event: unknown }\n\n/** Why the loop stopped. `completed` = model finished naturally; `stuck-loop` =\n * ≥3 consecutive identical tool calls (same tool + args); `backstop` = hit the\n * runaway-backstop cap (200 by default); `deadline` = wall-clock deadlineMs\n * exceeded; `budget` = maxCostUsd exhausted. Non-`completed` stops are infra /\n * resource outcomes — eval scoring must distinguish them from capability failure. */\nexport type ToolLoopStopReason = 'completed' | 'stuck-loop' | 'backstop' | 'deadline' | 'budget'\n\nexport interface ToolLoopResult {\n finalText: string\n toolResults: Array<{ call: ToolLoopCall; label: string; outcome: ToolCallOutcome }>\n turns: number\n stopReason: ToolLoopStopReason\n /** @deprecated Use `stopReason !== 'completed'` instead. */\n cappedOut: boolean\n}\n\nexport interface RunToolLoopOptions {\n systemPrompt: string\n userMessage: string\n priorMessages?: ToolLoopMessage[]\n streamTurn: (messages: ToolLoopMessage[]) => AsyncIterable<ToolLoopEvent>\n executeToolCall: (call: ToolLoopCall) => Promise<ToolCallOutcome>\n isExecutableTool: (toolName: string) => boolean\n /** Runaway-backstop cap. Default 200 — set far above any legitimate workflow.\n * For per-workflow limits, use `maxCostUsd` or `deadlineMs` instead. */\n maxToolTurns?: number\n /** Wall-clock deadline in ms since epoch (Date.now()-based). When exceeded the\n * loop stops with stopReason `deadline`. */\n deadlineMs?: number\n /** Maximum total cost in USD. Requires `costOf` to meter each tool call. */\n maxCostUsd?: number\n /** Return the USD cost of one outcome. Required for `maxCostUsd` to work. */\n costOf?: (call: ToolLoopCall, outcome: ToolCallOutcome) => number\n renderResult?: (label: string, outcome: ToolCallOutcome) => string\n labelFor?: (call: ToolLoopCall) => string\n runId?: string\n scenarioId?: string\n hooks?: RuntimeHooks\n}\n\n/** Run the bounded tool loop and return the final text + every executed tool\n * outcome. Awaitable — callers needing to stream events to a UI use\n * {@link streamToolLoop}. */\nexport async function runToolLoop(opts: RunToolLoopOptions): Promise<ToolLoopResult> {\n const backstop = opts.maxToolTurns ?? RUNAWAY_BACKSTOP_TURNS\n const render = opts.renderResult ?? defaultRender\n const labelFor = opts.labelFor ?? ((c: ToolLoopCall) => c.toolName)\n const runId = opts.runId ?? `agent-run-${randomSuffix()}`\n const messages: ToolLoopMessage[] = [\n { role: 'system', content: opts.systemPrompt },\n ...(opts.priorMessages ?? []),\n { role: 'user', content: opts.userMessage },\n ]\n const observer = createToolLoopObserver(opts.hooks, runId, opts.scenarioId)\n const toolResults: ToolLoopResult['toolResults'] = []\n let finalText = ''\n let turns = 0\n let accumulatedCostUsd = 0\n // Stuck-loop detection: track the last canonical-JSON call signature and how\n // many consecutive times we've seen it.\n let lastCallHash: string | null = null\n let consecutiveCount = 0\n\n observer.loopBefore(backstop, messages.length)\n\n for (let toolTurn = 0; ; toolTurn++) {\n turns++\n\n // Wall-clock deadline check — before every new turn.\n if (opts.deadlineMs !== undefined && Date.now() >= opts.deadlineMs) {\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'deadline' })\n return { finalText, toolResults, turns, stopReason: 'deadline', cappedOut: true }\n }\n\n let turnText = ''\n const pending: ToolLoopCall[] = []\n const turnEventId = observer.turnBefore(toolTurn, messages.length)\n for await (const ev of opts.streamTurn([...messages])) {\n if (ev.type === 'text') {\n turnText += ev.text\n finalText += ev.text\n } else if (ev.type === 'tool_call' && opts.isExecutableTool(ev.call.toolName)) {\n pending.push(ev.call)\n }\n }\n if (pending.length === 0) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: 0,\n finalTextChars: finalText.length,\n })\n break\n }\n\n // Runaway backstop — the model keeps emitting calls past the safety ceiling.\n if (toolTurn >= backstop) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'backstop',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'backstop' })\n return { finalText, toolResults, turns, stopReason: 'backstop', cappedOut: true }\n }\n\n // The assistant turn that emitted the calls, carrying its tool_calls array,\n // so a strict model reads its own tool use back in OpenAI shape.\n messages.push(assistantToolCallMessage(turnText, pending))\n const outcomes: ExecutedToolCall[] = []\n for (const [callIndex, call] of pending.entries()) {\n // Stuck-loop detection: hash the first pending call each turn (a model\n // stuck in a loop re-issues the same call repeatedly, not alternating calls).\n const callHash = canonicalCallHash(call)\n if (callHash === lastCallHash) {\n consecutiveCount++\n } else {\n lastCallHash = callHash\n consecutiveCount = 1\n }\n if (consecutiveCount >= STUCK_LOOP_THRESHOLD) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'stuck-loop',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'stuck-loop' })\n return { finalText, toolResults, turns, stopReason: 'stuck-loop', cappedOut: true }\n }\n\n const callEventId = observer.toolCallBefore(toolTurn, turnEventId, callIndex, call)\n let outcome: ToolCallOutcome\n try {\n outcome = await opts.executeToolCall(call)\n } catch (err) {\n outcome = {\n ok: false,\n code: 'executor_error',\n message: err instanceof Error ? err.message : String(err),\n }\n }\n\n // Budget check after each tool call.\n if (opts.maxCostUsd !== undefined && opts.costOf !== undefined) {\n accumulatedCostUsd += opts.costOf(call, outcome)\n if (accumulatedCostUsd >= opts.maxCostUsd) {\n const label = labelFor(call)\n toolResults.push({ call, label, outcome })\n messages.push(toolResultMessage(call, render(label, outcome)))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'budget',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'budget' })\n return { finalText, toolResults, turns, stopReason: 'budget', cappedOut: true }\n }\n }\n\n const label = labelFor(call)\n const rendered = render(label, outcome)\n toolResults.push({ call, label, outcome })\n outcomes.push({ call, label, outcome, rendered })\n // One role:'tool' message per result, keyed to its call by tool_call_id.\n messages.push(toolResultMessage(call, rendered))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n }\n observer.failureRecovery({\n toolTurn,\n messages,\n turnText,\n outcomes,\n })\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n toolResults: outcomes.map((item) => ({\n toolName: item.call.toolName,\n toolCallId: item.call.toolCallId,\n ok: item.outcome.ok,\n })),\n failedToolCalls: outcomes.filter((item) => !item.outcome.ok).length,\n })\n }\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'completed' })\n return { finalText, toolResults, turns, stopReason: 'completed', cappedOut: false }\n}\n\n// ── Streaming variant (SSE chat runtimes + per-event telemetry) ────────────\n\nexport type StreamToolLoopYield<Raw> =\n | { kind: 'event'; event: Raw }\n | {\n kind: 'tool_result'\n toolName: string\n toolCallId?: string\n label: string\n outcome: ToolCallOutcome\n }\n | { kind: 'capped'; pending: number; stopReason: Exclude<ToolLoopStopReason, 'completed'> }\n\nexport interface StreamToolLoopOptions<Raw> {\n systemPrompt: string\n userMessage: string\n priorMessages?: ToolLoopMessage[]\n streamTurn: (messages: ToolLoopMessage[]) => AsyncIterable<Raw>\n extractText: (event: Raw) => string\n extractToolCall: (event: Raw) => ToolLoopCall | null\n isExecutableTool: (toolName: string) => boolean\n executeToolCall: (call: ToolLoopCall) => Promise<ToolCallOutcome>\n /** Runaway-backstop cap. Default 200 — set far above any legitimate workflow. */\n maxToolTurns?: number\n /** Wall-clock deadline in ms since epoch (Date.now()-based). */\n deadlineMs?: number\n /** Maximum total cost in USD. Requires `costOf` to meter each tool call. */\n maxCostUsd?: number\n /** Return the USD cost of one outcome. Required for `maxCostUsd` to work. */\n costOf?: (call: ToolLoopCall, outcome: ToolCallOutcome) => number\n renderResult?: (label: string, outcome: ToolCallOutcome) => string\n labelFor?: (call: ToolLoopCall) => string\n runId?: string\n scenarioId?: string\n hooks?: RuntimeHooks\n}\n\n/** Streaming bounded tool loop: yields each raw turn event (the caller maps +\n * telemetries + re-emits it) and each executed `tool_result`; emits one\n * `capped` if it stops for any non-completed reason with calls still pending. */\nexport async function* streamToolLoop<Raw>(\n opts: StreamToolLoopOptions<Raw>,\n): AsyncGenerator<StreamToolLoopYield<Raw>, void, unknown> {\n const backstop = opts.maxToolTurns ?? RUNAWAY_BACKSTOP_TURNS\n const render = opts.renderResult ?? defaultRender\n const labelFor = opts.labelFor ?? ((c: ToolLoopCall) => c.toolName)\n const runId = opts.runId ?? `agent-run-${randomSuffix()}`\n const messages: ToolLoopMessage[] = [\n { role: 'system', content: opts.systemPrompt },\n ...(opts.priorMessages ?? []),\n { role: 'user', content: opts.userMessage },\n ]\n const observer = createToolLoopObserver(opts.hooks, runId, opts.scenarioId)\n let accumulatedCostUsd = 0\n let lastCallHash: string | null = null\n let consecutiveCount = 0\n\n observer.loopBefore(backstop, messages.length)\n\n for (let toolTurn = 0; ; toolTurn++) {\n // Wall-clock deadline check before every new turn.\n if (opts.deadlineMs !== undefined && Date.now() >= opts.deadlineMs) {\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'deadline' })\n yield { kind: 'capped', pending: 0, stopReason: 'deadline' }\n return\n }\n\n let turnText = ''\n const pending: ToolLoopCall[] = []\n const turnEventId = observer.turnBefore(toolTurn, messages.length)\n for await (const event of opts.streamTurn([...messages])) {\n yield { kind: 'event', event }\n turnText += opts.extractText(event)\n const call = opts.extractToolCall(event)\n if (call && opts.isExecutableTool(call.toolName)) pending.push(call)\n }\n if (pending.length === 0) {\n observer.turnAfter(toolTurn, turnEventId, { pendingToolCalls: 0 })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'completed' })\n return\n }\n\n // Runaway backstop.\n if (toolTurn >= backstop) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'backstop',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'backstop' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'backstop' }\n return\n }\n\n // The assistant turn that emitted the calls, carrying its tool_calls array,\n // so a strict model reads its own tool use back in OpenAI shape.\n messages.push(assistantToolCallMessage(turnText, pending))\n const outcomes: ExecutedToolCall[] = []\n for (const [callIndex, call] of pending.entries()) {\n // Stuck-loop detection.\n const callHash = canonicalCallHash(call)\n if (callHash === lastCallHash) {\n consecutiveCount++\n } else {\n lastCallHash = callHash\n consecutiveCount = 1\n }\n if (consecutiveCount >= STUCK_LOOP_THRESHOLD) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'stuck-loop',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'stuck-loop' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'stuck-loop' }\n return\n }\n\n const callEventId = observer.toolCallBefore(toolTurn, turnEventId, callIndex, call)\n let outcome: ToolCallOutcome\n try {\n outcome = await opts.executeToolCall(call)\n } catch (err) {\n outcome = {\n ok: false,\n code: 'executor_error',\n message: err instanceof Error ? err.message : String(err),\n }\n }\n\n // Budget check after each tool call.\n if (opts.maxCostUsd !== undefined && opts.costOf !== undefined) {\n accumulatedCostUsd += opts.costOf(call, outcome)\n if (accumulatedCostUsd >= opts.maxCostUsd) {\n const label = labelFor(call)\n yield {\n kind: 'tool_result',\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n label,\n outcome,\n }\n messages.push(toolResultMessage(call, render(label, outcome)))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'budget',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'budget' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'budget' }\n return\n }\n }\n\n const label = labelFor(call)\n yield {\n kind: 'tool_result',\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n label,\n outcome,\n }\n const rendered = render(label, outcome)\n outcomes.push({ call, label, outcome, rendered })\n // One role:'tool' message per result, keyed to its call by tool_call_id.\n messages.push(toolResultMessage(call, rendered))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n }\n observer.failureRecovery({\n toolTurn,\n messages,\n turnText,\n outcomes,\n })\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n toolResults: outcomes.map((item) => ({\n toolName: item.call.toolName,\n toolCallId: item.call.toolCallId,\n ok: item.outcome.ok,\n })),\n failedToolCalls: outcomes.filter((item) => !item.outcome.ok).length,\n })\n }\n}\n\ninterface ExecutedToolCall {\n call: ToolLoopCall\n label: string\n outcome: ToolCallOutcome\n rendered: string\n}\n\ninterface NotifyToolFailureRecoveryOptions {\n hooks?: RuntimeHooks\n runId: string\n scenarioId?: string\n stepIndex: number\n messages: ToolLoopMessage[]\n turnText: string\n outcomes: ExecutedToolCall[]\n}\n\ninterface NotifyToolLoopEventOptions {\n hooks?: RuntimeHooks\n runId: string\n scenarioId?: string\n target: 'agent.run' | 'agent.turn' | 'agent.tool_call'\n phase: 'before' | 'after' | 'error' | 'event'\n id?: string\n stepIndex?: number\n parentId?: string\n payload?: Record<string, unknown>\n metadata?: Record<string, unknown>\n}\n\ninterface ToolLoopObserver {\n loopBefore(maxToolTurns: number, messageCount: number): void\n loopAfter(payload: Record<string, unknown>): void\n turnBefore(toolTurn: number, messageCount: number): string\n turnAfter(toolTurn: number, turnEventId: string, payload: Record<string, unknown>): void\n toolCallBefore(\n toolTurn: number,\n turnEventId: string,\n callIndex: number,\n call: ToolLoopCall,\n ): string\n toolCallAfter(\n toolTurn: number,\n callEventId: string,\n call: ToolLoopCall,\n outcome: ToolCallOutcome,\n ): void\n failureRecovery(options: {\n toolTurn: number\n messages: ToolLoopMessage[]\n turnText: string\n outcomes: ExecutedToolCall[]\n }): void\n}\n\nfunction createToolLoopObserver(\n hooks: RuntimeHooks | undefined,\n runId: string,\n scenarioId: string | undefined,\n): ToolLoopObserver {\n const loopEventId = `${runId}:agent.run`\n return {\n loopBefore: (maxToolTurns, messageCount) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.run',\n phase: 'before',\n id: `${loopEventId}:before`,\n payload: { maxToolTurns, messageCount },\n })\n },\n loopAfter: (payload) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.run',\n phase: 'after',\n id: `${loopEventId}:after`,\n payload,\n })\n },\n turnBefore: (toolTurn, messageCount) => {\n const turnEventId = `${loopEventId}:${toolTurn}`\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.turn',\n phase: 'before',\n id: turnEventId,\n stepIndex: toolTurn,\n parentId: loopEventId,\n payload: { messageCount },\n })\n return turnEventId\n },\n turnAfter: (toolTurn, turnEventId, payload) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.turn',\n phase: 'after',\n id: `${turnEventId}:after`,\n stepIndex: toolTurn,\n parentId: turnEventId,\n payload,\n })\n },\n toolCallBefore: (toolTurn, turnEventId, callIndex, call) => {\n const callEventId = `${turnEventId}:tool-call:${callIndex}`\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.tool_call',\n phase: 'before',\n id: callEventId,\n stepIndex: toolTurn,\n parentId: turnEventId,\n payload: toolCallPayload(call),\n })\n return callEventId\n },\n toolCallAfter: (toolTurn, callEventId, call, outcome) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.tool_call',\n phase: 'after',\n id: `${callEventId}:after`,\n stepIndex: toolTurn,\n parentId: callEventId,\n payload: { ...toolCallPayload(call), outcome: outcomePayload(outcome) },\n })\n },\n failureRecovery: (options) => {\n notifyToolFailureRecovery({\n hooks,\n runId,\n scenarioId,\n stepIndex: options.toolTurn,\n messages: options.messages,\n turnText: options.turnText,\n outcomes: options.outcomes,\n })\n },\n }\n}\n\nfunction notifyToolLoopEvent(options: NotifyToolLoopEventOptions): void {\n notifyRuntimeHookEvent(options.hooks, {\n id: options.id ?? `${options.runId}:${options.target}:${options.phase}`,\n runId: options.runId,\n scenarioId: options.scenarioId,\n target: options.target,\n phase: options.phase,\n timestamp: Date.now(),\n stepIndex: options.stepIndex,\n parentId: options.parentId,\n payload: options.payload,\n metadata: { producer: 'tool-loop', ...options.metadata },\n })\n}\n\nfunction notifyToolFailureRecovery(options: NotifyToolFailureRecoveryOptions): void {\n const failed = options.outcomes.filter((item) => !item.outcome.ok)\n if (failed.length === 0) return\n\n const evidence: RuntimeDecisionEvidenceRef[] = []\n for (const item of failed) {\n const id = item.call.toolCallId ?? `${options.stepIndex}:${item.label}`\n evidence.push({\n source: 'tool_call',\n id,\n detail: `${item.call.toolName} ${stringifySafe(item.call.args, 2_000)}`,\n metadata: { toolName: item.call.toolName, label: item.label },\n })\n evidence.push({\n source: 'tool_result',\n id: `${id}:result`,\n detail: item.rendered,\n metadata: failureMetadata(item.outcome),\n })\n }\n\n notifyRuntimeDecisionPoint(options.hooks, {\n id: `${options.runId}:agent.turn:${options.stepIndex}:failure-recovery`,\n runId: options.runId,\n scenarioId: options.scenarioId,\n stepIndex: options.stepIndex,\n kind: 'retry',\n candidateActions: [...FAILURE_RECOVERY_ACTIONS],\n context: renderDecisionContext(options.messages, options.turnText, options.outcomes),\n evidence,\n metadata: {\n target: 'failure-recovery',\n source: 'agent.turn',\n failedToolCount: failed.length,\n toolNames: failed.map((item) => item.call.toolName),\n },\n })\n}\n\nfunction toolCallPayload(call: ToolLoopCall): Record<string, unknown> {\n return {\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n argsPreview: stringifySafe(call.args, 2_000),\n }\n}\n\nfunction outcomePayload(outcome: ToolCallOutcome): Record<string, unknown> {\n if (!outcome.ok) {\n return {\n ok: false,\n code: outcome.code,\n message: trimText(outcome.message, 2_000),\n status: outcome.status,\n }\n }\n return {\n ok: true,\n resultPreview: stringifySafe(outcome.result, 2_000),\n }\n}\n\nfunction failureMetadata(outcome: ToolCallOutcome): Record<string, unknown> | undefined {\n if (outcome.ok) return undefined\n return {\n code: outcome.code,\n message: outcome.message,\n status: outcome.status,\n }\n}\n\nfunction renderDecisionContext(\n messages: ToolLoopMessage[],\n turnText: string,\n outcomes: ExecutedToolCall[],\n): string {\n const recent = messages.slice(-6).map((message) => `[${message.role}]\\n${message.content ?? ''}`)\n const assistant = turnText.trim() ? [`[assistant]\\n${turnText}`] : []\n const toolResults = [`[tool results]\\n${outcomes.map((item) => item.rendered).join('\\n')}`]\n return trimText(\n [...recent, ...assistant, ...toolResults].join('\\n\\n'),\n DEFAULT_DECISION_CONTEXT_CHARS,\n )\n}\n\n/** Canonical identifier for a tool call used by stuck-loop detection.\n * Keys are sorted so `{b:1,a:2}` and `{a:2,b:1}` produce the same hash. */\nfunction canonicalCallHash(call: ToolLoopCall): string {\n const sortedArgs = Object.fromEntries(\n Object.entries(call.args).sort(([a], [b]) => a.localeCompare(b)),\n )\n return `${call.toolName}:${JSON.stringify(sortedArgs)}`\n}\n\nfunction stringifySafe(value: unknown, max: number): string {\n let text: string\n try {\n text = JSON.stringify(value) ?? String(value)\n } catch {\n text = String(value)\n }\n return trimText(text, max)\n}\n\nfunction trimText(text: string, max: number): string {\n if (text.length <= max) return text\n return `${text.slice(0, max)}…`\n}\n\nfunction randomSuffix(len = 8): string {\n return Math.random()\n .toString(36)\n .slice(2, 2 + len)\n}\n"],"mappings":"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","names":["emit","randomSuffix","label"]}
1
+ {"version":3,"sources":["../src/durable/chat-engine.ts","../src/durable/execution-handle.ts","../src/improvement/build-prompts.ts","../src/improvement/mcp-serve-verifier.ts","../src/improvement/profile-diff-proposer.ts","../src/improvement/reflective-generator.ts","../src/readiness.ts","../src/resolve-agent-backend.ts","../src/run.ts","../src/runtime-run.ts","../src/sse.ts","../src/tool-loop.ts"],"sourcesContent":["/**\n * `handleChatTurn` — framework-neutral chat-turn HTTP orchestrator.\n * Owns the NDJSON `ChatStreamEvent` line protocol, the `session.run.*`\n * lifecycle vocabulary, and the persist / post-process / trace-flush\n * hook order. Returns a `ReadableStream` body the product hands to its\n * platform `Response`.\n *\n * Execution durability is the substrate's concern: `box.streamPrompt`\n * auto-reconnects in-call; cross-process reconnect via `X-Execution-ID`\n * is the product's job. The producer this engine wraps already speaks\n * that protocol — the engine just frames the events.\n *\n * Hooks (`ChatTurnHooks`):\n * - `produce` — build the backend event stream\n * - `persistAssistantMessage` — write the assistant turn to the product DB\n * - `onTurnComplete?` — post-process (proposals, citations, …)\n * - `onEvent?` — per-event side channel (e.g. DO broadcast)\n * - `transformFinalText?` — pre-persist transform (e.g. PII redact)\n * - `traceFlush?` — handed to waitUntil so OTLP export lands\n *\n * Framework neutrality: takes already-resolved values (`identity` tuple,\n * a `waitUntil`), never a `Request` or a `Context`. The product's thin\n * route adapter does auth + parse + access-control, then calls\n * `handleChatTurn(...)` and returns `result.body` as its platform `Response`.\n */\n\n/** The NDJSON line protocol every product chat client already speaks. */\nexport interface ChatStreamEvent {\n type: string\n data?: Record<string, unknown>\n}\n\n/** Identity of a chat turn. `tenantId` is the workspace id for workspace-\n * scoped products and the user id for session-scoped products. */\nexport interface ChatTurnIdentity {\n tenantId: string\n /** Thread / session id. */\n sessionId: string\n userId: string\n /** Monotonic 0-based turn index within the session. */\n turnIndex: number\n}\n\n/** The live side of a turn — what the product's `produce` hook returns. */\nexport interface ChatTurnProducer<TEvent extends ChatStreamEvent = ChatStreamEvent> {\n /** The turn's event stream. Forwarded verbatim to the caller. */\n stream: AsyncGenerator<TEvent, void, unknown>\n /** The turn's final assistant text. Read once, after `stream` drains. */\n finalText(): string\n}\n\nexport interface ChatTurnHooks {\n /** Build the backend stream. The engine forwards events verbatim and\n * reads `finalText()` once the stream drains. */\n produce(): ChatTurnProducer\n /** Persist the assistant message to the product's own store. Called\n * once, after drain, with the assembled (transform-applied) text. */\n persistAssistantMessage(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional post-processing (proposals, citations, credit metering …).\n * Errors are swallowed + logged — post-process must never fail a turn\n * that already streamed successfully. */\n onTurnComplete?(input: { identity: ChatTurnIdentity; finalText: string }): Promise<void>\n /** Optional per-event side channel (e.g. DO broadcast). Runs for every\n * emitted event, lifecycle envelope included. Errors swallowed — a\n * broadcast failure must not break the chat stream. */\n onEvent?(event: ChatStreamEvent): void | Promise<void>\n /** Optional pre-persist transform of the final text (e.g. PII\n * redaction). Affects only what is persisted; the live stream is\n * never altered. */\n transformFinalText?(text: string): string | Promise<string>\n /** Optional trace flush — resolves when OTLP export completes. Handed\n * to `waitUntil` so the worker isolate stays alive for the POST. */\n traceFlush?(): Promise<void>\n}\n\nexport interface RunChatTurnInput {\n identity: ChatTurnIdentity\n hooks: ChatTurnHooks\n /** Worker liveness hook. When omitted, trace flush is awaited inline\n * before the stream closes. */\n waitUntil?: (p: Promise<unknown>) => void\n /** Structured logger for swallowed hook errors. Defaults to\n * `console.error` so failures surface without product wiring. */\n log?: (message: string, meta?: Record<string, unknown>) => void\n}\n\nexport interface ChatTurnResult {\n /** NDJSON body — return this as the platform `Response` body. */\n body: ReadableStream<Uint8Array>\n /** Content type for the response. */\n contentType: 'application/x-ndjson'\n}\n\nconst encoder = new TextEncoder()\n\nfunction encodeLine(event: ChatStreamEvent): Uint8Array {\n return encoder.encode(`${JSON.stringify(event)}\\n`)\n}\n\nfunction defaultLog(message: string, meta?: Record<string, unknown>): void {\n if (meta) console.error(message, meta)\n else console.error(message)\n}\n\n/**\n * Run one chat turn. Returns immediately with a `ReadableStream` body;\n * the turn executes as the body is pulled. Never rejects — backend\n * failures surface as `error` + `session.run.failed` events.\n */\nexport function handleChatTurn(input: RunChatTurnInput): ChatTurnResult {\n const log = input.log ?? defaultLog\n const { identity, hooks } = input\n\n const body = new ReadableStream<Uint8Array>({\n start: async (controller) => {\n const emit = async (event: ChatStreamEvent): Promise<void> => {\n controller.enqueue(encodeLine(event))\n if (hooks.onEvent) {\n try {\n await hooks.onEvent(event)\n } catch (err) {\n log('[chat-engine] onEvent hook threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n }\n\n try {\n await emit({\n type: 'session.run.started',\n data: {\n sessionId: identity.sessionId,\n tenantId: identity.tenantId,\n turnIndex: identity.turnIndex,\n },\n })\n\n const producer = hooks.produce()\n for await (const event of producer.stream) {\n await emit(event)\n }\n const rawFinal = producer.finalText()\n const finalText = hooks.transformFinalText\n ? await hooks.transformFinalText(rawFinal)\n : rawFinal\n\n await hooks.persistAssistantMessage({ identity, finalText })\n if (hooks.onTurnComplete) {\n try {\n await hooks.onTurnComplete({ identity, finalText })\n } catch (err) {\n log('[chat-engine] onTurnComplete threw', {\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n await emit({\n type: 'session.run.completed',\n data: { sessionId: identity.sessionId },\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n log('[chat-engine] turn failed', { error: message })\n await emit({ type: 'error', data: { message } })\n await emit({\n type: 'session.run.failed',\n data: { sessionId: identity.sessionId, message },\n })\n } finally {\n if (hooks.traceFlush) {\n const flush = hooks.traceFlush().catch((err) =>\n log('[chat-engine] traceFlush threw', {\n error: err instanceof Error ? err.message : String(err),\n }),\n )\n if (input.waitUntil) input.waitUntil(flush)\n else await flush\n }\n controller.close()\n }\n },\n })\n\n return { body, contentType: 'application/x-ndjson' }\n}\n","/**\n * Derive a stable executionId from the run identity. The same\n * `(projectId, sessionId, turnIndex)` tuple yields the same id — so a\n * client retry of the same turn lands on the same substrate execution\n * and the orchestrator's buffer replays instead of starting a second\n * prompt.\n *\n * Format is readable, not hashed: operators grepping orchestrator logs\n * for `gtm-agent:thread-abc:3` find the run without translating an\n * opaque id. Substrate executionIds are not a secrecy boundary.\n *\n * Wire integration:\n * - Sandbox PromptOptions accepts `executionId` and `lastEventId`.\n * Products pass this id to make cross-process reconnect land on the\n * same substrate execution instead of spawning a duplicate run.\n */\nexport function deriveExecutionId(input: {\n projectId: string\n sessionId: string\n turnIndex: number\n}): string {\n return `${input.projectId}:${input.sessionId}:${input.turnIndex}`\n}\n","/**\n * Build-prompt starting points for the two buildable artifact types. There is\n * NO `toolGenerator`/`mcpGenerator` wrapper — the factory is `agenticGenerator`\n * + a verifier (docs/artifact-lifecycle-frontier.md), so a tool or an MCP\n * server is built by composing the pieces directly:\n *\n * // a tool:\n * agenticGenerator({ buildPrompt: toolBuildPrompt, verify: commandVerifier('pnpm', ['test']) })\n * // an MCP server:\n * agenticGenerator({ buildPrompt: mcpBuildPrompt, verify: mcpServeVerifier({ command: 'node', args: ['server.mjs'] }) })\n *\n * These are the only type-specific bit (the phrasing that points the agent at a\n * tool vs. an MCP); the worktree, resume-on-failure loop, and improvement-loop\n * wrapper are shared. MCP is the load-bearing target — it is how a harness\n * acquires tools; raw tools matter where we control the loader.\n */\n\nimport type { AnalystFinding } from '@tangle-network/agent-eval'\n\ntype FindingsArg = { report: unknown; findings: AnalystFinding[] }\n\nfunction findingLines(findings: AnalystFinding[]): string[] {\n return findings.map((f) => {\n const where = f.subject ? ` [${f.subject}]` : ''\n const action = f.recommended_action ? ` → ${f.recommended_action}` : ''\n return `- (${f.severity})${where} ${f.claim}${action}`\n })\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new tool. */\nexport function toolBuildPrompt(args: FindingsArg): string {\n return [\n 'You are building a new TOOL for this codebase to address the gaps below.',\n 'Write the tool as a small, self-contained module PLUS tests that exercise it.',\n 'The tool must compile and its tests must pass — they will be run automatically;',\n 'if verification fails you will get the error and another attempt. Do not commit;',\n 'leave the changes in the working tree.',\n '',\n 'Gaps the tool should close:',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n\n/** Build the starting instruction for a coder agent tasked with implementing a new MCP server. */\nexport function mcpBuildPrompt(args: FindingsArg): string {\n return [\n 'You are building a new MCP SERVER (Model Context Protocol) that exposes',\n 'tool(s) addressing the gaps below, so any harness can mount it.',\n 'Requirements that WILL be checked by booting the server:',\n '- it starts over stdio and answers the MCP `initialize` handshake,',\n '- `tools/list` returns at least one tool with a valid input schema.',\n 'Newline-delimited JSON-RPC 2.0, protocol version 2024-11-05. Include a start',\n 'command (e.g. a package.json `start` script or a clear entrypoint). If the',\n 'boot-and-probe fails you will get the error and another attempt. Do not',\n 'commit; leave the changes in the working tree.',\n '',\n 'Capabilities the server should provide:',\n ...findingLines(args.findings),\n ].join('\\n')\n}\n","/**\n * `mcpServeVerifier` — the intrinsic verifier for a built MCP server: the\n * boot-and-probe checker named in docs/artifact-lifecycle-frontier.md. A\n * generated MCP server is only a candidate if it actually *serves* — so this\n * boots it over stdio (the default local MCP transport) and runs the real\n * handshake: `initialize` → `notifications/initialized` → `tools/list`, and\n * asserts the server answers with at least `minTools` tools.\n *\n * Outcomes follow the `Verifier` contract: a server that fails to start, exits\n * early, errors the handshake, times out, or exposes no tools is a FAILED\n * candidate (`{ok:false}`, fed back into the next generation shot); a missing\n * start binary or spawn fault THROWS (a setup bug, never a silent fallback).\n *\n * Protocol matches the runtime's own stdio MCP server (src/mcp/server.ts):\n * newline-delimited JSON-RPC 2.0, protocol version 2024-11-05.\n */\n\nimport { spawn } from 'node:child_process'\nimport { createInterface } from 'node:readline'\nimport type { Verifier, VerifyResult } from './agentic-generator'\n\nconst PROTOCOL_VERSION = '2024-11-05'\n\nexport interface McpServeSpec {\n /** Command that starts the built MCP server in the worktree (stdio transport). */\n command: string\n args?: string[]\n /** Extra env for the server process (merged over `process.env`). */\n env?: Record<string, string>\n /** Handshake timeout (ms). Default 30s. */\n timeoutMs?: number\n /** Minimum tools the server must expose to pass. Default 1. */\n minTools?: number\n}\n\ninterface JsonRpcResponse {\n jsonrpc?: string\n id?: number | string | null\n result?: unknown\n error?: { code: number; message: string }\n}\n\n/** Build a `Verifier` that boots a generated MCP server over stdio and checks it exposes tools. */\nexport function mcpServeVerifier(spec: McpServeSpec): Verifier {\n const timeoutMs = spec.timeoutMs ?? 30_000\n const minTools = spec.minTools ?? 1\n\n return (worktreePath: string): Promise<VerifyResult> =>\n new Promise<VerifyResult>((resolve, reject) => {\n const child = spawn(spec.command, spec.args ?? [], {\n cwd: worktreePath,\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env, ...spec.env },\n })\n\n const stderr: string[] = []\n let settled = false\n let nextId = 1\n const initId = nextId++\n let listId = -1\n\n const settle = (fn: () => void) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n rl.close()\n child.kill('SIGKILL')\n fn()\n }\n const withStderr = (msg: string) =>\n stderr.length > 0 ? `${msg}\\nstderr:\\n${stderr.join('').slice(-2000)}` : msg\n const pass = () => settle(() => resolve({ ok: true }))\n const failCandidate = (msg: string) =>\n settle(() => resolve({ ok: false, feedback: withStderr(msg) }))\n const setupFault = (err: Error) => settle(() => reject(err))\n const failStdin = (err: Error) =>\n failCandidate(`writing to MCP server stdin failed: ${err.message}`)\n\n const send = (msg: Record<string, unknown>): boolean => {\n try {\n child.stdin.write(`${JSON.stringify(msg)}\\n`)\n return true\n } catch (err) {\n // EPIPE: the server died mid-handshake — a failed candidate, not a fault.\n failStdin(err as Error)\n return false\n }\n }\n\n child.on('error', (err) => {\n const code = (err as NodeJS.ErrnoException).code\n setupFault(\n code === 'ENOENT'\n ? new Error(\n `mcpServeVerifier: '${spec.command}' not found in PATH (setup bug, not a failed candidate)`,\n )\n : new Error(`mcpServeVerifier: '${spec.command}' failed to spawn: ${err.message}`),\n )\n })\n child.on('exit', (code, signal) => {\n // An exit before the handshake completes is a failed candidate (the\n // server crashed on boot); after we settle, our own SIGKILL fires here.\n failCandidate(`MCP server exited (code ${code}, signal ${signal}) before serving`)\n })\n // Pipe failures normally arrive asynchronously, outside send()'s try/catch.\n child.stdin.on('error', failStdin)\n child.stderr.on('data', (d) => stderr.push(String(d)))\n\n const rl = createInterface({ input: child.stdout })\n rl.on('line', (line) => {\n let msg: JsonRpcResponse | undefined\n try {\n msg = JSON.parse(line) as JsonRpcResponse\n } catch {\n return // servers log to stdout too; skip non-JSON lines\n }\n if (!msg || typeof msg !== 'object') return\n\n if (msg.id === initId) {\n if (msg.error) return failCandidate(`initialize errored: ${JSON.stringify(msg.error)}`)\n if (!send({ jsonrpc: '2.0', method: 'notifications/initialized' })) return\n listId = nextId++\n send({ jsonrpc: '2.0', id: listId, method: 'tools/list' })\n return\n }\n if (msg.id === listId) {\n if (msg.error) return failCandidate(`tools/list errored: ${JSON.stringify(msg.error)}`)\n const tools = (msg.result as { tools?: unknown[] } | undefined)?.tools\n if (!Array.isArray(tools)) return failCandidate('tools/list result has no tools array')\n if (tools.length < minTools) {\n return failCandidate(`tools/list returned ${tools.length} tool(s), need >= ${minTools}`)\n }\n return pass()\n }\n })\n\n const timer = setTimeout(\n () => failCandidate(`MCP server did not complete the handshake within ${timeoutMs}ms`),\n timeoutMs,\n )\n\n send({\n jsonrpc: '2.0',\n id: initId,\n method: 'initialize',\n params: {\n protocolVersion: PROTOCOL_VERSION,\n capabilities: {},\n clientInfo: { name: 'agent-runtime-mcp-verify', version: '0' },\n },\n })\n })\n}\n","import { canonicalJson } from '@tangle-network/agent-eval'\nimport type {\n MutableSurface,\n ProposeContext,\n ProposedCandidate,\n SurfaceProposer,\n} from '@tangle-network/agent-eval/campaign'\nimport {\n type AgentProfile,\n type AgentProfileDiff,\n changedAgentProfileAxes,\n} from '@tangle-network/agent-interface'\nimport { canonicalCandidateDigest } from '../candidate-execution/digest'\nimport {\n applyExactAgentProfileDiff,\n parseExactAgentProfile,\n parseExactAgentProfileDiff,\n} from '../candidate-execution/profile'\n\nexport type ProfileDiffProposerContext<TFindings = unknown> = ProposeContext<TFindings> & {\n profile: AgentProfile\n}\n\nexport interface ProfileDiffProposerOptions<TFindings = unknown> {\n proposeDiffs(\n context: ProfileDiffProposerContext<TFindings>,\n ): Promise<readonly AgentProfileDiff[]> | readonly AgentProfileDiff[]\n}\n\n/**\n * Turn exact AgentProfileDiffs from any source into full profile candidates for\n * the shared optimization loop. Research, catalogs, humans, and trace miners\n * differ only in `proposeDiffs`; measurement and promotion stay identical.\n */\nexport function profileDiffProposer<TFindings = unknown>(\n options: ProfileDiffProposerOptions<TFindings>,\n): SurfaceProposer<TFindings> {\n return {\n kind: 'agent-profile-diff',\n async propose(ctx): Promise<Array<MutableSurface | ProposedCandidate>> {\n if (typeof ctx.currentSurface !== 'string') {\n throw new Error('profileDiffProposer requires a serialized AgentProfile surface')\n }\n const profile = parseSerializedProfile(ctx.currentSurface)\n const proposals = await options.proposeDiffs({\n ...ctx,\n profile,\n })\n const candidates: ProposedCandidate[] = []\n const normalizedBaseline = applyExactAgentProfileDiff(\n profile,\n { kind: 'agent-profile-diff' },\n 'profile diff baseline',\n )\n const seen = new Set<string>([canonicalJson(normalizedBaseline)])\n for (const [index, proposal] of proposals.entries()) {\n if (candidates.length >= ctx.populationSize || ctx.signal.aborted) break\n const diff = parseExactAgentProfileDiff(proposal, `profile diff proposal ${index}`)\n const axes = changedAgentProfileAxes(diff)\n if (axes.length === 0) continue\n const candidate = applyExactAgentProfileDiff(\n profile,\n diff,\n `profile diff candidate ${index}`,\n )\n const surface = canonicalJson(candidate)\n if (seen.has(surface)) continue\n seen.add(surface)\n candidates.push({\n surface,\n label: diff.title ?? diff.id ?? `Change ${axes.join(', ')}`,\n rationale: candidateRationale(diff, axes),\n })\n }\n return candidates\n },\n }\n}\n\nfunction candidateRationale(diff: AgentProfileDiff, axes: readonly string[]): string {\n const reason = diff.rationale ?? `Changes profile axes: ${axes.join(', ')}.`\n const source = diff.source\n ? [diff.source.kind, ...(diff.source.artifacts ?? [])].join(' · ')\n : 'source unspecified'\n return `${reason} Source: ${source}. Diff: ${canonicalCandidateDigest(diff)}.`\n}\n\nfunction parseSerializedProfile(surface: string): AgentProfile {\n let raw: unknown\n try {\n raw = JSON.parse(surface)\n } catch (cause) {\n throw new Error('profileDiffProposer current surface is not valid AgentProfile JSON', {\n cause,\n })\n }\n return parseExactAgentProfile(raw, 'profileDiffProposer current profile')\n}\n","/**\n *\n * `reflectiveGenerator` — the cheap, no-sandbox `CandidateGenerator`. It drafts\n * surface edits via the existing improvement proposer (`proposeFromFindings`,\n * one LLM patch per finding) and applies them as ONE coherent improvement into\n * the candidate worktree. `maxShots` is ignored — reflection is single-shot by\n * construction (the patches are already drafted).\n *\n * This is the `shots=1, sandbox=off` setting of the one improvement driver.\n * The `agenticGenerator` (a multi-shot verify-in-session loop) is the\n * `shots=N` setting — both plug into the same `improvementDriver`.\n *\n * @experimental\n */\n\nimport { spawnSync } from 'node:child_process'\nimport type { SurfaceImprovementEdit } from '../agent/improvement-adapter'\nimport type { ImprovementProposalSource } from '../analyst-loop/types'\nimport type { CandidateGenerator } from './improvement-driver'\n\nexport interface ReflectiveGeneratorOptions {\n improvementProposalSource: ImprovementProposalSource<SurfaceImprovementEdit>\n}\n\n/** Cheap no-sandbox `CandidateGenerator` (the `shots=1` setting): draft surface edits via the improvement adapter and apply them as one coherent candidate. */\nexport function reflectiveGenerator(opts: ReflectiveGeneratorOptions): CandidateGenerator {\n return {\n kind: 'reflective',\n async generate({ worktreePath, findings }) {\n const batch = await opts.improvementProposalSource.proposeFromFindings(findings)\n if (batch.edits.length === 0) return { applied: false, summary: '' }\n\n let applied = 0\n for (const edit of batch.edits) {\n if (applyPatch(edit.patch, worktreePath)) applied++\n }\n if (applied === 0) return { applied: false, summary: '' }\n\n const summary =\n batch.edits.length === 1\n ? batch.edits[0]!.summary\n : `analyst: ${applied} surface edit${applied === 1 ? '' : 's'}`\n return { applied: true, summary }\n },\n }\n}\n\n/** Apply a proposed patch inside the isolated candidate worktree.\n * candidate worktree (a fresh checkout of baseRef, so `-p0` paths match). */\nfunction applyPatch(patch: string, cwd: string): boolean {\n const result = spawnSync('git', ['apply', '--whitespace=fix', '-p0', '-'], {\n cwd,\n input: patch,\n encoding: 'utf-8',\n })\n return result.status === 0\n}\n","/**\n *\n * Pure readiness-decision helper. Maps a `KnowledgeReadinessReport` from\n * `@tangle-network/agent-eval` to a three-state branch (`ready` / `blocked` /\n * `caveat`) the runtime, route handlers, and UI shells can all switch on.\n *\n * Default `minimumScore` of 0.7 mirrors the readiness scoring scale in\n * agent-eval; callers tightening or loosening this should keep it consistent\n * across all entry points for the same product so the UI / metrics agree on\n * what \"caveat\" means.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\n\nimport { ValidationError } from './errors'\nimport type { KnowledgeReadinessDecision } from './types'\n\nconst DEFAULT_MINIMUM_READINESS_SCORE = 0.7\n\n/**\n * Map a `KnowledgeReadinessReport` to a three-state branch (`ready` / `blocked` / `caveat`) the runtime, route handlers, and UI shells all switch on.\n *\n * @stable\n */\nexport function decideKnowledgeReadiness(\n report: KnowledgeReadinessReport,\n options: { minimumScore?: number } = {},\n): KnowledgeReadinessDecision {\n const minimumScore = options.minimumScore ?? DEFAULT_MINIMUM_READINESS_SCORE\n if (!Number.isFinite(minimumScore) || minimumScore < 0 || minimumScore > 1) {\n throw new ValidationError(\n `minimumScore must be a finite number in [0, 1]; received ${String(minimumScore)}`,\n )\n }\n const blockingGapIds = report.blockingMissingRequirements.map((requirement) => requirement.id)\n const nonBlockingGapIds = report.nonBlockingGaps.map((requirement) => requirement.id)\n if (blockingGapIds.length > 0) {\n return {\n passed: false,\n status: 'blocked',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n if (report.readinessScore < minimumScore) {\n return {\n passed: false,\n status: 'caveat',\n reason: `Knowledge readiness score ${report.readinessScore.toFixed(3)} is below minimum ${minimumScore.toFixed(3)}.`,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n }\n return {\n passed: true,\n status: 'ready',\n reason: report.reason,\n readinessScore: report.readinessScore,\n recommendedAction: report.recommendedAction,\n severity: report.severity,\n blockingGapIds,\n nonBlockingGapIds,\n }\n}\n","/**\n * The product-facing backend selector for `runChatThroughRuntime` /\n * `runAgentTaskStream`: one call turns a `--backend {router,tcloud,cli-bridge,\n * sandbox}` choice into the `AgentExecutionBackend` the chat leg runs on.\n *\n * It is the `AgentExecutionBackend` sibling of `resolveSandboxClient` (which\n * resolves the `SandboxClient` a `runLoop` drives). Both exist for the same\n * reason: every in-process eval product hand-rolled the identical\n * \"`backend-name` → `createOpenAICompatibleBackend`\" branch, and the copies\n * drift. This is the single generic resolver they share.\n *\n * - `router` / `tcloud` / `cli-bridge` → OpenAI-compatible chat completions.\n * All three speak `POST {baseUrl}/chat/completions` in OpenAI's SSE shape —\n * the router (a.k.a. tcloud) IS that endpoint, and cli-bridge fronts a\n * harness CLI behind the same protocol at its own `/v1`. They differ only\n * in `baseUrl` / `apiKey` and the `kind` label a product wants on its\n * traces. cli-bridge REQUIRES `model` in the request body, so it MUST route\n * through `createOpenAICompatibleBackend` (which sends it), never a\n * transport that drops the field.\n * - `sandbox` → the caller's own domain backend. The sandbox variant carries\n * product specifics (system prompt, workspace id, in-box D1 executor) that\n * do NOT belong in the substrate, so the product passes a `sandboxBackend()`\n * seam that this resolver simply invokes.\n *\n * This resolver is PURE backend selection. Product concerns — credit hard-cuts,\n * fetch-capture shims, D1 platform wiring — stay as product-side WRAPPERS\n * around the returned backend. The OpenAI-compat passthrough fields (`tools`,\n * `toolChoice`, `responseFormat`, `temperature`, `maxTokens`, `fetchImpl`,\n * `retry`) are forwarded verbatim so a product can advertise its app tools,\n * preserve generation settings, or install a capturing fetch without\n * re-opening the branch this consolidation closes.\n */\n\nimport { createOpenAICompatibleBackend } from './backends'\nimport type { AgentBackendInput, AgentExecutionBackend } from './types'\n\n/** The transport a chat backend runs on. */\nexport type AgentBackendKind = 'router' | 'tcloud' | 'cli-bridge' | 'sandbox'\n\n/**\n * OpenAI-compat passthrough forwarded to `createOpenAICompatibleBackend` for\n * the `router` / `tcloud` / `cli-bridge` kinds. Mirrors that factory's optional\n * inputs so a product keeps its tool advertising / capture-fetch without\n * re-implementing the backend branch.\n */\ntype OpenAICompatPassthrough = Pick<\n Parameters<typeof createOpenAICompatibleBackend>[0],\n 'tools' | 'toolChoice' | 'responseFormat' | 'temperature' | 'maxTokens' | 'fetchImpl' | 'retry'\n>\n\nexport interface ResolveAgentBackendOptions<TInput extends AgentBackendInput = AgentBackendInput>\n extends OpenAICompatPassthrough {\n /** The chat transport to resolve. */\n kind: AgentBackendKind\n /**\n * Bearer credential for the OpenAI-compat kinds. Empty string is valid for a\n * loopback-anonymous cli-bridge; a `router`/`tcloud` route with an empty key\n * is a caller bug the product surfaces before calling in.\n */\n apiKey: string\n /** Base URL for the OpenAI-compat kinds. cli-bridge's is its `/v1`. */\n baseUrl: string\n /** Model id sent on every request. cli-bridge rejects a request without it. */\n model: string\n /** `kind` label stamped on the resolved backend + its traces. Defaults to `kind`. */\n label?: string\n /**\n * `sandbox` kind: the product's own domain backend. Required for that kind —\n * the substrate owns no product sandbox shape, so a `sandbox` resolution with\n * no seam is a caller bug, not a silent fallback.\n */\n sandboxBackend?: () => AgentExecutionBackend<TInput>\n}\n\n/**\n * Resolve the `AgentExecutionBackend` for the chosen `kind`. Reuse this instead\n * of hand-rolling the `createOpenAICompatibleBackend` branch in each product.\n */\nexport function resolveAgentBackend<TInput extends AgentBackendInput = AgentBackendInput>(\n opts: ResolveAgentBackendOptions<TInput>,\n): AgentExecutionBackend<TInput> {\n switch (opts.kind) {\n case 'router':\n case 'tcloud':\n case 'cli-bridge': {\n const passthrough: OpenAICompatPassthrough = {}\n // Forward only the fields a caller actually set — an explicit\n // `tools: []` / `undefined` would otherwise reach the factory and change\n // its request shape (some providers reject an empty `tools` array).\n if (opts.tools !== undefined) passthrough.tools = opts.tools\n if (opts.toolChoice !== undefined) passthrough.toolChoice = opts.toolChoice\n if (opts.responseFormat !== undefined) passthrough.responseFormat = opts.responseFormat\n if (opts.temperature !== undefined) passthrough.temperature = opts.temperature\n if (opts.maxTokens !== undefined) passthrough.maxTokens = opts.maxTokens\n if (opts.fetchImpl !== undefined) passthrough.fetchImpl = opts.fetchImpl\n if (opts.retry !== undefined) passthrough.retry = opts.retry\n return createOpenAICompatibleBackend<TInput>({\n apiKey: opts.apiKey,\n baseUrl: opts.baseUrl,\n model: opts.model,\n kind: opts.label ?? opts.kind,\n ...passthrough,\n })\n }\n case 'sandbox': {\n if (!opts.sandboxBackend) {\n throw new Error(\"resolveAgentBackend: kind 'sandbox' requires opts.sandboxBackend\")\n }\n return opts.sandboxBackend()\n }\n }\n}\n","/**\n *\n * The two top-level entry points:\n *\n * - `runAgentTask` — single-shot lifecycle for adapter-driven tasks.\n * - `runAgentTaskStream` — streaming lifecycle that delegates execution to an\n * `AgentExecutionBackend` (model API, sandbox, or custom iterable).\n *\n * Both gate the run on `KnowledgeReadinessReport` from `agent-eval`, emit the\n * same lifecycle event vocabulary (under different shapes — see `types.ts`),\n * and route session lifecycle through a pluggable `RuntimeSessionStore`.\n *\n * @stable\n */\n\nimport {\n acquisitionPlansForKnowledgeGaps,\n blockingKnowledgeEval,\n type ControlContext,\n type ControlEvalResult,\n type ControlRunResult,\n type DataAcquisitionPlan,\n FAILURE_CLASSES,\n type FailureClass,\n type KnowledgeReadinessReport,\n type RunRecord,\n runAgentControlLoop,\n scoreKnowledgeReadiness,\n type UserQuestion,\n userQuestionsForKnowledgeGaps,\n} from '@tangle-network/agent-eval'\n\nconst FAILURE_CLASS_SET = new Set<string>(FAILURE_CLASSES)\n\n/** True when a free-form control failure string is a canonical taxonomy\n * class — so only real taxonomy tags are promoted to the cross-agent\n * `RunRecord.failureClass` key; novel strings stay as `failureMode` detail. */\nfunction asFailureClass(value: string | undefined): FailureClass | undefined {\n return value && FAILURE_CLASS_SET.has(value) ? (value as FailureClass) : undefined\n}\n\n/** Stamp cross-cutting defaults onto adapter-projected RunRecords without\n * overriding anything the adapter set explicitly:\n * - `scenarioId` — the run's scenario, when the record omits one.\n * - `failureClass` — the control layer's failure classification promoted\n * onto the canonical cross-agent key, but ONLY when it's a real taxonomy\n * class. This is what lets the substrate aggregate failures across every\n * agent in one vocabulary instead of per-agent ad-hoc strings. */\nexport function applyRunRecordDefaults(\n records: RunRecord[],\n scenarioId: string,\n controlFailureClass: string | undefined,\n): RunRecord[] {\n const fc = asFailureClass(controlFailureClass)\n return records.map((record) => {\n let r = record\n if (r.scenarioId === undefined) r = { ...r, scenarioId }\n if (r.failureClass === undefined && fc) r = { ...r, failureClass: fc }\n return r\n })\n}\n\nimport { normalizeBackendStreamEvent } from './backends'\nimport { BackendTransportError } from './errors'\nimport { decideKnowledgeReadiness } from './readiness'\nimport { nowIso, startOrResumeRuntimeSession, touchSession } from './sessions'\nimport type {\n AgentBackendInput,\n AgentKnowledgeProvider,\n AgentRuntimeEventSink,\n AgentTaskContext,\n AgentTaskRunResult,\n AgentTaskSpec,\n AgentTaskStatus,\n BackendErrorDetail,\n RunAgentTaskOptions,\n RunAgentTaskStreamOptions,\n RuntimeStreamEvent,\n} from './types'\n\n/**\n * Single-shot task lifecycle for adapter-driven tasks: readiness-gated, emits the runtime lifecycle event vocabulary, session-store pluggable.\n *\n * @stable\n */\nexport async function runAgentTask<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult = ControlEvalResult,\n>(\n options: RunAgentTaskOptions<TState, TAction, TActionResult, TEval>,\n): Promise<AgentTaskRunResult<TState, TAction, TActionResult, TEval>> {\n const task = options.task\n await emit(options.onEvent, { type: 'task_start', task })\n await emit(options.onEvent, { type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflight(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n options.onEvent,\n )\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n await emit(options.onEvent, { type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n await emit(options.onEvent, { type: 'readiness_end', task, knowledge })\n }\n\n await emit(options.onEvent, { type: 'control_start', task, knowledge })\n const scenarioId = options.scenarioId ?? task.id\n const control = await runAgentControlLoop<TState, TAction, TActionResult, TEval>({\n intent: task.intent,\n budget: task.budget,\n signal: options.signal,\n store: options.store,\n scenarioId,\n projectId: options.projectId,\n variantId: options.variantId,\n observe: ({ history, abortSignal }) =>\n options.adapter.observe({ task, knowledge, history, abortSignal }),\n validate: async ({ state, history, abortSignal }) => {\n const readinessEval = blockingKnowledgeEval(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n const evals = await options.adapter.validate({\n task,\n knowledge,\n state,\n history,\n abortSignal,\n })\n return [readinessEval as TEval, ...evals]\n },\n decide: (ctx) => {\n if (isKnowledgeBlocked(ctx.evals)) {\n return (\n options.adapter.onKnowledgeBlocked?.({\n task,\n knowledge,\n questions,\n acquisitionPlans,\n }) ?? {\n type: 'stop',\n pass: false,\n score: knowledge.readinessScore,\n reason: `knowledge readiness blocked: ${knowledge.reason}`,\n }\n )\n }\n return options.adapter.decide(toAgentContext(task, knowledge, ctx))\n },\n act: (action, ctx) => options.adapter.act(action, toAgentContext(task, knowledge, ctx)),\n shouldStop: options.adapter.shouldStop\n ? (ctx) => options.adapter.shouldStop!(toAgentContext(task, knowledge, ctx))\n : undefined,\n getActionCostUsd: options.adapter.getActionCostUsd\n ? ({ action, result, state, evals, history }) =>\n options.adapter.getActionCostUsd!({ action, result, task, state, evals, history })\n : undefined,\n onStep: (step) => emit(options.onEvent, { type: 'control_step', task, step }),\n })\n await emit(options.onEvent, { type: 'control_end', task, control })\n const status = statusFromControl(control)\n await emit(options.onEvent, { type: 'task_end', task, status, reason: control.reason })\n\n return {\n task,\n status,\n knowledge,\n questions,\n acquisitionPlans,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n control,\n runRecords: applyRunRecordDefaults(\n options.adapter.projectRunRecords?.(control, task) ?? [],\n scenarioId,\n control.failureClass,\n ),\n }\n}\n\n/**\n * Streaming task lifecycle: delegates execution to an `AgentExecutionBackend` (model API, sandbox, or custom iterable) and yields lifecycle events as they happen.\n *\n * @stable\n */\nexport async function* runAgentTaskStream<TInput extends AgentBackendInput = AgentBackendInput>(\n options: RunAgentTaskStreamOptions<TInput>,\n): AsyncIterable<RuntimeStreamEvent> {\n const task = options.task\n const input = { task, ...(options.input ?? {}) } as TInput\n yield streamEvent({ type: 'task_start', task })\n\n yield streamEvent({ type: 'readiness_start', task })\n let knowledge = await buildReadiness(task, options.knowledge)\n const questions = userQuestionsForKnowledgeGaps(knowledge.blockingMissingRequirements)\n const acquisitionPlans = acquisitionPlansForKnowledgeGaps([\n ...knowledge.blockingMissingRequirements,\n ...knowledge.nonBlockingGaps,\n ])\n const preflight = await runKnowledgePreflightStream(\n task,\n questions,\n acquisitionPlans,\n options.knowledge,\n )\n for (const event of preflight.events) yield event\n if (\n options.knowledge?.refreshReadiness &&\n (Object.keys(preflight.userAnswers).length > 0 || preflight.acquiredEvidenceIds.length > 0)\n ) {\n yield streamEvent({ type: 'readiness_start', task })\n knowledge = await options.knowledge.refreshReadiness({\n task,\n previous: knowledge,\n userAnswers: preflight.userAnswers,\n acquiredEvidenceIds: preflight.acquiredEvidenceIds,\n })\n }\n const decision = decideKnowledgeReadiness(knowledge, {\n minimumScore: options.minimumReadinessScore,\n })\n yield streamEvent({ type: 'readiness_end', task, knowledge, decision })\n if (!decision.passed && decision.status === 'blocked') {\n const reason = `knowledge readiness blocked: ${decision.reason}`\n yield streamEvent({ type: 'task_end', task, status: 'blocked', reason })\n yield streamEvent({ type: 'final', task, status: 'blocked', reason })\n return\n }\n\n const store = options.sessionStore\n const opened = await startOrResumeRuntimeSession({\n backend: options.backend,\n input,\n context: { task, knowledge, signal: options.signal },\n store,\n sessionId: options.sessionId,\n resume: options.resume,\n })\n let session = opened.session\n const shouldResume = opened.resumed\n const sessionEvent = streamEvent({\n type: shouldResume ? 'session_resumed' : 'session_created',\n task,\n session,\n })\n await store?.appendEvent?.(session.id, sessionEvent)\n yield sessionEvent\n\n const backendStart = streamEvent({\n type: 'backend_start',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendStart)\n yield backendStart\n\n let finalText = ''\n try {\n for await (const rawEvent of options.backend.stream(opened.input, {\n task,\n knowledge,\n session,\n signal: options.signal,\n })) {\n const event = normalizeBackendStreamEvent(rawEvent, task, session)\n if (event.type === 'text_delta') finalText += event.text\n await store?.appendEvent?.(session.id, event)\n yield event\n }\n const completedStatus: AgentTaskStatus = 'completed'\n session = touchSession({ ...session, status: completedStatus })\n await store?.put(session)\n const backendEnd = streamEvent({\n type: 'backend_end',\n task,\n session,\n backend: options.backend.kind,\n })\n await store?.appendEvent?.(session.id, backendEnd)\n yield backendEnd\n const reason = 'backend completed'\n const taskEnd = streamEvent({ type: 'task_end', task, status: completedStatus, reason })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status: completedStatus,\n reason,\n text: finalText || undefined,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n session = touchSession({ ...session, status: options.signal?.aborted ? 'aborted' : 'failed' })\n await store?.put(session)\n let stopErrorMessage: string | undefined\n try {\n await options.backend.stop?.(session, message)\n } catch (stopErr) {\n stopErrorMessage = stopErr instanceof Error ? stopErr.message : String(stopErr)\n }\n const combinedMessage = stopErrorMessage\n ? `${message}; backend stop failed: ${stopErrorMessage}`\n : message\n // Typed transport detail — preserves status code + truncated body so\n // consumers can map onto `RunRecord.error` without re-parsing the log\n // string. Required by the runtime's fail-loud contract: silent empty\n // output for a 402 / 401 / 5xx hides the real failure mode.\n const errorDetail: BackendErrorDetail =\n err instanceof BackendTransportError\n ? {\n kind: 'transport',\n message: combinedMessage,\n status: err.status,\n body: err.body,\n }\n : { kind: 'backend', message: combinedMessage }\n const backendError = streamEvent({\n type: 'backend_error',\n task,\n session,\n backend: options.backend.kind,\n message: combinedMessage,\n recoverable: !options.signal?.aborted,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, backendError)\n yield backendError\n const status: AgentTaskStatus = options.signal?.aborted ? 'aborted' : 'failed'\n const taskEnd = streamEvent({ type: 'task_end', task, status, reason: message })\n await store?.appendEvent?.(session.id, taskEnd)\n yield taskEnd\n const final = streamEvent({\n type: 'final',\n task,\n session,\n status,\n reason: message,\n text: finalText || undefined,\n error: errorDetail,\n })\n await store?.appendEvent?.(session.id, final)\n yield final\n }\n}\n\nasync function runKnowledgePreflight<\n TState,\n TAction,\n TActionResult,\n TEval extends ControlEvalResult,\n>(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n onEvent: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n): Promise<{ userAnswers: Record<string, string>; acquiredEvidenceIds: string[] }> {\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n await emit(onEvent, { type: 'questions_start', task, questions })\n userAnswers = await provider.answerQuestions(questions, task)\n await emit(onEvent, { type: 'questions_end', task, questions, userAnswers })\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n await emit(onEvent, { type: 'acquisition_start', task, acquisitionPlans })\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n await emit(onEvent, {\n type: 'acquisition_end',\n task,\n acquisitionPlans,\n acquiredEvidenceIds,\n })\n }\n return { userAnswers, acquiredEvidenceIds }\n}\n\nasync function runKnowledgePreflightStream(\n task: AgentTaskSpec,\n questions: UserQuestion[],\n acquisitionPlans: DataAcquisitionPlan[],\n provider: AgentKnowledgeProvider | undefined,\n): Promise<{\n userAnswers: Record<string, string>\n acquiredEvidenceIds: string[]\n events: RuntimeStreamEvent[]\n}> {\n const events: RuntimeStreamEvent[] = []\n let userAnswers: Record<string, string> = {}\n let acquiredEvidenceIds: string[] = []\n if (questions.length > 0 && provider?.answerQuestions) {\n events.push(streamEvent({ type: 'questions_start', task, questions }))\n userAnswers = await provider.answerQuestions(questions, task)\n events.push(streamEvent({ type: 'questions_end', task, questions, userAnswers }))\n }\n if (acquisitionPlans.length > 0 && provider?.executeAcquisitionPlans) {\n events.push(streamEvent({ type: 'acquisition_start', task, acquisitionPlans }))\n acquiredEvidenceIds = await provider.executeAcquisitionPlans(acquisitionPlans, task)\n events.push(\n streamEvent({ type: 'acquisition_end', task, acquisitionPlans, acquiredEvidenceIds }),\n )\n }\n return { userAnswers, acquiredEvidenceIds, events }\n}\n\nfunction streamEvent<T extends Omit<RuntimeStreamEvent, 'timestamp'>>(\n event: T,\n): T & { timestamp: string } {\n return { ...event, timestamp: nowIso() }\n}\n\nfunction buildReadiness(\n task: AgentTaskSpec,\n provider: AgentKnowledgeProvider | undefined,\n): Promise<KnowledgeReadinessReport> | KnowledgeReadinessReport {\n if (provider?.buildReadiness) return provider.buildReadiness(task)\n return scoreKnowledgeReadiness({\n taskId: task.id,\n requirements: task.requiredKnowledge ?? [],\n metadata: { domain: task.domain, ...task.metadata },\n })\n}\n\nfunction isKnowledgeBlocked(evals: ControlEvalResult[]): boolean {\n return evals.some((evalResult) => evalResult.id === 'knowledge-ready' && !evalResult.passed)\n}\n\nfunction statusFromControl(\n control: ControlRunResult<unknown, unknown, unknown, ControlEvalResult>,\n): AgentTaskStatus {\n if (control.stoppedBy === 'abort') return 'aborted'\n if (control.reason.includes('knowledge readiness blocked')) return 'blocked'\n if (control.pass) return 'completed'\n return 'failed'\n}\n\nasync function emit<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n sink: AgentRuntimeEventSink<TState, TAction, TActionResult, TEval> | undefined,\n event: Parameters<AgentRuntimeEventSink<TState, TAction, TActionResult, TEval>>[0],\n): Promise<void> {\n await sink?.(event)\n}\n\nfunction toAgentContext<TState, TAction, TActionResult, TEval extends ControlEvalResult>(\n task: AgentTaskSpec,\n knowledge: KnowledgeReadinessReport,\n ctx: ControlContext<TState, TAction, TActionResult, TEval>,\n): AgentTaskContext<TState, TAction, TActionResult, TEval> {\n return {\n task,\n knowledge,\n state: ctx.state,\n evals: ctx.evals,\n history: ctx.history,\n budget: ctx.budget,\n stepIndex: ctx.stepIndex,\n wallMs: ctx.wallMs,\n spentCostUsd: ctx.spentCostUsd,\n remainingCostUsd: ctx.remainingCostUsd,\n abortSignal: ctx.abortSignal,\n }\n}\n","/**\n *\n * Production-run lifecycle: record what the agent did on behalf of a customer,\n * what it cost, and how it ended.\n *\n * Three concerns live in this module:\n *\n * 1. **Lifecycle state machine** — `running` -> `completed | failed | cancelled`,\n * enforced by `RuntimeRunStateError`. Completion is idempotent for the same\n * status (a second `complete()` call is a no-op so retries / cleanup paths\n * don't double-fire side effects). A different terminal status is a state\n * error.\n *\n * 2. **Cost ledger** — every `llm_call` event the handle observes contributes\n * `tokensIn`, `tokensOut`, `costUsd`, and bumps `llmCalls`. Wall time is\n * measured from `startRuntimeRun()` to `complete()`. Surface via\n * `handle.cost()` for cost-per-task dashboards.\n *\n * 3. **Persistence adapter** — `RuntimeRunPersistenceAdapter` is the seam\n * consumers plug in to write a `RuntimeRunRow` to their D1 / postgres /\n * KV store. The adapter receives a sanitized row shape; no telemetry\n * payload bytes flow through it unless the consumer opts in via\n * `RuntimeRunOptions.telemetryEvents`.\n *\n * @stable\n */\n\nimport { RuntimeRunStateError, ValidationError } from './errors'\nimport type { AgentTaskSpec, RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport type RuntimeRunStatus = 'running' | 'completed' | 'failed' | 'cancelled'\n\n/** @stable */\nexport interface RuntimeRunCost {\n /** Cumulative input tokens across every observed `llm_call` event. */\n tokensIn: number\n /** Cumulative output tokens across every observed `llm_call` event. */\n tokensOut: number\n /** Sum of `costUsd` from every observed `llm_call` event. */\n costUsd: number\n /** Wall time from `startRuntimeRun()` to `complete()` (or `now()` if not yet completed). */\n wallMs: number\n /** Count of `llm_call` events observed during the run. */\n llmCalls: number\n}\n\n/** @stable */\nexport interface RuntimeRunCompleteInput {\n status: Exclude<RuntimeRunStatus, 'running'>\n resultSummary?: string\n /** Optional explicit cost override; if omitted, the accumulated ledger is used. */\n cost?: Partial<RuntimeRunCost>\n /** Stable error message when `status === 'failed'`. */\n error?: string\n /** Additional adapter-specific fields merged into the persisted row. */\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunRow {\n /** Stable runtime-side identifier. Adapters may translate to their own primary key. */\n id: string\n workspaceId: string\n sessionId?: string\n agentId?: string\n domain?: string\n taskId: string\n scenarioId?: string\n status: RuntimeRunStatus\n resultSummary?: string\n error?: string\n cost: RuntimeRunCost\n startedAt: string\n completedAt?: string\n metadata?: Record<string, unknown>\n}\n\n/** @stable */\nexport interface RuntimeRunPersistenceAdapter {\n /**\n * Called once when `handle.persist()` runs. Implementations write `row` to\n * their durable store (D1, postgres, KV) and return whatever the consumer\n * wants the caller to see (often the storage-side row id). Errors thrown\n * here propagate out of `persist()` so the caller can decide whether to\n * retry or log-and-continue.\n */\n upsert(row: RuntimeRunRow): Promise<void> | void\n}\n\n/** @stable */\nexport interface RuntimeRunOptions {\n workspaceId: string\n sessionId?: string\n agentId?: string\n taskSpec: AgentTaskSpec\n scenarioId?: string\n /** Optional persistence adapter; if omitted, `persist()` is a no-op. */\n adapter?: RuntimeRunPersistenceAdapter\n /** Override the row id; default = `${taskSpec.id}:${random suffix}`. */\n id?: string\n /** Override the clock; default = `Date.now()`. Useful for deterministic tests. */\n now?: () => number\n}\n\n/** @stable */\nexport interface RuntimeRunHandle {\n /** Stable id assigned at start. */\n readonly id: string\n readonly workspaceId: string\n readonly sessionId: string | undefined\n readonly taskSpec: AgentTaskSpec\n readonly status: RuntimeRunStatus\n\n /**\n * Observe a single `RuntimeStreamEvent`. The handle ignores non-cost events\n * (text deltas, tool calls) silently so consumers can pipe the whole stream\n * through `handle.observe`. `llm_call` events update the ledger.\n */\n observe(event: RuntimeStreamEvent): void\n\n /** Snapshot of the current cost ledger. Safe to call at any time. */\n cost(): RuntimeRunCost\n\n /**\n * Transition to a terminal state. Idempotent for the same status; throws\n * `RuntimeRunStateError` for a different terminal status (state machines\n * don't time-travel).\n */\n complete(input: RuntimeRunCompleteInput): void\n\n /** Build the current row without writing it. Useful for tests + dry runs. */\n toRow(metadata?: Record<string, unknown>): RuntimeRunRow\n\n /**\n * Persist the current row via the configured adapter. Must be called after\n * `complete()`. Idempotent for the same terminal state (the adapter sees\n * the same row on retry).\n */\n persist(metadata?: Record<string, unknown>): Promise<void>\n}\n\n/**\n *\n * Construct a runtime-run handle. The returned handle is mutable across its\n * lifetime; consumers should not share it across requests.\n *\n * @stable\n */\nexport function startRuntimeRun(options: RuntimeRunOptions): RuntimeRunHandle {\n if (!options.workspaceId) {\n throw new ValidationError('startRuntimeRun: workspaceId is required')\n }\n if (!options.taskSpec?.id) {\n throw new ValidationError('startRuntimeRun: taskSpec.id is required')\n }\n const now = options.now ?? Date.now\n const startedAtMs = now()\n const startedAt = new Date(startedAtMs).toISOString()\n const id = options.id ?? `${options.taskSpec.id}:${randomSuffix()}`\n\n let status: RuntimeRunStatus = 'running'\n let completedAtMs: number | undefined\n let resultSummary: string | undefined\n let error: string | undefined\n let completionMetadata: Record<string, unknown> | undefined\n\n const ledger: RuntimeRunCost = {\n tokensIn: 0,\n tokensOut: 0,\n costUsd: 0,\n wallMs: 0,\n llmCalls: 0,\n }\n\n const snapshotCost = (): RuntimeRunCost => ({\n tokensIn: ledger.tokensIn,\n tokensOut: ledger.tokensOut,\n costUsd: ledger.costUsd,\n wallMs: (completedAtMs ?? now()) - startedAtMs,\n llmCalls: ledger.llmCalls,\n })\n\n const buildRow = (extraMetadata?: Record<string, unknown>): RuntimeRunRow => ({\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n agentId: options.agentId,\n domain: options.taskSpec.domain,\n taskId: options.taskSpec.id,\n scenarioId: options.scenarioId,\n status,\n resultSummary,\n error,\n cost: snapshotCost(),\n startedAt,\n completedAt: completedAtMs !== undefined ? new Date(completedAtMs).toISOString() : undefined,\n metadata: mergeMetadata(completionMetadata, extraMetadata),\n })\n\n return {\n id,\n workspaceId: options.workspaceId,\n sessionId: options.sessionId,\n taskSpec: options.taskSpec,\n get status() {\n return status\n },\n observe(event) {\n if (event.type !== 'llm_call') return\n ledger.llmCalls += 1\n if (typeof event.tokensIn === 'number' && Number.isFinite(event.tokensIn)) {\n ledger.tokensIn += event.tokensIn\n }\n if (typeof event.tokensOut === 'number' && Number.isFinite(event.tokensOut)) {\n ledger.tokensOut += event.tokensOut\n }\n if (typeof event.costUsd === 'number' && Number.isFinite(event.costUsd)) {\n ledger.costUsd += event.costUsd\n }\n },\n cost: snapshotCost,\n complete(input) {\n // JS callers can bypass the `Exclude<…, 'running'>` type; enforce the\n // state machine at runtime as well.\n if ((input.status as RuntimeRunStatus) === 'running') {\n throw new ValidationError('complete() requires a terminal status, got \"running\"')\n }\n if (status !== 'running') {\n if (status === input.status) return\n throw new RuntimeRunStateError(\n `Cannot transition runtime run from \"${status}\" to \"${input.status}\"`,\n )\n }\n status = input.status\n completedAtMs = now()\n resultSummary = input.resultSummary\n error = input.error\n completionMetadata = input.metadata\n if (input.cost) {\n if (typeof input.cost.tokensIn === 'number' && Number.isFinite(input.cost.tokensIn)) {\n ledger.tokensIn = input.cost.tokensIn\n }\n if (typeof input.cost.tokensOut === 'number' && Number.isFinite(input.cost.tokensOut)) {\n ledger.tokensOut = input.cost.tokensOut\n }\n if (typeof input.cost.costUsd === 'number' && Number.isFinite(input.cost.costUsd)) {\n ledger.costUsd = input.cost.costUsd\n }\n if (typeof input.cost.llmCalls === 'number' && Number.isFinite(input.cost.llmCalls)) {\n ledger.llmCalls = input.cost.llmCalls\n }\n }\n },\n toRow(metadata) {\n return buildRow(metadata)\n },\n async persist(metadata) {\n if (status === 'running') {\n throw new RuntimeRunStateError('Cannot persist a runtime run before complete() is called')\n }\n if (!options.adapter) return\n await options.adapter.upsert(buildRow(metadata))\n },\n }\n}\n\nfunction mergeMetadata(\n base: Record<string, unknown> | undefined,\n extra: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!base && !extra) return undefined\n return { ...(base ?? {}), ...(extra ?? {}) }\n}\n\nfunction randomSuffix(): string {\n // 8 chars of base36 — sufficient for in-process uniqueness. Callers needing\n // stronger guarantees pass `options.id` explicitly.\n return Math.random().toString(36).slice(2, 10)\n}\n","/**\n *\n * Server-Sent Events serialization for runtime telemetry streams.\n *\n * Newline-safe by construction: any newline in `id` or `event` is collapsed to\n * a space (browsers terminate fields on newline), and multi-line `data`\n * payloads are split into one `data:` line per source line so JSON.stringify\n * output transports cleanly.\n *\n * @stable\n */\n\nimport type { KnowledgeReadinessReport } from '@tangle-network/agent-eval'\nimport type { RuntimeTelemetryOptions } from './sanitize'\nimport { sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent } from './sanitize'\nimport type { RuntimeStreamEvent } from './types'\n\n/** @stable */\nexport interface ServerSentEventOptions {\n event?: string\n id?: string\n retry?: number\n}\n\n/** @stable */\nexport function encodeServerSentEvent(data: unknown, options: ServerSentEventOptions = {}): string {\n const lines: string[] = []\n if (options.id) lines.push(`id: ${stripNewlines(options.id)}`)\n if (options.event) lines.push(`event: ${stripNewlines(options.event)}`)\n if (typeof options.retry === 'number' && Number.isFinite(options.retry) && options.retry >= 0) {\n lines.push(`retry: ${Math.floor(options.retry)}`)\n }\n\n const payload = typeof data === 'string' ? data : JSON.stringify(data)\n for (const line of payload.split(/\\r?\\n/)) {\n lines.push(`data: ${line}`)\n }\n return `${lines.join('\\n')}\\n\\n`\n}\n\n/** Serialize a `KnowledgeReadinessReport` as a Server-Sent Event string. @stable */\nexport function readinessServerSentEvent(\n report: KnowledgeReadinessReport,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(\n {\n type: 'readiness',\n readiness: sanitizeKnowledgeReadinessReport(report, telemetryOptions),\n },\n { event, id, retry },\n )\n}\n\n/** Serialize a `RuntimeStreamEvent` as a Server-Sent Event string. @stable */\nexport function runtimeStreamServerSentEvent(\n event: RuntimeStreamEvent,\n options: RuntimeTelemetryOptions & ServerSentEventOptions = {},\n): string {\n const { event: sseEvent, id, retry, ...telemetryOptions } = options\n return encodeServerSentEvent(sanitizeRuntimeStreamEvent(event, telemetryOptions), {\n event: sseEvent,\n id,\n retry,\n })\n}\n\nfunction stripNewlines(value: string): string {\n return value.replace(/[\\r\\n]/g, ' ')\n}\n","/**\n * Bounded turn-level tool-dispatch loop.\n *\n * `runAgentTaskStream` runs ONE model turn; `runLoop` orchestrates DELEGATED\n * multi-agent topologies (refine / fanout-vote). Neither is the everyday\n * interactive shape: a chat turn where the model may emit tool calls, each is\n * executed, the results are folded back, and the turn re-runs until the model\n * stops (or a turn cap). Every agent app hand-rolls that loop — this is it,\n * as a reusable primitive.\n *\n * Substrate-neutral by design: the caller supplies `streamTurn` (wrapping\n * whatever backend / `runAgentTaskStream` it uses) and `executeToolCall`\n * (routing to its executors). This module owns the LOOP; the caller owns the\n * model and the executors. `Raw` (streaming variant) is the caller's own\n * event type. The only imported contract is the runtime hook type: hooks are\n * execution-scoped observers, not part of the agent profile.\n */\n\nimport type { RuntimeDecisionEvidenceRef, RuntimeHooks } from './runtime-hooks'\nimport { notifyRuntimeDecisionPoint, notifyRuntimeHookEvent } from './runtime-hooks'\n\nexport interface ToolLoopCall {\n toolCallId?: string\n toolName: string\n args: Record<string, unknown>\n}\n\n/** Outcome of one tool dispatch — structurally compatible with a hub/integration\n * tool-outcome union, so callers can fold either through the loop. */\nexport type ToolCallOutcome =\n | { ok: true; result: unknown }\n | { ok: false; code: string; message: string; status?: number }\n\n/** Runaway-backstop: stops an infinite tool loop where cost is unmetered. Set\n * far above any legitimate workflow — this is a watchdog, not a policy cap.\n * Legitimate per-call budgets come from `maxCostUsd` + `costOf`. */\nconst RUNAWAY_BACKSTOP_TURNS = 200\nconst DEFAULT_DECISION_CONTEXT_CHARS = 12_000\nconst FAILURE_RECOVERY_ACTIONS = ['retry', 'verify', 'continue', 'stop']\n/** Consecutive identical calls (same tool + canonical-JSON args) that trigger\n * stuck-loop detection. The window resets on any different call. */\nconst STUCK_LOOP_THRESHOLD = 3\n\n/** One OpenAI-shaped tool-call entry carried on an assistant message. */\nexport interface ToolLoopAssistantToolCall {\n id: string\n type: 'function'\n function: { name: string; arguments: string }\n}\n\n/**\n * A message in the running conversation the loop sends to `streamTurn`.\n *\n * The base `{ role, content }` covers `system` / `user` / plain `assistant`\n * turns. Two optional fields carry the OpenAI function-calling contract so a\n * strict model (Claude, and any OpenAI-compatible provider that validates tool\n * history) reads its own tool use back instead of re-issuing the same call:\n *\n * - an assistant turn that emitted tool calls carries `tool_calls`, and its\n * `content` is `null` when the turn was tool-only;\n * - each tool result is its own `{ role: 'tool', tool_call_id, content }`\n * message keyed to the call that produced it.\n *\n * Widening is additive: a `streamTurn` that reads only `role` + `content` still\n * works; one that forwards the whole message to an OpenAI-compatible endpoint\n * now sends correct tool history.\n */\nexport type ToolLoopMessage = {\n role: string\n content: string | null\n tool_calls?: ToolLoopAssistantToolCall[]\n tool_call_id?: string\n}\n\n/** A tool-call id is required to key a `role: 'tool'` result back to its call.\n * When the model omitted one, derive a stable id from the tool name so the\n * assistant `tool_calls` entry and its `tool` result still match. */\nfunction toolCallId(call: ToolLoopCall): string {\n return call.toolCallId ?? `call_${call.toolName}`\n}\n\n/** The assistant turn that emitted `pending`, in OpenAI shape: text content\n * (null when the turn was tool-only) plus its `tool_calls` array. */\nfunction assistantToolCallMessage(turnText: string, pending: ToolLoopCall[]): ToolLoopMessage {\n return {\n role: 'assistant',\n content: turnText.trim() || null,\n tool_calls: pending.map((call) => ({\n id: toolCallId(call),\n type: 'function',\n function: { name: call.toolName, arguments: JSON.stringify(call.args) },\n })),\n }\n}\n\n/** One `role: 'tool'` result message keyed to its call by `tool_call_id`. */\nfunction toolResultMessage(call: ToolLoopCall, content: string): ToolLoopMessage {\n return { role: 'tool', tool_call_id: toolCallId(call), content }\n}\n\nfunction defaultRender(label: string, outcome: ToolCallOutcome): string {\n if (outcome.ok) return `- ${label} → ok: ${JSON.stringify(outcome.result)}`\n return `- ${label} → failed (${outcome.code}): ${outcome.message}`\n}\n\n// ── Awaitable variant (drain-only callers, tests) ──────────────────────────\n\nexport type ToolLoopEvent =\n | { type: 'text'; text: string }\n | { type: 'tool_call'; call: ToolLoopCall }\n | { type: 'other'; event: unknown }\n\n/** Why the loop stopped. `completed` = model finished naturally; `stuck-loop` =\n * ≥3 consecutive identical tool calls (same tool + args); `backstop` = hit the\n * runaway-backstop cap (200 by default); `deadline` = wall-clock deadlineMs\n * exceeded; `budget` = maxCostUsd exhausted. Non-`completed` stops are infra /\n * resource outcomes — eval scoring must distinguish them from capability failure. */\nexport type ToolLoopStopReason = 'completed' | 'stuck-loop' | 'backstop' | 'deadline' | 'budget'\n\nexport interface ToolLoopResult {\n finalText: string\n toolResults: Array<{ call: ToolLoopCall; label: string; outcome: ToolCallOutcome }>\n turns: number\n stopReason: ToolLoopStopReason\n /** @deprecated Use `stopReason !== 'completed'` instead. */\n cappedOut: boolean\n}\n\nexport interface RunToolLoopOptions {\n systemPrompt: string\n userMessage: string\n priorMessages?: ToolLoopMessage[]\n streamTurn: (messages: ToolLoopMessage[]) => AsyncIterable<ToolLoopEvent>\n executeToolCall: (call: ToolLoopCall) => Promise<ToolCallOutcome>\n isExecutableTool: (toolName: string) => boolean\n /** Runaway-backstop cap. Default 200 — set far above any legitimate workflow.\n * For per-workflow limits, use `maxCostUsd` or `deadlineMs` instead. */\n maxToolTurns?: number\n /** Wall-clock deadline in ms since epoch (Date.now()-based). When exceeded the\n * loop stops with stopReason `deadline`. */\n deadlineMs?: number\n /** Maximum total cost in USD. Requires `costOf` to meter each tool call. */\n maxCostUsd?: number\n /** Return the USD cost of one outcome. Required for `maxCostUsd` to work. */\n costOf?: (call: ToolLoopCall, outcome: ToolCallOutcome) => number\n renderResult?: (label: string, outcome: ToolCallOutcome) => string\n labelFor?: (call: ToolLoopCall) => string\n runId?: string\n scenarioId?: string\n hooks?: RuntimeHooks\n}\n\n/** Run the bounded tool loop and return the final text + every executed tool\n * outcome. Awaitable — callers needing to stream events to a UI use\n * {@link streamToolLoop}. */\nexport async function runToolLoop(opts: RunToolLoopOptions): Promise<ToolLoopResult> {\n const backstop = opts.maxToolTurns ?? RUNAWAY_BACKSTOP_TURNS\n const render = opts.renderResult ?? defaultRender\n const labelFor = opts.labelFor ?? ((c: ToolLoopCall) => c.toolName)\n const runId = opts.runId ?? `agent-run-${randomSuffix()}`\n const messages: ToolLoopMessage[] = [\n { role: 'system', content: opts.systemPrompt },\n ...(opts.priorMessages ?? []),\n { role: 'user', content: opts.userMessage },\n ]\n const observer = createToolLoopObserver(opts.hooks, runId, opts.scenarioId)\n const toolResults: ToolLoopResult['toolResults'] = []\n let finalText = ''\n let turns = 0\n let accumulatedCostUsd = 0\n // Stuck-loop detection: track the last canonical-JSON call signature and how\n // many consecutive times we've seen it.\n let lastCallHash: string | null = null\n let consecutiveCount = 0\n\n observer.loopBefore(backstop, messages.length)\n\n for (let toolTurn = 0; ; toolTurn++) {\n turns++\n\n // Wall-clock deadline check — before every new turn.\n if (opts.deadlineMs !== undefined && Date.now() >= opts.deadlineMs) {\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'deadline' })\n return { finalText, toolResults, turns, stopReason: 'deadline', cappedOut: true }\n }\n\n let turnText = ''\n const pending: ToolLoopCall[] = []\n const turnEventId = observer.turnBefore(toolTurn, messages.length)\n for await (const ev of opts.streamTurn([...messages])) {\n if (ev.type === 'text') {\n turnText += ev.text\n finalText += ev.text\n } else if (ev.type === 'tool_call' && opts.isExecutableTool(ev.call.toolName)) {\n pending.push(ev.call)\n }\n }\n if (pending.length === 0) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: 0,\n finalTextChars: finalText.length,\n })\n break\n }\n\n // Runaway backstop — the model keeps emitting calls past the safety ceiling.\n if (toolTurn >= backstop) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'backstop',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'backstop' })\n return { finalText, toolResults, turns, stopReason: 'backstop', cappedOut: true }\n }\n\n // The assistant turn that emitted the calls, carrying its tool_calls array,\n // so a strict model reads its own tool use back in OpenAI shape.\n messages.push(assistantToolCallMessage(turnText, pending))\n const outcomes: ExecutedToolCall[] = []\n for (const [callIndex, call] of pending.entries()) {\n // Stuck-loop detection: hash the first pending call each turn (a model\n // stuck in a loop re-issues the same call repeatedly, not alternating calls).\n const callHash = canonicalCallHash(call)\n if (callHash === lastCallHash) {\n consecutiveCount++\n } else {\n lastCallHash = callHash\n consecutiveCount = 1\n }\n if (consecutiveCount >= STUCK_LOOP_THRESHOLD) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'stuck-loop',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'stuck-loop' })\n return { finalText, toolResults, turns, stopReason: 'stuck-loop', cappedOut: true }\n }\n\n const callEventId = observer.toolCallBefore(toolTurn, turnEventId, callIndex, call)\n let outcome: ToolCallOutcome\n try {\n outcome = await opts.executeToolCall(call)\n } catch (err) {\n outcome = {\n ok: false,\n code: 'executor_error',\n message: err instanceof Error ? err.message : String(err),\n }\n }\n\n // Budget check after each tool call.\n if (opts.maxCostUsd !== undefined && opts.costOf !== undefined) {\n accumulatedCostUsd += opts.costOf(call, outcome)\n if (accumulatedCostUsd >= opts.maxCostUsd) {\n const label = labelFor(call)\n toolResults.push({ call, label, outcome })\n messages.push(toolResultMessage(call, render(label, outcome)))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'budget',\n })\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'budget' })\n return { finalText, toolResults, turns, stopReason: 'budget', cappedOut: true }\n }\n }\n\n const label = labelFor(call)\n const rendered = render(label, outcome)\n toolResults.push({ call, label, outcome })\n outcomes.push({ call, label, outcome, rendered })\n // One role:'tool' message per result, keyed to its call by tool_call_id.\n messages.push(toolResultMessage(call, rendered))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n }\n observer.failureRecovery({\n toolTurn,\n messages,\n turnText,\n outcomes,\n })\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n toolResults: outcomes.map((item) => ({\n toolName: item.call.toolName,\n toolCallId: item.call.toolCallId,\n ok: item.outcome.ok,\n })),\n failedToolCalls: outcomes.filter((item) => !item.outcome.ok).length,\n })\n }\n observer.loopAfter({ turns, toolResults: toolResults.length, stopReason: 'completed' })\n return { finalText, toolResults, turns, stopReason: 'completed', cappedOut: false }\n}\n\n// ── Streaming variant (SSE chat runtimes + per-event telemetry) ────────────\n\nexport type StreamToolLoopYield<Raw> =\n | { kind: 'event'; event: Raw }\n | {\n kind: 'tool_result'\n toolName: string\n toolCallId?: string\n label: string\n outcome: ToolCallOutcome\n }\n | { kind: 'capped'; pending: number; stopReason: Exclude<ToolLoopStopReason, 'completed'> }\n\nexport interface StreamToolLoopOptions<Raw> {\n systemPrompt: string\n userMessage: string\n priorMessages?: ToolLoopMessage[]\n streamTurn: (messages: ToolLoopMessage[]) => AsyncIterable<Raw>\n extractText: (event: Raw) => string\n extractToolCall: (event: Raw) => ToolLoopCall | null\n isExecutableTool: (toolName: string) => boolean\n executeToolCall: (call: ToolLoopCall) => Promise<ToolCallOutcome>\n /** Runaway-backstop cap. Default 200 — set far above any legitimate workflow. */\n maxToolTurns?: number\n /** Wall-clock deadline in ms since epoch (Date.now()-based). */\n deadlineMs?: number\n /** Maximum total cost in USD. Requires `costOf` to meter each tool call. */\n maxCostUsd?: number\n /** Return the USD cost of one outcome. Required for `maxCostUsd` to work. */\n costOf?: (call: ToolLoopCall, outcome: ToolCallOutcome) => number\n renderResult?: (label: string, outcome: ToolCallOutcome) => string\n labelFor?: (call: ToolLoopCall) => string\n runId?: string\n scenarioId?: string\n hooks?: RuntimeHooks\n}\n\n/** Streaming bounded tool loop: yields each raw turn event (the caller maps +\n * telemetries + re-emits it) and each executed `tool_result`; emits one\n * `capped` if it stops for any non-completed reason with calls still pending. */\nexport async function* streamToolLoop<Raw>(\n opts: StreamToolLoopOptions<Raw>,\n): AsyncGenerator<StreamToolLoopYield<Raw>, void, unknown> {\n const backstop = opts.maxToolTurns ?? RUNAWAY_BACKSTOP_TURNS\n const render = opts.renderResult ?? defaultRender\n const labelFor = opts.labelFor ?? ((c: ToolLoopCall) => c.toolName)\n const runId = opts.runId ?? `agent-run-${randomSuffix()}`\n const messages: ToolLoopMessage[] = [\n { role: 'system', content: opts.systemPrompt },\n ...(opts.priorMessages ?? []),\n { role: 'user', content: opts.userMessage },\n ]\n const observer = createToolLoopObserver(opts.hooks, runId, opts.scenarioId)\n let accumulatedCostUsd = 0\n let lastCallHash: string | null = null\n let consecutiveCount = 0\n\n observer.loopBefore(backstop, messages.length)\n\n for (let toolTurn = 0; ; toolTurn++) {\n // Wall-clock deadline check before every new turn.\n if (opts.deadlineMs !== undefined && Date.now() >= opts.deadlineMs) {\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'deadline' })\n yield { kind: 'capped', pending: 0, stopReason: 'deadline' }\n return\n }\n\n let turnText = ''\n const pending: ToolLoopCall[] = []\n const turnEventId = observer.turnBefore(toolTurn, messages.length)\n for await (const event of opts.streamTurn([...messages])) {\n yield { kind: 'event', event }\n turnText += opts.extractText(event)\n const call = opts.extractToolCall(event)\n if (call && opts.isExecutableTool(call.toolName)) pending.push(call)\n }\n if (pending.length === 0) {\n observer.turnAfter(toolTurn, turnEventId, { pendingToolCalls: 0 })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'completed' })\n return\n }\n\n // Runaway backstop.\n if (toolTurn >= backstop) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'backstop',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'backstop' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'backstop' }\n return\n }\n\n // The assistant turn that emitted the calls, carrying its tool_calls array,\n // so a strict model reads its own tool use back in OpenAI shape.\n messages.push(assistantToolCallMessage(turnText, pending))\n const outcomes: ExecutedToolCall[] = []\n for (const [callIndex, call] of pending.entries()) {\n // Stuck-loop detection.\n const callHash = canonicalCallHash(call)\n if (callHash === lastCallHash) {\n consecutiveCount++\n } else {\n lastCallHash = callHash\n consecutiveCount = 1\n }\n if (consecutiveCount >= STUCK_LOOP_THRESHOLD) {\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'stuck-loop',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'stuck-loop' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'stuck-loop' }\n return\n }\n\n const callEventId = observer.toolCallBefore(toolTurn, turnEventId, callIndex, call)\n let outcome: ToolCallOutcome\n try {\n outcome = await opts.executeToolCall(call)\n } catch (err) {\n outcome = {\n ok: false,\n code: 'executor_error',\n message: err instanceof Error ? err.message : String(err),\n }\n }\n\n // Budget check after each tool call.\n if (opts.maxCostUsd !== undefined && opts.costOf !== undefined) {\n accumulatedCostUsd += opts.costOf(call, outcome)\n if (accumulatedCostUsd >= opts.maxCostUsd) {\n const label = labelFor(call)\n yield {\n kind: 'tool_result',\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n label,\n outcome,\n }\n messages.push(toolResultMessage(call, render(label, outcome)))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n stopReason: 'budget',\n })\n observer.loopAfter({ turns: toolTurn + 1, stopReason: 'budget' })\n yield { kind: 'capped', pending: pending.length, stopReason: 'budget' }\n return\n }\n }\n\n const label = labelFor(call)\n yield {\n kind: 'tool_result',\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n label,\n outcome,\n }\n const rendered = render(label, outcome)\n outcomes.push({ call, label, outcome, rendered })\n // One role:'tool' message per result, keyed to its call by tool_call_id.\n messages.push(toolResultMessage(call, rendered))\n observer.toolCallAfter(toolTurn, callEventId, call, outcome)\n }\n observer.failureRecovery({\n toolTurn,\n messages,\n turnText,\n outcomes,\n })\n observer.turnAfter(toolTurn, turnEventId, {\n pendingToolCalls: pending.length,\n toolResults: outcomes.map((item) => ({\n toolName: item.call.toolName,\n toolCallId: item.call.toolCallId,\n ok: item.outcome.ok,\n })),\n failedToolCalls: outcomes.filter((item) => !item.outcome.ok).length,\n })\n }\n}\n\ninterface ExecutedToolCall {\n call: ToolLoopCall\n label: string\n outcome: ToolCallOutcome\n rendered: string\n}\n\ninterface NotifyToolFailureRecoveryOptions {\n hooks?: RuntimeHooks\n runId: string\n scenarioId?: string\n stepIndex: number\n messages: ToolLoopMessage[]\n turnText: string\n outcomes: ExecutedToolCall[]\n}\n\ninterface NotifyToolLoopEventOptions {\n hooks?: RuntimeHooks\n runId: string\n scenarioId?: string\n target: 'agent.run' | 'agent.turn' | 'agent.tool_call'\n phase: 'before' | 'after' | 'error' | 'event'\n id?: string\n stepIndex?: number\n parentId?: string\n payload?: Record<string, unknown>\n metadata?: Record<string, unknown>\n}\n\ninterface ToolLoopObserver {\n loopBefore(maxToolTurns: number, messageCount: number): void\n loopAfter(payload: Record<string, unknown>): void\n turnBefore(toolTurn: number, messageCount: number): string\n turnAfter(toolTurn: number, turnEventId: string, payload: Record<string, unknown>): void\n toolCallBefore(\n toolTurn: number,\n turnEventId: string,\n callIndex: number,\n call: ToolLoopCall,\n ): string\n toolCallAfter(\n toolTurn: number,\n callEventId: string,\n call: ToolLoopCall,\n outcome: ToolCallOutcome,\n ): void\n failureRecovery(options: {\n toolTurn: number\n messages: ToolLoopMessage[]\n turnText: string\n outcomes: ExecutedToolCall[]\n }): void\n}\n\nfunction createToolLoopObserver(\n hooks: RuntimeHooks | undefined,\n runId: string,\n scenarioId: string | undefined,\n): ToolLoopObserver {\n const loopEventId = `${runId}:agent.run`\n return {\n loopBefore: (maxToolTurns, messageCount) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.run',\n phase: 'before',\n id: `${loopEventId}:before`,\n payload: { maxToolTurns, messageCount },\n })\n },\n loopAfter: (payload) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.run',\n phase: 'after',\n id: `${loopEventId}:after`,\n payload,\n })\n },\n turnBefore: (toolTurn, messageCount) => {\n const turnEventId = `${loopEventId}:${toolTurn}`\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.turn',\n phase: 'before',\n id: turnEventId,\n stepIndex: toolTurn,\n parentId: loopEventId,\n payload: { messageCount },\n })\n return turnEventId\n },\n turnAfter: (toolTurn, turnEventId, payload) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.turn',\n phase: 'after',\n id: `${turnEventId}:after`,\n stepIndex: toolTurn,\n parentId: turnEventId,\n payload,\n })\n },\n toolCallBefore: (toolTurn, turnEventId, callIndex, call) => {\n const callEventId = `${turnEventId}:tool-call:${callIndex}`\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.tool_call',\n phase: 'before',\n id: callEventId,\n stepIndex: toolTurn,\n parentId: turnEventId,\n payload: toolCallPayload(call),\n })\n return callEventId\n },\n toolCallAfter: (toolTurn, callEventId, call, outcome) => {\n notifyToolLoopEvent({\n hooks,\n runId,\n scenarioId,\n target: 'agent.tool_call',\n phase: 'after',\n id: `${callEventId}:after`,\n stepIndex: toolTurn,\n parentId: callEventId,\n payload: { ...toolCallPayload(call), outcome: outcomePayload(outcome) },\n })\n },\n failureRecovery: (options) => {\n notifyToolFailureRecovery({\n hooks,\n runId,\n scenarioId,\n stepIndex: options.toolTurn,\n messages: options.messages,\n turnText: options.turnText,\n outcomes: options.outcomes,\n })\n },\n }\n}\n\nfunction notifyToolLoopEvent(options: NotifyToolLoopEventOptions): void {\n notifyRuntimeHookEvent(options.hooks, {\n id: options.id ?? `${options.runId}:${options.target}:${options.phase}`,\n runId: options.runId,\n scenarioId: options.scenarioId,\n target: options.target,\n phase: options.phase,\n timestamp: Date.now(),\n stepIndex: options.stepIndex,\n parentId: options.parentId,\n payload: options.payload,\n metadata: { producer: 'tool-loop', ...options.metadata },\n })\n}\n\nfunction notifyToolFailureRecovery(options: NotifyToolFailureRecoveryOptions): void {\n const failed = options.outcomes.filter((item) => !item.outcome.ok)\n if (failed.length === 0) return\n\n const evidence: RuntimeDecisionEvidenceRef[] = []\n for (const item of failed) {\n const id = item.call.toolCallId ?? `${options.stepIndex}:${item.label}`\n evidence.push({\n source: 'tool_call',\n id,\n detail: `${item.call.toolName} ${stringifySafe(item.call.args, 2_000)}`,\n metadata: { toolName: item.call.toolName, label: item.label },\n })\n evidence.push({\n source: 'tool_result',\n id: `${id}:result`,\n detail: item.rendered,\n metadata: failureMetadata(item.outcome),\n })\n }\n\n notifyRuntimeDecisionPoint(options.hooks, {\n id: `${options.runId}:agent.turn:${options.stepIndex}:failure-recovery`,\n runId: options.runId,\n scenarioId: options.scenarioId,\n stepIndex: options.stepIndex,\n kind: 'retry',\n candidateActions: [...FAILURE_RECOVERY_ACTIONS],\n context: renderDecisionContext(options.messages, options.turnText, options.outcomes),\n evidence,\n metadata: {\n target: 'failure-recovery',\n source: 'agent.turn',\n failedToolCount: failed.length,\n toolNames: failed.map((item) => item.call.toolName),\n },\n })\n}\n\nfunction toolCallPayload(call: ToolLoopCall): Record<string, unknown> {\n return {\n toolName: call.toolName,\n toolCallId: call.toolCallId,\n argsPreview: stringifySafe(call.args, 2_000),\n }\n}\n\nfunction outcomePayload(outcome: ToolCallOutcome): Record<string, unknown> {\n if (!outcome.ok) {\n return {\n ok: false,\n code: outcome.code,\n message: trimText(outcome.message, 2_000),\n status: outcome.status,\n }\n }\n return {\n ok: true,\n resultPreview: stringifySafe(outcome.result, 2_000),\n }\n}\n\nfunction failureMetadata(outcome: ToolCallOutcome): Record<string, unknown> | undefined {\n if (outcome.ok) return undefined\n return {\n code: outcome.code,\n message: outcome.message,\n status: outcome.status,\n }\n}\n\nfunction renderDecisionContext(\n messages: ToolLoopMessage[],\n turnText: string,\n outcomes: ExecutedToolCall[],\n): string {\n const recent = messages.slice(-6).map((message) => `[${message.role}]\\n${message.content ?? ''}`)\n const assistant = turnText.trim() ? [`[assistant]\\n${turnText}`] : []\n const toolResults = [`[tool results]\\n${outcomes.map((item) => item.rendered).join('\\n')}`]\n return trimText(\n [...recent, ...assistant, ...toolResults].join('\\n\\n'),\n DEFAULT_DECISION_CONTEXT_CHARS,\n )\n}\n\n/** Canonical identifier for a tool call used by stuck-loop detection.\n * Keys are sorted so `{b:1,a:2}` and `{a:2,b:1}` produce the same hash. */\nfunction canonicalCallHash(call: ToolLoopCall): string {\n const sortedArgs = Object.fromEntries(\n Object.entries(call.args).sort(([a], [b]) => a.localeCompare(b)),\n )\n return `${call.toolName}:${JSON.stringify(sortedArgs)}`\n}\n\nfunction stringifySafe(value: unknown, max: number): string {\n let text: string\n try {\n text = JSON.stringify(value) ?? String(value)\n } catch {\n text = String(value)\n }\n return trimText(text, max)\n}\n\nfunction trimText(text: string, max: number): string {\n if (text.length <= max) return text\n return `${text.slice(0, max)}…`\n}\n\nfunction randomSuffix(len = 8): string {\n return Math.random()\n .toString(36)\n .slice(2, 2 + len)\n}\n"],"mappings":"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","names":["emit","randomSuffix","label"]}