la-machina-engine 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/tools/contract.ts","../src/tools/fetchData.ts","../src/orchestrator/types.ts","../src/orchestrator/planParser.ts","../src/orchestrator/agentPrompts.ts","../src/orchestrator/phases.ts","../src/orchestrator/retry.ts","../src/orchestrator/snapshot.ts","../src/orchestrator/synthesize.ts","../src/orchestrator/orchestrate.ts","../src/index.ts","../src/config/merge.ts","../src/config/defaults.ts","../src/config/schema.ts","../src/engine/engine.ts","../src/model/factory.ts","../src/api/providerSelector.ts","../src/engine/errors.ts","../src/model/anthropicAdapter.ts","../src/api/anthropicClient.ts","../src/api/betaHeaders.ts","../src/api/streaming.ts","../src/model/aiSdkAdapter.ts","../src/model/messageConverter.ts","../src/model/toolConverter.ts","../src/runtime/detect.ts","../src/tools/capabilityStub.ts","../src/subagent/registry.ts","../src/runtime/uuid.ts","../src/tools/agent.ts","../src/subagent/runner.ts","../src/engine/agentLoop.ts","../src/transcript/snapshot.ts","../src/engine/toolResultOffload.ts","../src/engine/toolResultSummarizer.ts","../src/hooks/dispatch.ts","../src/engine/normalizeMessages.ts","../src/compact/compactor.ts","../src/compact/dropMiddle.ts","../src/compact/microcompact.ts","../src/compact/summarize.ts","../src/compact/prompt.ts","../src/engine/streamingExecutor.ts","../src/engine/runContext.ts","../src/engine/toolRuntime.ts","../src/transcript/writer.ts","../src/transcript/entries.ts","../src/transcript/meta.ts","../src/subagent/fork.ts","../src/tools/bash.ts","../src/tools/sendMessage.ts","../src/tools/fileEdit.ts","../src/tools/fileRead.ts","../src/tools/fileWrite.ts","../src/tools/glob.ts","../src/tools/walkAdapter.ts","../src/tools/grep.ts","../src/tools/webFetch.ts","../src/tools/fileTracker.ts","../src/tools/webSearch.ts","../src/tools/sleep.ts","../src/tools/toolSearch.ts","../src/tools/memorize.ts","../src/tools/recall.ts","../src/tools/notebookEdit.ts","../src/tools/tasks/store.ts","../src/tools/tasks/tools.ts","../src/logging/logger.ts","../src/agents/loader.ts","../src/coordinator/mode.ts","../src/coordinator/prompt.ts","../src/mcp/manager.ts","../src/mcp/client.ts","../src/mcp/bindingTransport.ts","../src/mcp/errors.ts","../src/mcp/toolAdapter.ts","../src/mcp/sampling.ts","../src/permissions/evaluator.ts","../src/permissions/allowlist.ts","../src/permissions/rules.ts","../src/memory/memoryConfig.ts","../src/memory/episodes.ts","../src/memory/hippocampus.ts","../src/prompts/systemPrompt.ts","../src/skills/loader.ts","../src/prompts/sections/base.ts","../src/prompts/sections/doingTasks.ts","../src/prompts/sections/actions.ts","../src/prompts/sections/usingTools.ts","../src/prompts/sections/toneAndStyle.ts","../src/prompts/sections/environment.ts","../src/prompts/sections/mcp.ts","../src/engine/jsonOutput.ts","../src/skills/skillPage.ts","../src/tools/apiCall.ts","../src/tools/searchKnowledge.ts","../src/knowledge/indexer.ts","../src/knowledge/tokenize.ts","../src/knowledge/scope.ts","../src/tools/readKnowledge.ts","../src/knowledge/extractors.ts","../src/skills/storageSkillSource.ts","../src/skills/inlineSkillSource.ts","../src/storage/factory.ts","../src/storage/interface.ts","../src/storage/localAdapter.ts","../src/storage/pathSafety.ts","../src/storage/r2Adapter.ts","../src/storage/r2BindingAdapter.ts","../src/transcript/reader.ts","../src/engine/rehydrate.ts","../src/engine/response.ts","../src/engine/state.ts","../src/engine/executor.ts","../src/engine/webhook.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Tool contract — the shape every tool implements, plus a registry to\n * collect them by name.\n *\n * The contract is intentionally minimal:\n *\n * 1. A tool has a `name`, a `description`, and a Zod `inputSchema`.\n * Zod gives both runtime validation and a TypeScript-inferred\n * input type for `execute()`.\n * 2. `execute(input, context)` returns a `ToolResult` (or rejects).\n * The runtime catches rejections and turns them into error\n * results — a misbehaving tool can never crash the agent loop.\n * 3. The runtime supplies a `ToolContext` carrying at least an\n * `AbortSignal` for cancellation.\n *\n * Phase 5 ships the types and the registry. Phase 6 fills the registry\n * with the core tool set (Bash, Read, Write, Edit, Glob, Grep, WebFetch).\n * Custom tools come from `config.tools.custom` at engine init time.\n */\n\nimport type { z } from 'zod'\n\n/**\n * The execution context passed to every tool. Phase 5 keeps this\n * minimal — only an AbortSignal — so the contract stays portable.\n * Later phases extend with storage, run/node ids, hook handles, etc.\n */\nexport interface ToolContext {\n readonly signal: AbortSignal\n}\n\n/**\n * The result of a single tool invocation. The runtime wraps thrown\n * errors in this shape so the agent loop only ever sees success/error\n * as data, not exceptions.\n */\nexport interface ToolResult {\n /** Human- and model-readable output. The agent's next turn sees this. */\n readonly content: string\n /** True when the tool failed. */\n readonly isError?: boolean\n /** Optional structured metadata for hooks / observability. */\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n/**\n * A tool definition. Generic on a Zod schema so that `execute()`'s\n * input parameter is statically typed via `z.infer<TSchema>`.\n *\n * Tool authors normally use `defineTool()` to get the inference\n * without writing the generic by hand.\n */\nexport interface Tool<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {\n readonly name: string\n readonly description: string\n readonly inputSchema: TSchema\n /**\n * Optional raw JSON Schema to send to the Anthropic API as\n * `input_schema`, bypassing Zod-to-JSON-Schema conversion. Used by\n * MCP-sourced tools whose schema is authored in JSON Schema directly\n * and whose Zod schema is a `z.unknown()` passthrough.\n *\n * When set, `toAnthropicTool()` in the agent loop prefers this over\n * running `zodToJsonSchema(inputSchema)`. Normal in-process tools\n * defined via `defineTool()` should leave this undefined.\n */\n readonly anthropicSchemaOverride?: Record<string, unknown>\n /**\n * Returns true if this tool is safe to run concurrently with other\n * concurrency-safe tools. Read-only tools (Read, Glob, Grep, etc.)\n * should return true; mutating tools (Write, Edit, Bash) should\n * return false. Default: false (fail-closed).\n *\n * The agent loop uses this to batch consecutive safe tool calls\n * into a single `Promise.all()` for parallel execution, while\n * running unsafe tools serially.\n *\n * Input is typed as `unknown` (not `z.infer<TSchema>`) so that\n * `Tool<ZodObject<...>>` remains assignable to `Tool<ZodTypeAny>`\n * under `exactOptionalPropertyTypes`.\n */\n isConcurrencySafe?: ((input: unknown) => boolean) | undefined\n /**\n * Declares that this tool needs Node-only capabilities\n * (`node:child_process`, the real filesystem, stdio-based MCP, etc.)\n * When true AND the runtime can't support them, the engine replaces\n * this tool with a capability stub (see `src/tools/capabilityStub.ts`)\n * that returns a structured `isError` result instead of crashing.\n *\n * Leave undefined / false for tools that work anywhere (Read, Write,\n * WebFetch, http-based MCP). Default: false.\n */\n readonly requiresNode?: boolean\n /**\n * Internal marker set by `capabilityStub()` so the agent-loop's\n * runner-handoff check (Plan 019 §4) can distinguish a stubbed tool\n * from a real one without reflecting on the implementation.\n * Do not set this manually.\n */\n readonly isCapabilityStub?: boolean\n execute(input: z.infer<TSchema>, context: ToolContext): Promise<ToolResult>\n}\n\n/**\n * Identity helper that locks in the schema generic so callers don't have\n * to write it. Use this whenever defining a tool — it costs nothing at\n * runtime and gives you full inference inside `execute()`.\n *\n * @example\n * ```ts\n * const Echo = defineTool({\n * name: 'Echo',\n * description: 'Echoes its input back',\n * inputSchema: z.object({ msg: z.string() }),\n * execute: async ({ msg }) => ({ content: msg }),\n * })\n * ```\n */\nexport function defineTool<TSchema extends z.ZodTypeAny>(tool: Tool<TSchema>): Tool<TSchema> {\n return tool\n}\n\n/**\n * In-memory registry of tools by name. Used by the engine's tool runtime\n * to dispatch tool calls. Re-registering the same name throws so typos\n * surface immediately rather than silently shadowing.\n */\nexport class ToolRegistry {\n private readonly tools = new Map<string, Tool>()\n\n register(tool: Tool): void {\n if (typeof tool.name !== 'string' || tool.name.length === 0) {\n throw new Error('ToolRegistry: tool.name must be a non-empty string')\n }\n if (this.tools.has(tool.name)) {\n throw new Error(`ToolRegistry: \"${tool.name}\" is already registered`)\n }\n this.tools.set(tool.name, tool)\n }\n\n registerAll(tools: ReadonlyArray<Tool>): void {\n for (const tool of tools) this.register(tool)\n }\n\n unregister(name: string): void {\n this.tools.delete(name)\n }\n\n get(name: string): Tool | undefined {\n return this.tools.get(name)\n }\n\n has(name: string): boolean {\n return this.tools.has(name)\n }\n\n list(): Tool[] {\n return Array.from(this.tools.values())\n }\n\n count(): number {\n return this.tools.size\n }\n}\n","/**\n * FetchData — built-in tool that rehydrates an offloaded tool result\n * (Plan 021).\n *\n * When offload is enabled, large tool results get stored under the\n * current agent's log path (`{logPath}/toolResults/{ref}.json`) and\n * replaced in the model's context with a short summary + a `ref`\n * token. If the model needs the full payload it calls:\n *\n * FetchData({ ref: \"tu_abc\" })\n *\n * and this tool reads the blob back. Each agent gets its own\n * `FetchData` instance bound to the agent's own log path — a\n * subagent can't reach the parent's blobs and vice versa.\n *\n * Safety rails:\n * - `ref` must match `/^[a-zA-Z0-9_-]+$/` — tool_use IDs fit, path-\n * traversal attempts (`../`, absolute paths, slashes) don't.\n * - Missing ref → `isError: true` with a clear message.\n * - Path is computed server-side from the caller's logPath; the\n * model only supplies the ref.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\n\nconst SAFE_REF = /^[a-zA-Z0-9_-]+$/\n\nexport interface CreateFetchDataToolOptions {\n readonly storage: StorageAdapter\n /**\n * This agent's log path, e.g. `projects/{runId}/nodes/{nodeId}`\n * for the top-level run, or\n * `projects/{runId}/nodes/{nodeId}/subagents/{agentId}` for a\n * subagent. The tool reads `{logPath}/toolResults/{ref}.json`.\n */\n readonly logPath: string\n}\n\nconst inputSchema = z.object({\n ref: z.string().min(1),\n})\n\nexport function createFetchDataTool(opts: CreateFetchDataToolOptions): Tool {\n return defineTool({\n name: 'FetchData',\n description:\n 'Fetch the full content of a tool result that was offloaded because it ' +\n 'was too large for the main context. Pass the `ref` token from the ' +\n 'summarized tool_result message (the text that looked like ' +\n '\\'Use FetchData with ref=\"...\"\\'). Returns the raw bytes of the original ' +\n 'tool output.',\n inputSchema,\n execute: async ({ ref }) => {\n if (!SAFE_REF.test(ref)) {\n return {\n content: `ERR_OFFLOAD_INVALID_REF: ref \"${ref}\" contains unsafe characters`,\n isError: true,\n }\n }\n const path = `${opts.logPath}/toolResults/${ref}.json`\n const raw = await opts.storage.readFile(path)\n if (raw === null) {\n return {\n content: `ERR_OFFLOAD_REF_NOT_FOUND: no data found for ref \"${ref}\"`,\n isError: true,\n }\n }\n return {\n content: raw,\n isError: false,\n metadata: { ref, bytes: raw.length },\n }\n },\n })\n}\n","/**\n * Orchestrator types — plan schema, step results, retry policy,\n * orchestrator config, and the public OrchestratorResult.\n */\n\nimport { z } from 'zod'\nimport type { TokenUsage } from '../api/streaming.js'\n\n// ---------- Plan schema ----------\n\nexport const PlanStepSchema = z.object({\n id: z.string().min(1),\n description: z.string().min(1),\n action: z.enum(['research', 'implement', 'verify', 'review', 'custom']),\n files: z.array(z.string()).optional(),\n spec: z.string().optional(),\n dependsOn: z.array(z.string()).optional(),\n})\n\nexport const PlanSchema = z.object({\n summary: z.string().min(1),\n steps: z.array(PlanStepSchema).min(1),\n})\n\nexport type PlanStep = z.infer<typeof PlanStepSchema>\nexport type Plan = z.infer<typeof PlanSchema>\n\n// ---------- Step results ----------\n\nexport type StepStatus = 'done' | 'failed' | 'skipped' | 'reverted'\n\nexport interface StepResult {\n readonly stepId: string\n readonly action: string\n readonly status: StepStatus\n readonly output?: string | undefined\n readonly error?: string | undefined\n readonly attempts: number\n readonly agentId?: string | undefined\n}\n\n// ---------- File snapshots ----------\n\nexport interface FileSnapshot {\n readonly path: string\n /** null = file didn't exist before (delete on revert). */\n readonly content: string | null\n}\n\n// ---------- Retry policy ----------\n\nexport interface RetryPolicy {\n readonly maxAttempts: number\n readonly backoffMs: number\n readonly onExhausted: 'revert' | 'skip' | 'fail'\n}\n\nexport interface ResolvedRetryPolicies {\n readonly plan: RetryPolicy\n readonly research: RetryPolicy\n readonly implement: RetryPolicy\n readonly verify: RetryPolicy\n readonly review: RetryPolicy\n}\n\n// ---------- Orchestrator config ----------\n\nexport interface ResolvedOrchestratorConfig {\n readonly enabled: boolean\n readonly retries: ResolvedRetryPolicies\n readonly maxParallelResearchers: number\n readonly enableReview: boolean\n readonly enableRollback: boolean\n readonly maxPlanSteps: number\n /** Max turns per internal agent run (planner, researcher, implementer, verifier). Default: 15. */\n readonly agentMaxTurns: number\n}\n\n// ---------- Orchestrator result ----------\n\nexport interface OrchestratorResult {\n readonly status: 'done' | 'partial' | 'failed'\n readonly output: string\n readonly plan: Plan | null\n readonly steps: readonly StepResult[]\n readonly tokensUsed: TokenUsage\n readonly agentRuns: number\n readonly reverted: readonly string[]\n readonly durationMs: number\n}\n\n// ---------- Orchestrate options (public API) ----------\n\nexport interface OrchestrateOptions {\n readonly runId: string\n readonly nodeId: string\n readonly task: string\n /** Optional pre-built plan — skip the Planner agent. */\n readonly plan?: Plan | undefined\n}\n","/**\n * Plan parser — extract and validate a JSON plan from LLM output.\n *\n * The Planner agent may wrap JSON in markdown fences, include preamble\n * text, or produce slightly malformed JSON. This parser is tolerant:\n * 1. Strips markdown ```json ... ``` fences\n * 2. Finds the first { ... } block in the text\n * 3. Parses as JSON\n * 4. Validates against PlanSchema with Zod\n */\n\nimport { PlanSchema, type Plan } from './types.js'\n\n/**\n * Extract a valid Plan from raw LLM output. Returns null if the output\n * can't be parsed into a valid plan.\n */\nexport function parsePlan(raw: string, maxSteps: number): Plan | null {\n const json = extractJson(raw)\n if (json === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(json)\n } catch {\n return null\n }\n\n const result = PlanSchema.safeParse(parsed)\n if (!result.success) return null\n\n const plan = result.data\n if (plan.steps.length > maxSteps) return null\n\n return plan\n}\n\n/**\n * Find the first top-level JSON object in a string. Handles markdown\n * fences and leading/trailing text.\n */\nfunction extractJson(text: string): string | null {\n // Try stripping markdown fences first.\n const fenceMatch = text.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/)\n if (fenceMatch?.[1]) {\n const inner = fenceMatch[1].trim()\n if (inner.startsWith('{')) return inner\n }\n\n // Find the first { ... } block by tracking brace depth.\n let start = -1\n let depth = 0\n for (let i = 0; i < text.length; i++) {\n const c = text[i]\n if (c === '{') {\n if (depth === 0) start = i\n depth++\n } else if (c === '}') {\n depth--\n if (depth === 0 && start !== -1) {\n return text.slice(start, i + 1)\n }\n }\n }\n\n return null\n}\n","/**\n * System prompts for each orchestrator agent role.\n * Static strings — no LLM generates them.\n */\n\nexport const PLANNER_PROMPT = `You are a planning agent. Your job is to decompose a task into executable steps.\n\nOutput a JSON object with this EXACT shape:\n{\n \"summary\": \"one-line task summary\",\n \"steps\": [\n {\n \"id\": \"step-1\",\n \"description\": \"what this step does\",\n \"action\": \"research|implement|verify|review\",\n \"files\": [\"src/file.ts\"],\n \"dependsOn\": []\n }\n ]\n}\n\nRules:\n- Actions: \"research\" (read-only investigation), \"implement\" (code changes), \"verify\" (test/validate), \"review\" (optional code review)\n- Every \"implement\" step MUST be followed by a \"verify\" step that depends on it\n- Research steps with no dependencies can run in parallel — use this for speed\n- Keep steps focused — one concern per step\n- Include specific file paths in the \"files\" field when known\n- \"dependsOn\" lists step IDs that must complete before this step starts\n- Do NOT implement anything — only plan\n\nOutput ONLY the JSON object. No explanation, no markdown fences, no preamble.`\n\nexport const RESEARCHER_PROMPT = `You are a research agent. Investigate the given question thoroughly.\n\nRules:\n- Do NOT modify any files. Read-only investigation.\n- Report specific file paths, line numbers, type signatures, and code snippets\n- Be thorough — anything you don't report will be lost\n- If you can't find something, say so explicitly\n- Structure your findings clearly with headers and bullet points`\n\nexport const IMPLEMENTER_PROMPT = `You are an implementation agent. Execute the given specification exactly.\n\nRules:\n- Make the minimum changes needed to satisfy the spec\n- Read files before editing them\n- After making changes, verify they compile/work if possible\n- Report: which files you changed, what you changed, and the result\n- If you encounter errors, report them with full details — do not skip\n- Do not add features or improvements beyond what the spec asks for\n- Commit your changes if the spec asks for it`\n\nexport const VERIFIER_PROMPT = `You are a verification agent. Prove that recent changes work correctly.\n\nRules:\n- Run tests if available. Report pass/fail with output.\n- Check for type errors, syntax errors, import errors\n- Try edge cases — don't just verify the happy path\n- Be skeptical — if something looks wrong, investigate\n- Do NOT rubber-stamp. If you can't verify, say so.\n- Your output MUST include a clear verdict: PASS or FAIL\n- If FAIL, include the specific error and what needs fixing`\n\nexport const REVIEWER_PROMPT = `You are a code review agent. Review recent changes for quality and correctness.\n\nReview for:\n- Correctness: does the code do what it should?\n- Security: any injection, XSS, auth bypass, or data exposure?\n- Quality: naming, structure, unnecessary complexity?\n- Edge cases: what happens with empty input, null, large data?\n\nReport findings as bullet points. Be specific — include file paths and line numbers.\nIf no issues found, say \"No issues found\" explicitly.`\n\nexport const FINALIZER_PROMPT = `You are a reporting agent. Assemble a final report from the workflow results.\n\nInclude:\n1. What was the original task\n2. What steps were executed and their outcomes\n3. What succeeded and what failed\n4. Any files that were reverted (rolled back)\n5. Key decisions made during execution\n6. Recommended next steps (if any)\n\nBe concise but complete. Use bullet points for lists.\nIf there were failures, explain what went wrong and suggest fixes.\nSave key decisions and learnings using the Memorize tool.`\n","/**\n * Phase runners — each function spawns one agent role via engine.run()\n * and returns the result. The orchestrator calls these in sequence\n * according to the plan.\n *\n * Each phase:\n * 1. Builds a RunOptions with the role-specific system prompt\n * 2. Calls engine.run() (isolated context, isolated transcript)\n * 3. Extracts the relevant output\n * 4. Returns it to the orchestrator\n *\n * All phases are pure async functions — no platform dependencies.\n */\n\nimport type { Engine } from '../engine/engine.js'\nimport type { EngineResponse } from '../engine/response.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { parsePlan } from './planParser.js'\nimport type { Plan, PlanStep, StepResult } from './types.js'\nimport {\n PLANNER_PROMPT,\n RESEARCHER_PROMPT,\n IMPLEMENTER_PROMPT,\n VERIFIER_PROMPT,\n REVIEWER_PROMPT,\n FINALIZER_PROMPT,\n} from './agentPrompts.js'\n\n/** Aggregate token usage tracker + per-phase maxTurns. */\nexport class TokenTracker {\n input = 0\n output = 0\n runs = 0\n /** Max turns each internal agent run is allowed. */\n maxTurns: number = 15\n\n add(usage: TokenUsage): void {\n this.input += usage.input\n this.output += usage.output\n this.runs++\n }\n\n get total(): TokenUsage {\n return { input: this.input, output: this.output }\n }\n}\n\n// ---------- Planner ----------\n\nexport async function runPlanner(\n engine: Engine,\n task: string,\n runId: string,\n maxSteps: number,\n tracker: TokenTracker,\n): Promise<Plan | null> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: 'planner',\n task: `Plan the following task:\\n\\n${task}`,\n systemOverride: PLANNER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n if (result.status !== 'done') return null\n return parsePlan(\n result.meta.output ?? (typeof result.data === 'string' ? result.data : ''),\n maxSteps,\n )\n}\n\n// ---------- Researcher ----------\n\nexport async function runResearcher(\n engine: Engine,\n step: PlanStep,\n runId: string,\n index: number,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `research-${step.id}-${index}`,\n task:\n step.description + (step.files?.length ? `\\n\\nFocus on files: ${step.files.join(', ')}` : ''),\n systemOverride: RESEARCHER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'research',\n status: result.status === 'done' ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: result.status === 'failed' ? (result.errors[0]?.message ?? 'unknown') : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Implementer ----------\n\nexport async function runImplementer(\n engine: Engine,\n spec: string,\n step: PlanStep,\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `implement-${step.id}`,\n task: spec,\n systemOverride: IMPLEMENTER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'implement',\n status: result.status === 'done' ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: result.status === 'failed' ? (result.errors[0]?.message ?? 'unknown') : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Verifier ----------\n\nexport async function runVerifier(\n engine: Engine,\n step: PlanStep,\n implResult: StepResult,\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const task = [\n `Verify the following changes:\\n`,\n step.description,\n implResult.output ? `\\n\\nImplementation result:\\n${implResult.output}` : '',\n step.files?.length ? `\\n\\nFiles involved: ${step.files.join(', ')}` : '',\n `\\n\\nRun tests if available. Report PASS or FAIL with details.`,\n ].join('')\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `verify-${step.id}`,\n task,\n systemOverride: VERIFIER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n const passed =\n result.status === 'done' &&\n /\\bPASS\\b/i.test(result.meta.output ?? (typeof result.data === 'string' ? result.data : '')) &&\n !/\\bFAIL\\b/i.test(result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n\n return {\n stepId: step.id,\n action: 'verify',\n status: passed ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: !passed\n ? result.status === 'failed'\n ? (result.errors[0]?.message ?? 'unknown')\n : 'Verification failed'\n : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Reviewer ----------\n\nexport async function runReviewer(\n engine: Engine,\n step: PlanStep,\n allResults: readonly StepResult[],\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const implResults = allResults\n .filter((r) => r.action === 'implement' && r.status === 'done')\n .map((r) => r.output)\n .join('\\n\\n')\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `review-${step.id}`,\n task: `Review the following changes:\\n\\n${implResults}`,\n systemOverride: REVIEWER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'review',\n status: result.status === 'done' ? 'done' : 'skipped',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Finalizer ----------\n\nexport async function runFinalizer(\n engine: Engine,\n task: string,\n results: readonly StepResult[],\n reverted: readonly string[],\n runId: string,\n tracker: TokenTracker,\n): Promise<string> {\n const summary = results\n .map(\n (r) =>\n `- [${r.status.toUpperCase()}] ${r.stepId} (${r.action}): ${r.output?.slice(0, 200) ?? r.error ?? 'no output'}`,\n )\n .join('\\n')\n\n const revertedList = reverted.length > 0 ? `\\n\\nReverted files: ${reverted.join(', ')}` : ''\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: 'finalizer',\n task: `Original task: ${task}\\n\\nStep results:\\n${summary}${revertedList}\\n\\nAssemble a final report.`,\n systemOverride: FINALIZER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : `Orchestration completed with issues. ${results.filter((r) => r.status === 'failed').length} step(s) failed.`\n}\n\n// ---------- Helpers ----------\n\ninterface AgentRunOptions {\n runId: string\n nodeId: string\n task: string\n systemOverride: string\n maxTurns?: number\n}\n\nasync function runAgent(engine: Engine, options: AgentRunOptions): Promise<EngineResponse> {\n const task = `${options.systemOverride}\\n\\n---\\n\\n${options.task}`\n return engine.run({\n runId: options.runId,\n nodeId: options.nodeId,\n task,\n ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),\n })\n}\n\nfunction getTokens(result: EngineResponse): TokenUsage {\n return result.meta.tokensUsed ?? { input: 0, output: 0 }\n}\n","/**\n * Generic retry-with-backoff wrapper. Pure JS — no platform APIs\n * beyond setTimeout.\n */\n\nimport type { RetryPolicy } from './types.js'\n\nexport interface RetryResult<T> {\n readonly success: boolean\n readonly value?: T\n readonly error?: string\n readonly attempts: number\n}\n\n/**\n * Execute `fn` up to `policy.maxAttempts` times with exponential backoff.\n * Returns the first successful result or the last error.\n */\nexport async function runWithRetry<T>(\n fn: () => Promise<T>,\n policy: RetryPolicy,\n): Promise<RetryResult<T>> {\n let lastError = ''\n\n for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {\n try {\n const value = await fn()\n return { success: true, value, attempts: attempt }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err)\n\n // Don't backoff after the last attempt.\n if (attempt < policy.maxAttempts && policy.backoffMs > 0) {\n const delay = policy.backoffMs * Math.pow(2, attempt - 1)\n await sleep(delay)\n }\n }\n }\n\n return { success: false, error: lastError, attempts: policy.maxAttempts }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms)\n if (typeof timer.unref === 'function') timer.unref()\n })\n}\n","/**\n * File snapshot + restore — rollback mechanism for implementation failures.\n * Operates through the StorageAdapter abstraction — works on both\n * local filesystem and R2.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { FileSnapshot } from './types.js'\n\n/**\n * Read and store the current content of a list of files. Files that\n * don't exist get `content: null` — restoring them will delete the file\n * (reversing a create).\n */\nexport async function snapshotFiles(\n storage: StorageAdapter,\n paths: readonly string[],\n): Promise<FileSnapshot[]> {\n return Promise.all(\n paths.map(async (path) => {\n const content = await storage.readFile(path)\n return { path, content }\n }),\n )\n}\n\n/**\n * Restore files to their snapshotted state. Files that didn't exist\n * (content === null) are deleted. Files that existed are overwritten\n * with their original content.\n */\nexport async function restoreSnapshot(\n storage: StorageAdapter,\n snapshots: readonly FileSnapshot[],\n): Promise<string[]> {\n const reverted: string[] = []\n for (const snap of snapshots) {\n try {\n if (snap.content === null) {\n await storage.deleteFile(snap.path)\n } else {\n await storage.writeFile(snap.path, snap.content)\n }\n reverted.push(snap.path)\n } catch {\n // Best-effort restore — don't crash the orchestrator.\n }\n }\n return reverted\n}\n","/**\n * Synthesize — combine research findings into an implementation spec.\n *\n * This is CODE, not an LLM call. It takes the research step results\n * for a given implementation step and produces a combined spec string\n * that the Implementer agent receives as its task.\n *\n * The synthesis is deliberately simple: concatenate research findings\n * with the step's description and any file paths. The Implementer\n * LLM does the actual reasoning — the synthesizer just assembles context.\n */\n\nimport type { PlanStep, StepResult } from './types.js'\n\n/**\n * Build an implementation spec from the step's description, prior\n * research results, and file list.\n */\nexport function synthesizeSpec(step: PlanStep, allResults: readonly StepResult[]): string {\n const parts: string[] = []\n\n parts.push(`## Task\\n${step.description}`)\n\n // Include relevant research findings.\n const deps = new Set(step.dependsOn ?? [])\n const researchResults = allResults.filter(\n (r) => deps.has(r.stepId) && r.status === 'done' && r.output,\n )\n\n if (researchResults.length > 0) {\n parts.push('## Research Findings')\n for (const r of researchResults) {\n parts.push(`### ${r.stepId}\\n${r.output}`)\n }\n }\n\n // Include file list if specified.\n if (step.files && step.files.length > 0) {\n parts.push(`## Files\\n${step.files.map((f) => `- ${f}`).join('\\n')}`)\n }\n\n // Include the explicit spec if provided.\n if (step.spec) {\n parts.push(`## Spec\\n${step.spec}`)\n }\n\n return parts.join('\\n\\n')\n}\n","/**\n * Orchestrate — the main state machine.\n *\n * Pure JS. No platform APIs. Calls engine.run() internally for each\n * agent phase. Enforces retry policies, file snapshots for rollback,\n * dependency ordering, and parallel research execution.\n *\n * Flow:\n * 1. Plan — Planner agent produces a JSON plan (or use caller-supplied plan)\n * 2. Execute — for each step in dependency order:\n * - research: spawn N researchers in parallel\n * - implement: synthesize spec from research → run implementer with retry\n * - verify: run verifier → on fail, retry implementer or revert\n * - review: optional code review\n * 3. Finalize — Finalizer agent assembles the report\n * 4. Return — OrchestratorResult with full provenance\n */\n\nimport type { Engine } from '../engine/engine.js'\nimport type { Logger } from '../logging/logger.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport {\n runPlanner,\n runResearcher,\n runImplementer,\n runVerifier,\n runReviewer,\n runFinalizer,\n TokenTracker,\n} from './phases.js'\nimport { runWithRetry } from './retry.js'\nimport { snapshotFiles, restoreSnapshot } from './snapshot.js'\nimport { synthesizeSpec } from './synthesize.js'\nimport type {\n OrchestrateOptions,\n OrchestratorResult,\n Plan,\n PlanStep,\n ResolvedOrchestratorConfig,\n StepResult,\n} from './types.js'\n\n/**\n * Execute a structured orchestration. This is the internal implementation\n * called by engine.orchestrate().\n */\nexport async function orchestrate(\n engine: Engine,\n options: OrchestrateOptions,\n config: ResolvedOrchestratorConfig,\n storage: StorageAdapter,\n logger: Logger,\n): Promise<OrchestratorResult> {\n const start = Date.now()\n const tracker = new TokenTracker()\n tracker.maxTurns = config.agentMaxTurns\n const results: StepResult[] = []\n const allReverted: string[] = []\n\n logger.info('orchestrator.start', { runId: options.runId, task: options.task.slice(0, 100) })\n\n // ── Phase 1: Plan ──\n\n let plan: Plan | null = options.plan ?? null\n\n if (plan === null) {\n const planRetry = await runWithRetry(async () => {\n const p = await runPlanner(engine, options.task, options.runId, config.maxPlanSteps, tracker)\n if (p === null) throw new Error('Planner produced invalid plan')\n return p\n }, config.retries.plan)\n\n if (planRetry.success && planRetry.value) {\n plan = planRetry.value\n logger.info('orchestrator.plan', {\n summary: plan.summary,\n steps: plan.steps.length,\n })\n } else {\n logger.warn('orchestrator.plan failed, using single-step fallback', {\n error: planRetry.error,\n })\n // Fallback: single implementation step\n plan = {\n summary: options.task,\n steps: [{ id: 'fallback', description: options.task, action: 'implement' }],\n }\n }\n }\n\n // ── Phase 2: Execute steps in dependency order ──\n\n const completed = new Set<string>()\n const sorted = topologicalSort(plan.steps)\n\n for (const step of sorted) {\n // Wait for dependencies (already completed in topo order).\n const depsReady = (step.dependsOn ?? []).every((d) => completed.has(d))\n if (!depsReady) {\n // Dependency failed — skip this step.\n const failedDep = (step.dependsOn ?? []).find(\n (d) => results.find((r) => r.stepId === d)?.status === 'failed',\n )\n if (failedDep) {\n results.push({\n stepId: step.id,\n action: step.action,\n status: 'skipped',\n error: `Dependency \"${failedDep}\" failed`,\n attempts: 0,\n })\n logger.info('orchestrator.step skipped', {\n stepId: step.id,\n reason: `dep ${failedDep} failed`,\n })\n continue\n }\n }\n\n logger.info('orchestrator.step start', { stepId: step.id, action: step.action })\n\n switch (step.action) {\n case 'research': {\n const stepResult = await executeResearch(\n engine,\n step,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n\n case 'implement': {\n const stepResult = await executeImplement(\n engine,\n step,\n results,\n config,\n options.runId,\n storage,\n tracker,\n logger,\n allReverted,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n\n case 'verify': {\n const implStep = (step.dependsOn ?? [])\n .map((id) => results.find((r) => r.stepId === id))\n .find((r) => r?.action === 'implement')\n\n if (!implStep || implStep.status !== 'done') {\n results.push({\n stepId: step.id,\n action: 'verify',\n status: 'skipped',\n error: 'No implementation to verify',\n attempts: 0,\n })\n } else {\n const stepResult = await executeVerify(\n engine,\n step,\n implStep,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n }\n break\n }\n\n case 'review': {\n if (!config.enableReview) {\n results.push({\n stepId: step.id,\n action: 'review',\n status: 'skipped',\n error: 'Review disabled in config',\n attempts: 0,\n })\n } else {\n const review = await runReviewer(engine, step, results, options.runId, tracker)\n results.push(review)\n completed.add(step.id)\n }\n break\n }\n\n case 'custom':\n default: {\n // Custom steps are treated as research (read-only).\n const stepResult = await executeResearch(\n engine,\n step,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n }\n\n logger.info('orchestrator.step end', {\n stepId: step.id,\n status: results[results.length - 1]?.status,\n })\n }\n\n // ── Phase 3: Finalize ──\n\n const report = await runFinalizer(\n engine,\n options.task,\n results,\n allReverted,\n options.runId,\n tracker,\n )\n\n const allDone = results.every((r) => r.status === 'done' || r.status === 'skipped')\n const anyFailed = results.some((r) => r.status === 'failed' || r.status === 'reverted')\n const status = allDone ? 'done' : anyFailed ? 'partial' : 'done'\n\n logger.info('orchestrator.done', {\n status,\n steps: results.length,\n done: results.filter((r) => r.status === 'done').length,\n failed: results.filter((r) => r.status === 'failed').length,\n reverted: allReverted.length,\n agentRuns: tracker.runs,\n })\n\n return {\n status,\n output: report,\n plan,\n steps: results,\n tokensUsed: tracker.total,\n agentRuns: tracker.runs,\n reverted: allReverted,\n durationMs: Date.now() - start,\n }\n}\n\n// ---------- Phase executors ----------\n\nasync function executeResearch(\n engine: Engine,\n step: PlanStep,\n config: ResolvedOrchestratorConfig,\n runId: string,\n tracker: TokenTracker,\n _logger: Logger,\n): Promise<StepResult> {\n const retryResult = await runWithRetry(async () => {\n // Launch parallel researchers (up to maxParallelResearchers).\n const count = config.maxParallelResearchers\n const researchers = Array.from({ length: count }, (_, i) =>\n runResearcher(engine, step, runId, i, tracker),\n )\n const results = await Promise.all(researchers)\n const failed = results.filter((r) => r.status === 'failed')\n if (failed.length === results.length) throw new Error('All researchers failed')\n\n // Combine findings from successful researchers.\n const findings = results\n .filter((r) => r.status === 'done' && r.output)\n .map((r) => r.output!)\n .join('\\n\\n---\\n\\n')\n\n return findings\n }, config.retries.research)\n\n return {\n stepId: step.id,\n action: 'research',\n status: retryResult.success\n ? 'done'\n : config.retries.research.onExhausted === 'skip'\n ? 'skipped'\n : 'failed',\n output: retryResult.value,\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\nasync function executeImplement(\n engine: Engine,\n step: PlanStep,\n allResults: readonly StepResult[],\n config: ResolvedOrchestratorConfig,\n runId: string,\n storage: StorageAdapter,\n tracker: TokenTracker,\n logger: Logger,\n allReverted: string[],\n): Promise<StepResult> {\n // Snapshot files for rollback.\n const filePaths = step.files ?? []\n const snapshots =\n config.enableRollback && filePaths.length > 0 ? await snapshotFiles(storage, filePaths) : []\n\n // Synthesize spec from prior results.\n const spec = synthesizeSpec(step, allResults)\n\n const retryResult = await runWithRetry(async () => {\n const result = await runImplementer(engine, spec, step, runId, tracker)\n if (result.status === 'failed') throw new Error(result.error ?? 'Implementation failed')\n return result\n }, config.retries.implement)\n\n if (retryResult.success && retryResult.value) {\n return { ...retryResult.value, attempts: retryResult.attempts }\n }\n\n // Failed after retries — revert if enabled.\n if (config.enableRollback && snapshots.length > 0) {\n const reverted = await restoreSnapshot(storage, snapshots)\n allReverted.push(...reverted)\n logger.warn('orchestrator.revert', { stepId: step.id, files: reverted })\n return {\n stepId: step.id,\n action: 'implement',\n status: 'reverted',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n }\n\n return {\n stepId: step.id,\n action: 'implement',\n status: 'failed',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\nasync function executeVerify(\n engine: Engine,\n step: PlanStep,\n implResult: StepResult,\n config: ResolvedOrchestratorConfig,\n runId: string,\n tracker: TokenTracker,\n _logger: Logger,\n): Promise<StepResult> {\n const retryResult = await runWithRetry(async () => {\n const result = await runVerifier(engine, step, implResult, runId, tracker)\n if (result.status === 'failed') throw new Error(result.error ?? 'Verification failed')\n return result\n }, config.retries.verify)\n\n if (retryResult.success && retryResult.value) {\n return { ...retryResult.value, attempts: retryResult.attempts }\n }\n\n return {\n stepId: step.id,\n action: 'verify',\n status: 'failed',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\n// ---------- Topological sort ----------\n\nfunction topologicalSort(steps: readonly PlanStep[]): PlanStep[] {\n const byId = new Map(steps.map((s) => [s.id, s]))\n const visited = new Set<string>()\n const sorted: PlanStep[] = []\n\n function visit(step: PlanStep): void {\n if (visited.has(step.id)) return\n visited.add(step.id)\n for (const dep of step.dependsOn ?? []) {\n const depStep = byId.get(dep)\n if (depStep) visit(depStep)\n }\n sorted.push(step)\n }\n\n for (const step of steps) visit(step)\n return sorted\n}\n","/**\n * la-machina-engine — public API.\n *\n * The single entry point is `initEngine()`. Every config option has a\n * default; `initEngine()` with no arguments must work, so long as either\n * `config.model.apiKey` is set OR `ANTHROPIC_API_KEY` is in the environment.\n *\n * See plans/002-la-machina-engine.md for the full spec.\n */\n\nimport { mergeConfig } from './config/merge.js'\nimport type { ResolvedConfig, UserConfig } from './config/types.js'\nimport { Engine } from './engine/engine.js'\nimport { ConfigError } from './engine/errors.js'\n\n// ---------- model adapter ----------\nexport type {\n ModelAdapter,\n NormalizedEvent,\n StreamRequest,\n ModelToolDefinition,\n ModelMessage,\n} from './model/adapter.js'\nexport { AnthropicAdapter } from './model/anthropicAdapter.js'\nexport { AISdkAdapter } from './model/aiSdkAdapter.js'\nexport { createModelAdapter } from './model/factory.js'\n\n// ---------- engine surface ----------\nexport { Engine } from './engine/engine.js'\nexport type {\n StartOptions,\n ResumeAsyncOptions,\n WaitForOptions,\n WebhookOptions,\n EngineInternals,\n} from './engine/engine.js'\nexport { RunStateManager } from './engine/state.js'\nexport type {\n RunState,\n RunStatus,\n RunProgress,\n WebhookEvent,\n WebhookConfig,\n WebhookDelivery,\n} from './engine/state.js'\nexport { NodeBackgroundExecutor } from './engine/executor.js'\nexport type { BackgroundExecutor } from './engine/executor.js'\nexport { WebhookDispatcher, signPayload, RETRY_DELAYS_MS, MAX_ATTEMPTS } from './engine/webhook.js'\nexport {\n ApiError,\n AuthError,\n ConfigError,\n EngineError,\n NotImplementedError,\n RateLimitError,\n RunTimeoutError,\n StreamIncompleteError,\n StreamParseError,\n} from './engine/errors.js'\nexport type {\n PauseReason,\n ResumeOptions,\n RunOptions,\n RunResult,\n RunSnapshot,\n TokenUsage,\n TranscriptLocation,\n} from './engine/types.js'\n\n// ---------- config types ----------\nexport type {\n FlushPolicy,\n GateBeforeToolHook,\n LogEntry,\n LogLevel,\n LogSink,\n MemoryMode,\n MemoryScope,\n ModelProvider,\n PostRunHook,\n PostToolCallHook,\n PostTurnHook,\n PreRunHook,\n PreToolCallHook,\n PreTurnHook,\n ResolvedAgentsConfig,\n ResolvedConfig,\n ResolvedExecutionConfig,\n ResolvedHooksConfig,\n ResolvedLoggingConfig,\n ResolvedMemoryConfig,\n ResolvedModelConfig,\n ResolvedR2Config,\n ResolvedRunnerConfig,\n ResolvedSkillsConfig,\n ResolvedStorageConfig,\n ResolvedToolsConfig,\n ResolvedTranscriptConfig,\n StorageProvider,\n UserConfig,\n} from './config/types.js'\n\n// ---------- hook event payloads ----------\nexport type {\n GateDecision,\n PostRunEvent,\n PostToolCallEvent,\n PostTurnEvent,\n PreRunEvent,\n PreToolCallEvent,\n PreTurnEvent,\n StopHook,\n StopHookEvent,\n StopHookResult,\n} from './hooks/types.js'\n\n// ---------- tool contract (for custom tools) ----------\nexport { ToolRegistry, defineTool } from './tools/contract.js'\nexport { capabilityStub, withCapabilityCheck } from './tools/capabilityStub.js'\n\n// ---------- tool-result offload (Plan 021) ----------\nexport { createFetchDataTool } from './tools/fetchData.js'\nexport type { CreateFetchDataToolOptions } from './tools/fetchData.js'\nexport { defaultToolResultSummarizer } from './engine/toolResultSummarizer.js'\nexport type {\n ToolResultOffloadConfigV1,\n ToolResultSummarizerV1,\n ToolResultSummarizerCtxV1,\n ResolvedToolResultOffloadConfigV1,\n} from './engine/toolResultOffload.types.js'\nexport type { Tool, ToolContext, ToolResult } from './tools/contract.js'\n\n// ---------- unified response ----------\nexport { toResponse } from './engine/response.js'\nexport type { EngineResponse, ResponseError, ResponseMeta } from './engine/response.js'\n\n// ---------- structured output ----------\nexport { tryParseJSON, buildSchemaPrompt, validateOutput } from './engine/jsonOutput.js'\n\n// ---------- tool batching ----------\nexport { partitionToolCalls } from './engine/agentLoop.js'\nexport type { LoopProgress } from './engine/agentLoop.js'\nexport { StreamingToolExecutor } from './engine/streamingExecutor.js'\n\n// ---------- SendMessage (inter-agent communication) ----------\nexport { createSendMessageTool } from './tools/sendMessage.js'\n\n// ---------- subagent registry ----------\nexport { SubagentRegistry } from './subagent/registry.js'\nexport { isInForkChild, buildForkedMessages } from './subagent/fork.js'\nexport type {\n BackgroundAgentResult,\n SerializedAgent,\n SpawnResult,\n SubagentRegistryOptions,\n} from './subagent/registry.js'\n\n// ---------- storage adapter (for custom backends) ----------\nexport { LocalStorageAdapter } from './storage/localAdapter.js'\nexport { R2StorageAdapter } from './storage/r2Adapter.js'\nexport { R2BindingStorageAdapter } from './storage/r2BindingAdapter.js'\nexport type { R2BucketBinding } from './storage/r2BindingAdapter.js'\nexport { StorageError } from './storage/interface.js'\nexport type { EngineStorage, FileStat, StorageAdapter } from './storage/interface.js'\nexport type { R2ClientConfig } from './storage/r2Adapter.js'\n\n// ---------- transcript (for custom readers) ----------\nexport type { Entry } from './transcript/entries.js'\nexport type { TranscriptMeta, TranscriptStatus } from './transcript/meta.js'\n\n// ---------- memory (for callers that want direct access) ----------\nexport { Hippocampus } from './memory/hippocampus.js'\nexport { EpisodicMemory } from './memory/episodes.js'\nexport { createSmartMemory } from './memory/memoryConfig.js'\nexport type { SmartMemory, SmartMemoryConfig } from './memory/memoryConfig.js'\nexport type {\n Engram,\n EngramConfidence,\n EngramKind,\n EngramScope,\n EngramSource,\n Episode,\n} from './memory/types.js'\n\n// ---------- skills (for caller-driven discovery) ----------\nexport { loadSkills } from './skills/loader.js'\nexport type { LoadedSkill } from './skills/loader.js'\nexport { createSkillPageTool } from './skills/skillPage.js'\nexport type {\n SkillSource,\n ResolvedSkill,\n SkillOverride,\n SkillPageOverride,\n} from './skills/source.js'\nexport { StorageSkillSource } from './skills/storageSkillSource.js'\nexport { InlineSkillSource } from './skills/inlineSkillSource.js'\n\n// ---------- Knowledge (Plan 023) ----------\nexport { writeKnowledgeIndex, buildKnowledgeIndex } from './knowledge/indexer.js'\nexport { createSearchKnowledgeTool } from './tools/searchKnowledge.js'\nexport type { CreateSearchKnowledgeToolOptions } from './tools/searchKnowledge.js'\nexport { createReadKnowledgeTool } from './tools/readKnowledge.js'\nexport type { CreateReadKnowledgeToolOptions } from './tools/readKnowledge.js'\nexport { getExtractor } from './knowledge/extractors.js'\nexport type { KnowledgeExtractorV1 } from './knowledge/extractors.js'\nexport type {\n KnowledgeFolderRefV1,\n KnowledgeExternalLinkV1,\n KnowledgeFormatV1,\n KnowledgeConfigV1,\n ResolvedKnowledgeConfigV1,\n RunKnowledgeOptionsV1,\n SectionEntryV1,\n FileMetaV1,\n KnowledgeIndexV1,\n} from './knowledge/types.js'\n\n// ---------- ApiCall (Plan 020) ----------\nexport { createApiCallTool } from './tools/apiCall.js'\nexport type { CreateApiCallToolOptions } from './tools/apiCall.js'\nexport type {\n ApiHttpMethodV1,\n ApiAuthV1,\n ApiServiceV1,\n ApiResolverCtxV1,\n ApiAuthResolverV1,\n ApiRequestEventV1,\n ApiResponseEventV1,\n ResolvedApiConfigV1,\n} from './tools/apiCall.types.js'\nexport type { ResolvedApiConfig } from './config/types.js'\n\n// ---------- runtime detection ----------\nexport { detectRuntime, canSpawnProcesses, hasProcessLifecycle } from './runtime/detect.js'\nexport type { RuntimeKind } from './runtime/detect.js'\n\n// ---------- orchestrator ----------\nexport { orchestrate } from './orchestrator/orchestrate.js'\nexport { parsePlan } from './orchestrator/planParser.js'\nexport { runWithRetry } from './orchestrator/retry.js'\nexport { snapshotFiles, restoreSnapshot } from './orchestrator/snapshot.js'\nexport { synthesizeSpec } from './orchestrator/synthesize.js'\nexport type {\n OrchestrateOptions,\n OrchestratorResult,\n Plan,\n PlanStep,\n StepResult,\n StepStatus,\n FileSnapshot,\n RetryPolicy,\n ResolvedOrchestratorConfig,\n} from './orchestrator/types.js'\nexport { PlanSchema, PlanStepSchema } from './orchestrator/types.js'\n\n// ---------- agents (for caller-driven custom agent loading) ----------\nexport { loadAgents } from './agents/loader.js'\nexport type { AgentDefinition } from './tools/agent.js'\n\n// ---------- coordinator ----------\nexport {\n isCoordinatorMode,\n buildWorkerAgent,\n getCoordinatorBasePrompt,\n} from './coordinator/mode.js'\nexport { getCoordinatorSystemPrompt } from './coordinator/prompt.js'\nexport type { ResolvedCoordinatorConfig } from './coordinator/types.js'\n\n// ---------- mcp (caller-driven access to the Model Context Protocol) ----------\nexport { McpClient } from './mcp/client.js'\nexport { BindingHttpTransport } from './mcp/bindingTransport.js'\nexport { McpManager } from './mcp/manager.js'\nexport { defaultSamplingHandler, DEFAULT_SAMPLING_MAX_DEPTH } from './mcp/sampling.js'\nexport type {\n SamplingHandler,\n SamplingRequest,\n SamplingResponse,\n SamplingMessage,\n SamplingTextBlock,\n SamplingContext,\n SamplingModelPreferences,\n} from './mcp/sampling.js'\nexport type { McpInstructionDelta } from './mcp/manager.js'\nexport { McpConnectionError, McpProtocolError, McpTimeoutError } from './mcp/errors.js'\nexport { adaptMcpTool, mcpToolName } from './mcp/toolAdapter.js'\nexport type {\n McpCallResult,\n McpServerState,\n McpToolDef,\n ResolvedMcpConfig,\n ResolvedMcpHttpServerConfig,\n ResolvedMcpServerConfig,\n ResolvedMcpSseServerConfig,\n ResolvedMcpStdioServerConfig,\n} from './mcp/types.js'\n\n// ---------- system prompt builder ----------\nexport { buildSystemPrompt } from './prompts/systemPrompt.js'\nexport type { BuildSystemPromptOptions } from './prompts/systemPrompt.js'\n\n// ---------- logging ----------\nexport { createLogger } from './logging/logger.js'\nexport type { Logger } from './logging/logger.js'\n\n// ---------- permissions ----------\nexport { buildPermissionPolicy } from './permissions/evaluator.js'\nexport type { PermissionPolicy } from './permissions/evaluator.js'\nexport { SAFE_TOOL_ALLOWLIST, isSafeTool } from './permissions/allowlist.js'\nexport { parseRule, parseRules, matchesRule } from './permissions/rules.js'\nexport type {\n PermissionAction,\n PermissionDecision,\n PermissionMode,\n PermissionRule,\n ResolvedPermissionsConfig,\n} from './permissions/types.js'\n\nexport const ENGINE_VERSION = '0.0.0'\n\n/**\n * Initialize an Engine with (optional) user config merged over defaults.\n *\n * @param user Partial config. Every field is optional.\n * @returns A fully-configured Engine ready to `run()` (once Phase 7 lands).\n * @throws {ConfigError} If config validation fails or `apiKey` cannot be\n * resolved from either `config.model.apiKey` or `ANTHROPIC_API_KEY` env.\n */\nexport function initEngine(user: UserConfig = {}): Engine {\n // `mergeConfig` only throws ZodError (subclass of Error), so `.message`\n // is always defined. If a future refactor introduces non-Error throws,\n // the type-check on `err` below would need widening.\n let resolved: ResolvedConfig\n try {\n resolved = mergeConfig(user)\n } catch (err) {\n throw new ConfigError(`Invalid config: ${(err as Error).message}`)\n }\n\n resolved = resolveApiKey(resolved)\n\n return new Engine(resolved)\n}\n\n/**\n * Resolve `model.apiKey` with env-var fallback. If both are missing, throw.\n */\nfunction resolveApiKey(config: ResolvedConfig): ResolvedConfig {\n if (config.model.apiKey !== '') return config\n\n const fromEnv = process.env.ANTHROPIC_API_KEY\n if (fromEnv !== undefined && fromEnv !== '') {\n return {\n ...config,\n model: { ...config.model, apiKey: fromEnv },\n }\n }\n\n throw new ConfigError(\n 'apiKey is required. Set `config.model.apiKey` or the ANTHROPIC_API_KEY environment variable.',\n )\n}\n","/**\n * Deep-merge user config over DEFAULTS with three rules:\n *\n * 1. Plain objects merge recursively (deep merge).\n * 2. Arrays REPLACE — if the user provides `tools.enabled = ['Read']`, the\n * result is `['Read']`, not `['*', 'Read']`. Empty arrays are honored.\n * 3. `undefined` in the override preserves the default. Explicit falsy\n * values (`0`, `false`, `''`) are honored.\n *\n * The user config is validated by `UserConfigSchema` before merge. The\n * merged result is validated by `ResolvedConfigSchema` after merge, so both\n * input and output shape are guaranteed correct.\n *\n * The DEFAULTS object is never mutated; every merge returns a fresh object.\n *\n * Clone strategy — `deepClone` below — matters because user config can\n * contain:\n * - Hook functions (`hooks.preRun: [fn]`)\n * - Tool definitions (`tools.custom: [{ name, execute, inputSchema }]`)\n * - Zod schemas nested inside those tool definitions\n * - Logger callables (`logging.sink: fn`)\n *\n * None of those are cloneable via `structuredClone`. We deep-copy plain\n * objects and arrays (so callers get a fresh shell), but share references\n * for functions, Zod schemas, and any non-plain object. That gives us\n * isolation from caller-side mutation of the containers while preserving\n * the identity of the callable values the engine actually needs to invoke.\n */\n\nimport { DEFAULTS } from './defaults.js'\nimport { ResolvedConfigSchema, UserConfigSchema } from './schema.js'\nimport type { ResolvedConfig, UserConfig } from './types.js'\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false\n return Object.getPrototypeOf(value) === Object.prototype\n}\n\n/**\n * Deep-clone a value:\n * - primitives (including functions and symbols) → return as-is\n * - plain objects → new object with recursively cloned entries\n * - arrays → new array with recursively cloned elements\n * - non-plain objects (Zod schemas, class instances, Buffers, …) → shared\n *\n * Sharing non-plain objects is deliberate. Zod schemas, tool definitions\n * produced by `defineTool`, and the like carry behavior that `structuredClone`\n * cannot reproduce. Plain-object containers are still fresh, so mutation by\n * the caller after `initEngine()` cannot affect the engine's internal config.\n */\nfunction deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) {\n return value.map((v) => deepClone(v)) as unknown as T\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n out[k] = deepClone(v)\n }\n return out as T\n }\n // Non-plain object: Zod schema, class instance, Buffer, Date, etc.\n // Share the reference — the caller owns it and the engine only reads it.\n return value\n}\n\nfunction deepMerge<T>(base: T, override: Record<string, unknown>): T {\n const baseObj = base as unknown as Record<string, unknown>\n // Caller contract: both arguments are plain objects. The top-level call\n // passes DEFAULTS + validated user config (both objects), and recursion\n // only fires inside an `isPlainObject && isPlainObject` guard below, so\n // we never recurse into a primitive or array.\n\n const result: Record<string, unknown> = {}\n const keys = new Set<string>([...Object.keys(baseObj), ...Object.keys(override)])\n\n for (const key of keys) {\n const baseValue = baseObj[key]\n const overrideValue = override[key]\n\n if (overrideValue === undefined) {\n result[key] = deepClone(baseValue)\n continue\n }\n if (Array.isArray(overrideValue)) {\n result[key] = deepClone(overrideValue)\n continue\n }\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue)\n continue\n }\n result[key] = deepClone(overrideValue)\n }\n\n return result as T\n}\n\n/**\n * Runtime-only fields on `api` that must not flow through the Zod\n * schema (Plan 020). Holding credentials + callbacks in a shape the\n * schema validates would risk them surfacing through serialization;\n * we split them out before validation and re-attach after.\n */\nconst API_RUNTIME_KEYS = ['env', 'resolveAuth', 'onRequest', 'onResponse'] as const\n\nfunction splitApiRuntime(user: UserConfig): {\n stripped: UserConfig\n runtime: Partial<Record<(typeof API_RUNTIME_KEYS)[number], unknown>>\n} {\n const api = (user as { api?: Record<string, unknown> }).api\n if (api === undefined) return { stripped: user, runtime: {} }\n const runtime: Partial<Record<(typeof API_RUNTIME_KEYS)[number], unknown>> = {}\n const schemaSafe: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(api)) {\n if ((API_RUNTIME_KEYS as readonly string[]).includes(k)) {\n runtime[k as (typeof API_RUNTIME_KEYS)[number]] = v\n } else {\n schemaSafe[k] = v\n }\n }\n const clone = { ...user, api: schemaSafe } as UserConfig\n return { stripped: clone, runtime }\n}\n\n/**\n * Merge a (possibly-partial) user config over DEFAULTS, returning a fully\n * resolved config. Throws on schema violation (unknown keys, invalid enum\n * values, numeric invariant failures, cross-field constraint failures).\n */\n/**\n * Plan 022 — coerce the deprecated `memory.scope: 'global'` input\n * value to `'workspace'` with a one-shot warning. Legacy configs\n * keep parsing; the resolved schema only ever sees 'workspace'.\n */\nfunction coerceDeprecatedMemoryScope(user: UserConfig): UserConfig {\n const scope = (user as { memory?: { scope?: string } }).memory?.scope\n if (scope !== 'global') return user\n console.warn(\n '[la-machina] config.memory.scope: \"global\" is deprecated and has ' +\n 'been rewritten to \"workspace\". Cross-tenant memory sharing was ' +\n 'removed in Plan 022 — the workspace is the tenant root. This field ' +\n 'value will be rejected outright in a future major release.',\n )\n const memory = user.memory ?? {}\n return {\n ...user,\n memory: { ...memory, scope: 'workspace' } as UserConfig['memory'],\n }\n}\n\n/**\n * Plan 021 — split the summarizer callback off `compaction.toolResultOffload`\n * before Zod parse (it's function-valued; the schema only validates\n * scalars). Also fills inner-field defaults so users can write\n * `{ enabled: true }` and get sensible values for the rest.\n *\n * Defaults: thresholdBytes=2048, maxPreviewChars=500.\n */\nconst OFFLOAD_DEFAULTS = { thresholdBytes: 2048, maxPreviewChars: 500 } as const\n\nfunction splitOffloadRuntime(user: UserConfig): {\n stripped: UserConfig\n summarizer?: unknown\n} {\n const block = (user as { compaction?: { toolResultOffload?: Record<string, unknown> } })\n .compaction?.toolResultOffload\n if (block === undefined) return { stripped: user }\n const { summarizer, ...schemaSafe } = block\n // Fill defaults for any missing scalar so the resolved schema\n // (which requires all three) accepts the merged config.\n const filled = {\n enabled: schemaSafe.enabled ?? false,\n thresholdBytes: schemaSafe.thresholdBytes ?? OFFLOAD_DEFAULTS.thresholdBytes,\n maxPreviewChars: schemaSafe.maxPreviewChars ?? OFFLOAD_DEFAULTS.maxPreviewChars,\n }\n const clone = {\n ...user,\n compaction: {\n ...(user.compaction ?? {}),\n toolResultOffload: filled,\n },\n } as UserConfig\n return { stripped: clone, summarizer }\n}\n\n/**\n * Plan 023 — fill knowledge config inner defaults so callers can\n * write `{ enabled: true }` and get sensible values for the rest.\n *\n * Defaults: maxSearchResults=5, maxReadBytes=10_000.\n */\nconst KNOWLEDGE_DEFAULTS = { maxSearchResults: 5, maxReadBytes: 10_000 } as const\n\nfunction fillKnowledgeDefaults(user: UserConfig): UserConfig {\n const block = (user as { knowledge?: Record<string, unknown> }).knowledge\n if (block === undefined) return user\n const filled = {\n enabled: block.enabled ?? false,\n maxSearchResults: block.maxSearchResults ?? KNOWLEDGE_DEFAULTS.maxSearchResults,\n maxReadBytes: block.maxReadBytes ?? KNOWLEDGE_DEFAULTS.maxReadBytes,\n }\n return { ...user, knowledge: filled } as UserConfig\n}\n\nexport function mergeConfig(user: UserConfig): ResolvedConfig {\n const withCoercedScope = coerceDeprecatedMemoryScope(user)\n const withKnowledge = fillKnowledgeDefaults(withCoercedScope)\n const { stripped: afterOffload, summarizer } = splitOffloadRuntime(withKnowledge)\n const { stripped, runtime } = splitApiRuntime(afterOffload)\n const validatedUser = UserConfigSchema.parse(stripped)\n const merged = deepMerge(DEFAULTS, validatedUser)\n const resolved = ResolvedConfigSchema.parse(merged) as unknown as ResolvedConfig\n\n // Re-attach runtime-only api fields. Deliberately assigned AFTER\n // Zod validation + structural clone so they never round-trip\n // through the schema. This is the non-persistence guarantee.\n if (resolved.api !== undefined && Object.keys(runtime).length > 0) {\n const mutableResolved = resolved as unknown as { api: Record<string, unknown> }\n mutableResolved.api = {\n ...resolved.api,\n ...runtime,\n }\n } else if (Object.keys(runtime).length > 0) {\n // User supplied ONLY runtime fields (no `services`). That's not a\n // viable config — no tool gets registered. Keep api undefined; the\n // runtime values are discarded.\n }\n\n // Re-attach the offload summarizer callback. Only when the block\n // is present on the resolved config AND a summarizer was stripped.\n if (summarizer !== undefined && resolved.compaction.toolResultOffload !== undefined) {\n const mutable = resolved.compaction as unknown as {\n toolResultOffload: Record<string, unknown>\n }\n mutable.toolResultOffload = {\n ...resolved.compaction.toolResultOffload,\n summarizer,\n }\n }\n return resolved\n}\n","/**\n * Default values for every config option.\n *\n * This file is the single source of truth for \"what zero-config looks like.\"\n * Every default is locked by `test/unit/config/defaults.test.ts` — changing\n * a value here requires updating that test, which forces a deliberate\n * decision instead of silent drift.\n *\n * Notes on specific defaults:\n * - `model.apiKey` is an empty string; `initEngine()` fills it from\n * `ANTHROPIC_API_KEY` at runtime, or throws if neither is set.\n * - `memory.mode` defaults to `'off'` (stateless) — safer for production.\n * - `tools.enabled` is `['*']` meaning all registered tools are on.\n * - `storage.provider` is `'local'` — cloud (R2) is opt-in via config.\n */\n\nimport type { ResolvedConfig } from './types.js'\n\nexport const DEFAULTS: ResolvedConfig = {\n model: {\n provider: 'anthropic',\n modelId: 'claude-opus-4-6',\n apiKey: '',\n baseURL: undefined,\n maxTokens: 8192,\n temperature: 1,\n maxRetries: 2,\n },\n storage: {\n provider: 'local',\n rootPath: '~/.claude',\n workspaceId: 'default',\n r2: undefined,\n },\n memory: {\n mode: 'off',\n scope: 'workspace',\n },\n tools: {\n enabled: ['*'],\n disabled: [],\n custom: [],\n },\n agents: {\n builtins: ['general-purpose'],\n customPath: undefined,\n },\n skills: {\n path: undefined,\n autoload: false,\n },\n execution: {\n maxTurns: 50,\n maxSubagentDepth: 5,\n turnTimeoutMs: 300_000,\n runTimeoutMs: 1_800_000,\n contextLimit: 200_000,\n maxToolConcurrency: 10,\n },\n transcript: {\n enabled: true,\n flushPolicy: 'turn-end',\n idleFlushMs: 2000,\n },\n hooks: {\n preRun: [],\n postRun: [],\n preTurn: [],\n postTurn: [],\n preToolCall: [],\n postToolCall: [],\n gateBeforeTool: undefined,\n stopHooks: [],\n },\n logging: {\n level: 'warn',\n sink: 'stderr',\n },\n mcp: {\n servers: {},\n connectTimeoutMs: 10_000,\n callTimeoutMs: 60_000,\n shutdownTimeoutMs: 5_000,\n },\n permissions: {\n mode: 'open',\n rules: [],\n },\n compaction: {\n strategy: 'auto',\n threshold: 0.85,\n keepLast: 6,\n summaryMaxTokens: 4096,\n microcompact: true,\n microcompactAgeMs: 300_000,\n },\n coordinator: {\n enabled: false,\n workerTools: ['Bash', 'Read', 'Write', 'Edit', 'Glob', 'Grep'],\n maxConcurrentWorkers: 5,\n },\n orchestrator: {\n enabled: false,\n retries: {\n plan: { maxAttempts: 2, backoffMs: 1000, onExhausted: 'fail' as const },\n research: { maxAttempts: 2, backoffMs: 500, onExhausted: 'skip' as const },\n implement: { maxAttempts: 3, backoffMs: 2000, onExhausted: 'revert' as const },\n verify: { maxAttempts: 2, backoffMs: 1000, onExhausted: 'revert' as const },\n review: { maxAttempts: 1, backoffMs: 0, onExhausted: 'skip' as const },\n },\n maxParallelResearchers: 3,\n enableReview: false,\n enableRollback: true,\n maxPlanSteps: 20,\n agentMaxTurns: 15,\n },\n} as const\n","/**\n * Zod schemas for user-supplied and fully-resolved config.\n *\n * Two schemas, matching the two type shapes in `./types.ts`:\n *\n * - `UserConfigSchema` — validates what the caller passes to `initEngine()`.\n * Every field is optional. Unknown keys are `.strict()` rejected.\n *\n * - `ResolvedConfigSchema` — validates the fully-merged internal config.\n * Every field is required. Also enforces cross-field invariants (e.g.\n * `storage.provider === 'r2'` requires `storage.r2` to be present).\n *\n * Numeric invariants:\n * - `maxTurns`, `maxSubagentDepth`, `maxTokens` must be positive integers\n * - `temperature` must be between 0 and 2 inclusive\n * - `turnTimeoutMs`, `runTimeoutMs`, `idleFlushMs` must be non-negative integers\n * - `workspaceId` must match `/^[a-zA-Z0-9_-]+$/` (storage-safe characters)\n */\n\nimport { z } from 'zod'\n\n// ---------- enums ----------\n\nconst ModelProviderEnum = z.enum([\n 'anthropic',\n 'openai',\n 'google',\n 'openai-compatible',\n 'bedrock',\n 'vertex',\n 'proxy',\n])\nconst StorageProviderEnum = z.enum(['local', 'r2', 'r2-binding'])\nconst MemoryModeEnum = z.enum(['off', 'read-only', 'read-write'])\n// Plan 022: user-side enum still accepts 'global' to keep existing\n// configs parsing, but `mergeConfig` emits a deprecation warning\n// and coerces to 'workspace' before the resolved schema sees it.\n// The resolved enum below is narrowed to 'workspace' only.\nconst MemoryScopeUserEnum = z.enum(['workspace', 'global'])\nconst MemoryScopeResolvedEnum = z.enum(['workspace'])\nconst FlushPolicyEnum = z.enum(['turn-end', 'entry', 'manual'])\nconst LogLevelEnum = z.enum(['silent', 'error', 'warn', 'info', 'debug'])\n\n// ---------- resolved sub-schemas ----------\n\nconst R2ConfigResolved = z\n .object({\n bucket: z.string().min(1),\n region: z.string().min(1),\n accessKeyId: z.string().min(1),\n secretAccessKey: z.string().min(1),\n endpoint: z.string().url().optional(),\n })\n .strict()\n\nconst ModelConfigResolved = z\n .object({\n provider: ModelProviderEnum,\n modelId: z.string().min(1),\n apiKey: z.string(),\n baseURL: z.string().url().optional(),\n maxTokens: z.number().int().positive(),\n temperature: z.number().min(0).max(2),\n maxRetries: z.number().int().nonnegative(),\n })\n .strict()\n\n// Shape check for the R2 binding object (env.BUCKET). We don't import\n// @cloudflare/workers-types; a structural check for the methods we use\n// keeps the engine dep-free.\nconst R2BucketBindingShape = z.custom<{\n head: (...args: unknown[]) => unknown\n get: (...args: unknown[]) => unknown\n put: (...args: unknown[]) => unknown\n delete: (...args: unknown[]) => unknown\n list: (...args: unknown[]) => unknown\n}>((val) => {\n if (val === null || typeof val !== 'object') return false\n const o = val as Record<string, unknown>\n return (\n typeof o.head === 'function' &&\n typeof o.get === 'function' &&\n typeof o.put === 'function' &&\n typeof o.delete === 'function' &&\n typeof o.list === 'function'\n )\n}, 'r2Binding must expose head/get/put/delete/list methods')\n\nconst StorageConfigResolved = z\n .object({\n provider: StorageProviderEnum,\n rootPath: z.string().min(1),\n workspaceId: z.string().regex(/^[a-zA-Z0-9_-]+$/, 'workspaceId: only [a-zA-Z0-9_-] allowed'),\n r2: R2ConfigResolved.optional(),\n r2Binding: R2BucketBindingShape.optional(),\n })\n .strict()\n .refine((s) => s.provider !== 'r2' || s.r2 !== undefined, {\n message: 'storage.r2 is required when storage.provider === \"r2\"',\n path: ['r2'],\n })\n .refine((s) => s.provider !== 'r2-binding' || s.r2Binding !== undefined, {\n message: 'storage.r2Binding is required when storage.provider === \"r2-binding\"',\n path: ['r2Binding'],\n })\n\nconst MemoryConfigResolved = z\n .object({\n mode: MemoryModeEnum,\n scope: MemoryScopeResolvedEnum,\n })\n .strict()\n\nconst ToolsConfigResolved = z\n .object({\n enabled: z.array(z.string()),\n disabled: z.array(z.string()),\n custom: z.array(z.unknown()),\n })\n .strict()\n\nconst AgentsConfigResolved = z\n .object({\n builtins: z.array(z.string()),\n customPath: z.string().optional(),\n })\n .strict()\n\nconst SkillsConfigResolved = z\n .object({\n path: z.string().optional(),\n autoload: z.boolean(),\n /**\n * SSRF allowlist for per-run `InlineSkillSource` url fetches\n * (Plan 017). When undefined/empty, any URL is allowed. When set,\n * each fetched URL's host must match an entry exactly or be a\n * subdomain of it.\n */\n allowedHosts: z.array(z.string().min(1)).optional(),\n })\n .strict()\n\nconst ExecutionConfigResolved = z\n .object({\n maxTurns: z.number().int().positive(),\n maxSubagentDepth: z.number().int().positive(),\n turnTimeoutMs: z.number().int().nonnegative(),\n runTimeoutMs: z.number().int().nonnegative(),\n contextLimit: z.number().int().positive(),\n maxToolConcurrency: z.number().int().positive(),\n })\n .strict()\n\nconst TranscriptConfigResolved = z\n .object({\n enabled: z.boolean(),\n flushPolicy: FlushPolicyEnum,\n idleFlushMs: z.number().int().nonnegative(),\n })\n .strict()\n\nconst HooksConfigResolved = z\n .object({\n preRun: z.array(z.function()),\n postRun: z.array(z.function()),\n preTurn: z.array(z.function()),\n postTurn: z.array(z.function()),\n preToolCall: z.array(z.function()),\n postToolCall: z.array(z.function()),\n gateBeforeTool: z.function().optional(),\n /**\n * When true, the parent's gateBeforeTool is threaded into every\n * subagent's inner loop. A gate denial inside a subagent then\n * pauses the parent run with RunSnapshot.pendingSubagent populated.\n * Default: false (subagent tool calls ignore the parent's gate).\n */\n propagateGateToSubagents: z.boolean().optional(),\n stopHooks: z.array(z.function()),\n })\n .strict()\n\n// ---------- MCP schemas ----------\n\nconst McpStdioServerConfigResolved = z\n .object({\n type: z.literal('stdio'),\n command: z.string().min(1, 'command cannot be empty'),\n args: z.array(z.string()).readonly(),\n env: z.record(z.string(), z.string()).optional(),\n cwd: z.string().optional(),\n isolateEnv: z.boolean(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpHttpServerConfigResolved = z\n .object({\n type: z.literal('http'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).optional(),\n preferBindingTransport: z.boolean().optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpSseServerConfigResolved = z\n .object({\n type: z.literal('sse'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpServerConfigResolved = z.discriminatedUnion('type', [\n McpStdioServerConfigResolved,\n McpHttpServerConfigResolved,\n McpSseServerConfigResolved,\n])\n\nconst McpConfigResolved = z\n .object({\n servers: z.record(z.string().min(1), McpServerConfigResolved),\n connectTimeoutMs: z.number().int().nonnegative(),\n callTimeoutMs: z.number().int().nonnegative(),\n shutdownTimeoutMs: z.number().int().positive(),\n })\n .strict()\n\n// ---------- permissions schema ----------\n\nconst CompactionStrategyEnum = z.enum(['drop-middle', 'summarize', 'session-memory', 'auto'])\n\n// Plan 021 — tool-result offload. Scalars-only schema; the\n// summarizer callback (function-valued) is stripped out of user\n// config by `mergeConfig` before Zod parse and re-attached on the\n// resolved config afterwards. Structural non-persistence: callbacks\n// never round-trip through the schema.\nconst ToolResultOffloadConfigResolved = z\n .object({\n enabled: z.boolean(),\n thresholdBytes: z.number().int().positive(),\n maxPreviewChars: z.number().int().positive(),\n })\n .strict()\n\nconst CompactionConfigResolved = z\n .object({\n strategy: CompactionStrategyEnum,\n threshold: z.number().min(0).max(1),\n keepLast: z.number().int().positive(),\n summaryMaxTokens: z.number().int().positive(),\n microcompact: z.boolean(),\n microcompactAgeMs: z.number().int().nonnegative(),\n toolResultOffload: ToolResultOffloadConfigResolved.optional(),\n })\n .strict()\n\nconst CoordinatorConfigResolved = z\n .object({\n enabled: z.boolean(),\n workerTools: z.array(z.string()).readonly(),\n maxConcurrentWorkers: z.number().int().positive(),\n })\n .strict()\n\nconst RetryPolicySchema = z\n .object({\n maxAttempts: z.number().int().positive(),\n backoffMs: z.number().int().nonnegative(),\n onExhausted: z.enum(['revert', 'skip', 'fail']),\n })\n .strict()\n\nconst OrchestratorConfigResolved = z\n .object({\n enabled: z.boolean(),\n retries: z\n .object({\n plan: RetryPolicySchema,\n research: RetryPolicySchema,\n implement: RetryPolicySchema,\n verify: RetryPolicySchema,\n review: RetryPolicySchema,\n })\n .strict(),\n maxParallelResearchers: z.number().int().positive(),\n enableReview: z.boolean(),\n enableRollback: z.boolean(),\n maxPlanSteps: z.number().int().positive(),\n agentMaxTurns: z.number().int().positive(),\n })\n .strict()\n\nconst PermissionModeEnum = z.enum(['open', 'rules', 'locked'])\n\nconst PermissionsConfigResolved = z\n .object({\n mode: PermissionModeEnum,\n rules: z.array(z.string()).readonly(),\n })\n .strict()\n\nconst LogSinkSchema = z.union([z.literal('stderr'), z.literal('none'), z.function()])\n\nconst LoggingConfigResolved = z\n .object({\n level: LogLevelEnum,\n sink: LogSinkSchema,\n })\n .strict()\n\n// ---------- ApiCall (Plan 020) ----------\n//\n// We validate only the `services` list + `maxResponseBytes`. Env,\n// `resolveAuth`, `onRequest`, `onResponse` are excluded from the\n// schema — those runtime-only fields live on ResolvedConfig.api but\n// are stripped before we call `ResolvedConfigSchema.parse`. That's\n// the non-persistence guarantee: credentials cannot round-trip\n// through the Zod-validated shape.\n\nconst ApiHttpMethodEnum = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])\n\nconst ApiAuthSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('none') }).strict(),\n z.object({ type: z.literal('bearer'), tokenRef: z.string().min(1) }).strict(),\n z\n .object({\n type: z.literal('header'),\n name: z.string().min(1),\n valueRef: z.string().min(1),\n })\n .strict(),\n z\n .object({\n type: z.literal('basic'),\n userRef: z.string().min(1),\n passRef: z.string().min(1),\n })\n .strict(),\n z.object({ type: z.literal('custom'), id: z.string().min(1) }).strict(),\n])\n\nconst ApiServiceSchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n baseUrl: z.string().url(),\n auth: ApiAuthSchema.optional(),\n // Allow both strings and RegExp values via z.union — RegExp is\n // serialized as its source when cloned, so we accept both.\n allowedPaths: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),\n allowedMethods: z.array(ApiHttpMethodEnum).optional(),\n defaultHeaders: z.record(z.string(), z.string()).optional(),\n maxBodyBytes: z.number().int().positive().optional(),\n })\n .strict()\n\nconst ApiConfigResolved = z\n .object({\n services: z.array(ApiServiceSchema),\n maxResponseBytes: z.number().int().positive().optional(),\n })\n .strict()\n\n// ---------- knowledge (Plan 023) ----------\n//\n// Engine-level config validates ONLY scalars. Per-run external\n// links carry an optional `headers` field (auth secrets) — those\n// live on the runtime-only side and are stripped/re-attached in\n// mergeConfig the same way Plan 020's ApiCall env is handled.\n\nconst KnowledgeConfigResolved = z\n .object({\n enabled: z.boolean(),\n maxSearchResults: z.number().int().positive(),\n maxReadBytes: z.number().int().positive(),\n })\n .strict()\n\n// ---------- runner (Plan 019) ----------\n//\n// Both `url` and `secret` are required when the block is present. The\n// whole block itself is optional (the engine wraps this schema with\n// `.optional()` at the top level). Empty strings are rejected — an\n// empty URL is a misconfiguration, and auth is mandatory.\nconst RunnerConfigResolved = z\n .object({\n url: z.string().url(),\n secret: z.string().min(1, 'runner.secret cannot be empty'),\n })\n .strict()\n\n// ---------- resolved top-level schema ----------\n\nexport const ResolvedConfigSchema = z\n .object({\n model: ModelConfigResolved,\n storage: StorageConfigResolved,\n memory: MemoryConfigResolved,\n tools: ToolsConfigResolved,\n agents: AgentsConfigResolved,\n skills: SkillsConfigResolved,\n execution: ExecutionConfigResolved,\n transcript: TranscriptConfigResolved,\n hooks: HooksConfigResolved,\n logging: LoggingConfigResolved,\n mcp: McpConfigResolved,\n permissions: PermissionsConfigResolved,\n compaction: CompactionConfigResolved,\n coordinator: CoordinatorConfigResolved,\n orchestrator: OrchestratorConfigResolved,\n runner: RunnerConfigResolved.optional(),\n api: ApiConfigResolved.optional(),\n knowledge: KnowledgeConfigResolved.optional(),\n })\n .strict()\n\n// ---------- user (deep-partial) sub-schemas ----------\n//\n// We declare these explicitly instead of using .deepPartial() so that each\n// level is strictly keyed (unknown nested keys still rejected) while every\n// field itself is optional. Strictness without deepPartial would reject\n// fields missing from the literal; .deepPartial() alone would strip .strict().\n\nconst R2ConfigUser = R2ConfigResolved.partial()\n\nconst ModelConfigUser = ModelConfigResolved.partial()\n\nconst StorageConfigUser = z\n .object({\n provider: StorageProviderEnum.optional(),\n rootPath: z.string().min(1).optional(),\n workspaceId: z\n .string()\n .regex(/^[a-zA-Z0-9_-]+$/, 'workspaceId: only [a-zA-Z0-9_-] allowed')\n .optional(),\n r2: R2ConfigUser.optional(),\n r2Binding: R2BucketBindingShape.optional(),\n })\n .strict()\n\n// Knowledge user schema — same shape as resolved, but every field\n// optional. mergeConfig fills sensible defaults so callers can\n// write `{ enabled: true }` and not have to remember every knob.\nconst KnowledgeConfigUser = KnowledgeConfigResolved.partial()\n\n// User schema accepts the deprecated 'global' scope value so existing\n// configs parse; `mergeConfig` warns + coerces it to 'workspace'\n// before the resolved schema validates the final shape.\nconst MemoryConfigUser = z\n .object({\n mode: MemoryModeEnum.optional(),\n scope: MemoryScopeUserEnum.optional(),\n })\n .strict()\nconst ToolsConfigUser = ToolsConfigResolved.partial()\nconst AgentsConfigUser = AgentsConfigResolved.partial()\nconst SkillsConfigUser = SkillsConfigResolved.partial()\nconst ExecutionConfigUser = ExecutionConfigResolved.partial()\nconst TranscriptConfigUser = TranscriptConfigResolved.partial()\nconst HooksConfigUser = HooksConfigResolved.partial()\nconst LoggingConfigUser = LoggingConfigResolved.partial()\n\n// MCP user shape: each transport variant is deeply-partial. Since we\n// can't use a discriminated union on an optional `type` field at the user\n// level (callers may omit it), we merge them into one permissive shape.\n// The resolved schema (above) enforces the discriminator strictly.\nconst McpServerConfigUser = z\n .object({\n type: z.enum(['stdio', 'http', 'sse']).optional(),\n // stdio fields\n command: z.string().min(1).optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n cwd: z.string().optional(),\n isolateEnv: z.boolean().optional(),\n // http + sse fields\n url: z.string().url().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n preferBindingTransport: z.boolean().optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpConfigUser = z\n .object({\n servers: z.record(z.string().min(1), McpServerConfigUser).optional(),\n connectTimeoutMs: z.number().int().nonnegative().optional(),\n callTimeoutMs: z.number().int().nonnegative().optional(),\n shutdownTimeoutMs: z.number().int().positive().optional(),\n })\n .strict()\n\nconst PermissionsConfigUser = PermissionsConfigResolved.partial()\n// RunnerConfigUser intentionally mirrors the resolved schema — both\n// `url` and `secret` are required when the caller opts into handoff.\n// Partial here would allow `{ url }` without auth; Plan 019 §2 requires\n// the auth to be mandatory.\nconst RunnerConfigUser = RunnerConfigResolved\n\n// User-side api schema mirrors the resolved one (services + scalars).\n// Env / resolveAuth / hooks are stripped in `mergeConfig` before the\n// Zod parse runs, so they never appear here.\nconst ApiConfigUser = ApiConfigResolved.partial()\n// User schema is `.partial()` — but deep enough that the nested\n// toolResultOffload block also becomes partial. Otherwise passing\n// `toolResultOffload: { enabled: true }` would be rejected because\n// `thresholdBytes` / `maxPreviewChars` are required in the resolved\n// shape. The merge step fills defaults.\nconst ToolResultOffloadConfigUser = ToolResultOffloadConfigResolved.partial()\nconst CompactionConfigUser = z\n .object({\n strategy: CompactionStrategyEnum.optional(),\n threshold: z.number().min(0).max(1).optional(),\n keepLast: z.number().int().positive().optional(),\n summaryMaxTokens: z.number().int().positive().optional(),\n microcompact: z.boolean().optional(),\n microcompactAgeMs: z.number().int().nonnegative().optional(),\n toolResultOffload: ToolResultOffloadConfigUser.optional(),\n })\n .strict()\nconst CoordinatorConfigUser = CoordinatorConfigResolved.partial()\nconst OrchestratorConfigUser = OrchestratorConfigResolved.deepPartial()\n\nexport const UserConfigSchema = z\n .object({\n model: ModelConfigUser.optional(),\n storage: StorageConfigUser.optional(),\n memory: MemoryConfigUser.optional(),\n tools: ToolsConfigUser.optional(),\n agents: AgentsConfigUser.optional(),\n skills: SkillsConfigUser.optional(),\n execution: ExecutionConfigUser.optional(),\n transcript: TranscriptConfigUser.optional(),\n hooks: HooksConfigUser.optional(),\n logging: LoggingConfigUser.optional(),\n mcp: McpConfigUser.optional(),\n permissions: PermissionsConfigUser.optional(),\n compaction: CompactionConfigUser.optional(),\n coordinator: CoordinatorConfigUser.optional(),\n orchestrator: OrchestratorConfigUser.optional(),\n runner: RunnerConfigUser.optional(),\n api: ApiConfigUser.optional(),\n knowledge: KnowledgeConfigUser.optional(),\n })\n .strict()\n","/**\n * Engine — the top-level handle returned by `initEngine()`.\n *\n * Phase 7 wires `run()` end-to-end:\n * 1. Build the storage adapter pair (global + workspace) from config.\n * 2. Build the tool registry from the engine's core tools, filtered by\n * `config.tools.enabled`.\n * 3. Build the API client (Anthropic or proxy) from the model config.\n * 4. Build a transcript writer rooted at\n * `projects/{runId}/nodes/{nodeId}/`.\n * 5. Build the tool executor with timeout from config.\n * 6. Build a `RunContext`, seed it with the task as the first user\n * message, and drive the `agentLoop` to completion.\n * 7. Map the loop's `AgentLoopResult` into the public `RunResult`.\n *\n * `resume()` is still a Phase 10 stub.\n *\n * The optional second constructor parameter (`internals`) lets tests\n * inject a custom `fetch` implementation. The public `initEngine()`\n * factory does not expose this — it's strictly for unit/integration\n * tests that need to swap in a mock API client.\n */\n\nimport type { ResolvedConfig } from '../config/types.js'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport { createModelAdapter } from '../model/factory.js'\nimport { canSpawnProcesses } from '../runtime/detect.js'\nimport { withCapabilityCheck } from '../tools/capabilityStub.js'\nimport { SubagentRegistry } from '../subagent/registry.js'\nimport { createAgentTool } from '../tools/agent.js'\nimport { createBashTool } from '../tools/bash.js'\nimport { createSendMessageTool } from '../tools/sendMessage.js'\nimport type { Tool } from '../tools/contract.js'\nimport { ToolRegistry } from '../tools/contract.js'\nimport { createFileEditTool } from '../tools/fileEdit.js'\nimport { createFileReadTool } from '../tools/fileRead.js'\nimport { createFileWriteTool } from '../tools/fileWrite.js'\nimport { createGlobTool } from '../tools/glob.js'\nimport { createGrepTool } from '../tools/grep.js'\nimport { createWebFetchTool } from '../tools/webFetch.js'\nimport { FileTracker } from '../tools/fileTracker.js'\nimport { createWebSearchTool } from '../tools/webSearch.js'\nimport { createSleepTool } from '../tools/sleep.js'\nimport { createToolSearchTool } from '../tools/toolSearch.js'\nimport { createMemorizeTool } from '../tools/memorize.js'\nimport { createRecallTool } from '../tools/recall.js'\nimport { createNotebookEditTool } from '../tools/notebookEdit.js'\nimport { TaskStore } from '../tools/tasks/store.js'\nimport {\n createTaskCreateTool,\n createTaskGetTool,\n createTaskListTool,\n createTaskUpdateTool,\n} from '../tools/tasks/tools.js'\nimport { createLogger, type Logger } from '../logging/logger.js'\nimport { loadAgents } from '../agents/loader.js'\nimport {\n isCoordinatorMode,\n buildWorkerAgent,\n getCoordinatorBasePrompt,\n} from '../coordinator/mode.js'\nimport type { AgentDefinition } from '../tools/agent.js'\nimport { McpManager } from '../mcp/manager.js'\nimport { defaultSamplingHandler } from '../mcp/sampling.js'\nimport { buildPermissionPolicy, type PermissionPolicy } from '../permissions/evaluator.js'\nimport { createSmartMemory } from '../memory/memoryConfig.js'\nimport { buildSystemPrompt } from '../prompts/systemPrompt.js'\nimport { buildSchemaPrompt, tryParseJSON, validateOutput } from './jsonOutput.js'\nimport { createSkillPageTool } from '../skills/skillPage.js'\nimport { createApiCallTool } from '../tools/apiCall.js'\nimport { createFetchDataTool } from '../tools/fetchData.js'\nimport { createSearchKnowledgeTool } from '../tools/searchKnowledge.js'\nimport { createReadKnowledgeTool } from '../tools/readKnowledge.js'\nimport type { ResolvedApiConfig } from '../config/types.js'\nimport type { KnowledgeExternalLinkV1 } from '../knowledge/types.js'\nimport { StorageSkillSource } from '../skills/storageSkillSource.js'\nimport { InlineSkillSource } from '../skills/inlineSkillSource.js'\nimport type { SkillSource } from '../skills/source.js'\nimport { createEngineStorage } from '../storage/factory.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { TranscriptReader } from '../transcript/reader.js'\nimport { TranscriptWriter, loadWriterState } from '../transcript/writer.js'\nimport { dispatchHooks } from '../hooks/dispatch.js'\nimport type { PostRunEvent } from '../hooks/types.js'\nimport { agentLoop, type GateBeforeTool } from './agentLoop.js'\nimport { ConfigError } from './errors.js'\nimport { rebuildMessagesFromEntries } from './rehydrate.js'\nimport { RunContext } from './runContext.js'\nimport { ToolExecutor } from './toolRuntime.js'\nimport type { ResumeOptions, RunOptions, RunResult, RunSnapshot } from './types.js'\nimport { toResponse, type EngineResponse } from './response.js'\nimport { randomUUID } from '../runtime/uuid.js'\nimport {\n RunStateManager,\n type RunState,\n type RunStatus,\n type WebhookConfig,\n type WebhookEvent,\n} from './state.js'\nimport { NodeBackgroundExecutor, type BackgroundExecutor } from './executor.js'\nimport { WebhookDispatcher, RETRY_DELAYS_MS, MAX_ATTEMPTS } from './webhook.js'\n\n/** Config for webhook delivery when using async APIs. */\nexport interface WebhookOptions {\n readonly url: string\n readonly secret?: string\n readonly events?: readonly WebhookEvent[]\n readonly headers?: Record<string, string>\n}\n\n/** Options for engine.start() — extends RunOptions with webhook. */\nexport interface StartOptions extends RunOptions {\n readonly webhook?: WebhookOptions\n}\n\n/** Options for engine.resumeAsync() — extends ResumeOptions with webhook. */\nexport interface ResumeAsyncOptions extends ResumeOptions {\n readonly webhook?: WebhookOptions\n}\n\n/** Options for engine.waitFor() — blocks until terminal state. */\nexport interface WaitForOptions {\n readonly nodeId?: string\n readonly timeoutMs?: number\n readonly pollIntervalMs?: number\n}\n\nexport interface EngineInternals {\n /** Override the fetch implementation used by the API client. Tests only. */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Optional pre-tool gate. When set, every tool dispatch is checked\n * by this callback. Returning `{ allow: false }` pauses the run.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /**\n * Background executor for async runs (engine.start, engine.resumeAsync).\n * Defaults to NodeBackgroundExecutor. On Cloudflare Workers, provide a\n * DurableObjectExecutor that dispatches to a DO.\n */\n readonly backgroundExecutor?: BackgroundExecutor\n /**\n * Override the storage factory. When set, the engine calls this\n * instead of `createEngineStorage(config.storage)` for every run.\n *\n * Use this on Cloudflare Workers to build an `EngineStorage` pair\n * backed by `R2BindingStorageAdapter` (which uses the native R2\n * binding, not the S3 SDK). Example:\n *\n * new Engine(config, {\n * buildStorage: async () => ({\n * global: new R2BindingStorageAdapter(env.BUCKET, 'root/.claude'),\n * workspace: new R2BindingStorageAdapter(env.BUCKET, `root/workspaces/${ws}/.claude`),\n * }),\n * })\n */\n readonly buildStorage?: () => Promise<import('../storage/interface.js').EngineStorage>\n /**\n * Handler invoked when an MCP server with `allowSampling: true`\n * requests an LLM completion via `sampling/createMessage`. Defaults\n * to a handler that routes through the engine's own ModelAdapter\n * (same API key, same billing). Override to route to a cheaper\n * model, enforce budget limits, or refuse specific servers.\n */\n readonly samplingHandler?: import('../mcp/sampling.js').SamplingHandler\n}\n\nexport class Engine {\n readonly config: ResolvedConfig\n private readonly internals: EngineInternals\n private readonly mcpManager: McpManager\n private readonly permissionPolicy: PermissionPolicy\n private readonly backgroundExecutor: BackgroundExecutor\n private readonly webhookDispatcher: WebhookDispatcher\n\n constructor(config: ResolvedConfig, internals: EngineInternals = {}) {\n this.config = config\n this.internals = internals\n this.backgroundExecutor = internals.backgroundExecutor ?? new NodeBackgroundExecutor()\n this.webhookDispatcher = new WebhookDispatcher(\n internals.fetch ?? globalThis.fetch.bind(globalThis),\n )\n // Build the sampling handler: user override, else engine default\n // that routes to our own ModelAdapter. Only invoked when a server\n // has allowSampling: true.\n const samplingHandler =\n internals.samplingHandler ??\n defaultSamplingHandler(\n createModelAdapter(config.model, {\n ...(internals.fetch !== undefined ? { fetch: internals.fetch } : {}),\n }),\n )\n this.mcpManager = new McpManager(config.mcp, createLogger(config.logging), { samplingHandler })\n this.permissionPolicy = buildPermissionPolicy(config.permissions)\n }\n\n /**\n * Run a task synchronously to completion. The `_internal` parameter is\n * reserved for the engine's own async wrappers (`start`, `resumeAsync`)\n * to request runner handoff (Plan 019) — external callers must leave\n * it unset. Sync callers never hand off; if they hit a Node-only tool\n * on a restricted runtime, the capability stub returns an error and\n * the model adapts.\n */\n async run(\n options: RunOptions,\n _internal?: { handoffToRunner?: boolean },\n ): Promise<EngineResponse> {\n const startTime = Date.now()\n const runId = options.runId ?? `run_${randomUUID()}`\n const log = createLogger(this.config.logging)\n log.info('engine.run start', {\n runId,\n nodeId: options.nodeId,\n model: this.config.model.modelId,\n provider: this.config.model.provider,\n })\n const storage = await this.buildStorage()\n const client = this.buildClient()\n const logPath = `projects/${runId}/nodes/${options.nodeId}`\n const subagentRegistry = new SubagentRegistry({\n maxDepth: this.config.execution.maxSubagentDepth,\n })\n const memory = createSmartMemory({ storage, config: this.config.memory })\n const agents = await this.resolveAgents(storage)\n const mcpTools = await this.mcpManager.getTools()\n\n // Build the system prompt AFTER collecting MCP tools so the prompt\n // can list them, and AFTER resolving agents for the same reason.\n // We build a temporary registry first to get the full tool name set,\n // then pass it to the prompt builder, then build the real registry\n // with the final system prompt.\n const toolNameSet = this.collectToolNames(mcpTools)\n // In coordinator mode, the base prompt is swapped to the coordinator\n // version. The normal static sections (doingTasks, actions, usingTools)\n // are skipped — the coordinator prompt covers its own behavioral rules.\n const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : undefined\n // Resolve the skill source for this run. Per-run `options.skills`\n // override wins over the disk-backed autoload path. See Plan 017.\n const skillSource = this.resolveSkillSource(options.skills, storage)\n const skillList = skillSource !== undefined ? await skillSource.list() : undefined\n const apiConfig = this.resolveApiConfig(options.api)\n const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload)\n const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage)\n\n let systemPrompt = await buildSystemPrompt({\n ...(coordinatorBase !== undefined ? { base: coordinatorBase } : {}),\n memory,\n storage,\n // When an override was supplied, skip the legacy disk-scan path.\n skillsAutoload: options.skills !== undefined ? false : this.config.skills.autoload,\n ...(this.config.skills.path !== undefined ? { skillsDir: this.config.skills.path } : {}),\n ...(skillList !== undefined ? { skillList } : {}),\n modelId: this.config.model.modelId,\n provider: this.config.model.provider,\n registeredToolNames: toolNameSet,\n mcpTools,\n coordinatorMode: isCoordinatorMode(this.config),\n })\n\n // Structured output: inject schema instructions into system prompt\n if (options.outputFormat === 'json') {\n systemPrompt += '\\n\\n' + buildSchemaPrompt(options.outputSchema)\n }\n\n // Resolve gate early so it can be propagated into subagents when\n // config.hooks.propagateGateToSubagents === true.\n const gate = this.resolveGate()\n\n const registry = buildToolRegistry({\n config: this.config,\n storage,\n client,\n parentLogPath: logPath,\n parentAgentId: null,\n subagentRegistry,\n system: systemPrompt,\n agents,\n mcpTools,\n memory,\n ...(this.config.hooks.propagateGateToSubagents === true && gate !== undefined\n ? { subagentGate: gate }\n : {}),\n ...(skillSource !== undefined ? { skillSource } : {}),\n ...(apiConfig !== undefined ? { apiConfig } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n ...(knowledgeRuntime !== undefined ? { knowledge: knowledgeRuntime } : {}),\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n const writer = new TranscriptWriter({\n storage: storage.workspace,\n logPath,\n flushPolicy: this.config.transcript.flushPolicy,\n idleFlushMs: this.config.transcript.idleFlushMs,\n })\n const executor = new ToolExecutor({\n registry,\n timeoutMs: this.config.execution.turnTimeoutMs,\n permissions: this.permissionPolicy,\n hooks: {\n preToolCall: (event) => dispatchHooks(this.config.hooks.preToolCall, event),\n postToolCall: (event) => dispatchHooks(this.config.hooks.postToolCall, event),\n },\n })\n if (memory.episodes.enabled) {\n await memory.episodes.startSession()\n }\n const ctx = new RunContext({\n runId,\n nodeId: options.nodeId,\n writer,\n maxTurns: options.maxTurns ?? this.config.execution.maxTurns,\n episodes: memory.episodes,\n })\n\n const runTimeout = this.startRunTimeout()\n\n try {\n await writer.setStatus('running')\n await dispatchHooks(this.config.hooks.preRun, {\n runId,\n nodeId: options.nodeId,\n task: options.task,\n })\n await ctx.addUserMessage(options.task)\n\n const loopResult = await agentLoop({\n context: ctx,\n client,\n executor,\n tools: registry.list(),\n system: systemPrompt,\n contextLimit: this.config.execution.contextLimit,\n compactionConfig: this.config.compaction,\n storage: storage.workspace,\n registry,\n maxToolConcurrency: this.config.execution.maxToolConcurrency,\n subagentRegistry,\n preTurnHooks: this.config.hooks.preTurn,\n postTurnHooks: this.config.hooks.postTurn,\n stopHooks: this.config.hooks.stopHooks,\n onProgress: this.buildHeartbeat(storage, runId, options.nodeId),\n ...(options.tokenBudget !== undefined ? { tokenBudget: options.tokenBudget } : {}),\n ...(runTimeout.signal !== undefined\n ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs }\n : {}),\n ...(gate !== undefined ? { gateBeforeTool: gate } : {}),\n ...(_internal?.handoffToRunner === true ? { handoffToRunner: true } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n })\n\n const result = await this.finalizeResult(loopResult, writer, logPath, {\n ...(options.outputFormat !== undefined ? { outputFormat: options.outputFormat } : {}),\n ...(options.outputSchema !== undefined ? { outputSchema: options.outputSchema } : {}),\n })\n this.logRunEnd(log, runId, options.nodeId, result)\n await this.firePostRunHook(runId, options.nodeId, result, ctx, logPath)\n const capabilitiesMissing = ctx.getCapabilitiesMissing()\n return toResponse(result, {\n runId,\n nodeId: options.nodeId,\n durationMs: Date.now() - startTime,\n logPath,\n ...(capabilitiesMissing.length > 0 ? { capabilitiesMissing } : {}),\n })\n } finally {\n runTimeout.clear()\n await writer.close()\n }\n }\n\n async resume(\n options: ResumeOptions,\n _internal?: { handoffToRunner?: boolean },\n ): Promise<EngineResponse> {\n const startTime = Date.now()\n const log = createLogger(this.config.logging)\n\n // Load snapshot — either from options (internal) or from storage (client)\n const storage = await this.buildStorage()\n let snapshot: RunSnapshot\n if (options.snapshot) {\n snapshot = options.snapshot\n } else {\n // Client path: load snapshot from storage using runId (+ optional nodeId)\n snapshot = await this.loadSnapshot(storage, options.runId, options.nodeId)\n }\n\n log.info('engine.resume start', {\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n pauseReason: snapshot.pauseReason,\n messageCount: snapshot.messageCount,\n })\n if (snapshot.version !== 1) {\n throw new ConfigError(\n `Engine.resume: unsupported snapshot version ${String(snapshot.version)}`,\n )\n }\n\n const client = this.buildClient()\n const logPath = `projects/${snapshot.runId}/nodes/${snapshot.nodeId}`\n const subagentRegistry = new SubagentRegistry({\n maxDepth: this.config.execution.maxSubagentDepth,\n })\n const memory = createSmartMemory({ storage, config: this.config.memory })\n const agents = await this.resolveAgents(storage)\n const mcpTools = await this.mcpManager.getTools()\n\n const toolNameSet = this.collectToolNames(mcpTools)\n // In coordinator mode, the base prompt is swapped to the coordinator\n // version. The normal static sections (doingTasks, actions, usingTools)\n // are skipped — the coordinator prompt covers its own behavioral rules.\n const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : undefined\n // Resolve the skill source for this run. Per-run `options.skills`\n // override wins over the disk-backed autoload path. See Plan 017.\n const skillSource = this.resolveSkillSource(options.skills, storage)\n const skillList = skillSource !== undefined ? await skillSource.list() : undefined\n const apiConfig = this.resolveApiConfig(options.api)\n const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload)\n const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage)\n\n let systemPrompt = await buildSystemPrompt({\n ...(coordinatorBase !== undefined ? { base: coordinatorBase } : {}),\n memory,\n storage,\n // When an override was supplied, skip the legacy disk-scan path.\n skillsAutoload: options.skills !== undefined ? false : this.config.skills.autoload,\n ...(this.config.skills.path !== undefined ? { skillsDir: this.config.skills.path } : {}),\n ...(skillList !== undefined ? { skillList } : {}),\n modelId: this.config.model.modelId,\n provider: this.config.model.provider,\n registeredToolNames: toolNameSet,\n mcpTools,\n coordinatorMode: isCoordinatorMode(this.config),\n })\n\n // Structured output: inject schema instructions into system prompt\n if (options.outputFormat === 'json') {\n systemPrompt += '\\n\\n' + buildSchemaPrompt(options.outputSchema)\n }\n\n // Resolve gate early so it can be propagated into subagents when\n // config.hooks.propagateGateToSubagents === true.\n const gate = this.resolveGate()\n\n const registry = buildToolRegistry({\n config: this.config,\n storage,\n client,\n parentLogPath: logPath,\n parentAgentId: null,\n subagentRegistry,\n system: systemPrompt,\n agents,\n mcpTools,\n memory,\n ...(this.config.hooks.propagateGateToSubagents === true && gate !== undefined\n ? { subagentGate: gate }\n : {}),\n ...(skillSource !== undefined ? { skillSource } : {}),\n ...(apiConfig !== undefined ? { apiConfig } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n ...(knowledgeRuntime !== undefined ? { knowledge: knowledgeRuntime } : {}),\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n // Resume must continue appending to the existing transcript without\n // overwriting any shards. Load the prior writer state from meta.json\n // so the new writer's counter starts at lastShardIndex + 1.\n const priorState = await loadWriterState(storage.workspace, logPath)\n const writer = new TranscriptWriter({\n storage: storage.workspace,\n logPath,\n flushPolicy: this.config.transcript.flushPolicy,\n idleFlushMs: this.config.transcript.idleFlushMs,\n ...(priorState !== null\n ? {\n initialShardIndex: priorState.nextShardIndex,\n initialMeta: priorState.meta,\n }\n : {}),\n })\n const executor = new ToolExecutor({\n registry,\n timeoutMs: this.config.execution.turnTimeoutMs,\n permissions: this.permissionPolicy,\n hooks: {\n preToolCall: (event) => dispatchHooks(this.config.hooks.preToolCall, event),\n postToolCall: (event) => dispatchHooks(this.config.hooks.postToolCall, event),\n },\n })\n if (memory.episodes.enabled) {\n // Continue the same session id if any prior session existed.\n // For v0.1 we just start a new session on resume — episodes\n // are append-only and the new session id distinguishes them.\n await memory.episodes.startSession()\n }\n const ctx = new RunContext({\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n writer,\n maxTurns: this.config.execution.maxTurns,\n episodes: memory.episodes,\n })\n\n const runTimeout = this.startRunTimeout()\n\n try {\n // Replay the transcript shards back into the context's message\n // history. The reader walks the existing JSONL files; we\n // reconstruct the in-memory MessageParam[] without re-writing\n // any transcript entries.\n const reader = new TranscriptReader(storage.workspace, logPath)\n const entries = await reader.readAll()\n const messages = rebuildMessagesFromEntries(entries)\n ctx.rehydrate({\n messages,\n turnCount: snapshot.turnsUsed,\n tokensUsed: {\n input: snapshot.tokensUsedSoFar.input,\n output: snapshot.tokensUsedSoFar.output,\n ...(snapshot.tokensUsedSoFar.cacheCreationInput !== undefined\n ? { cacheCreationInput: snapshot.tokensUsedSoFar.cacheCreationInput }\n : {}),\n ...(snapshot.tokensUsedSoFar.cacheReadInput !== undefined\n ? { cacheReadInput: snapshot.tokensUsedSoFar.cacheReadInput }\n : {}),\n },\n lastUuid: snapshot.lastMessageUuid,\n })\n\n // If the snapshot captured a pending tool call, we need to inject\n // a tool_result so the API sees a complete tool_use ↔ tool_result\n // pair (otherwise the Messages API rejects the conversation).\n if (snapshot.pendingToolCall) {\n const pending = snapshot.pendingToolCall\n if (options.gateAnswer !== undefined) {\n // Caller provided an explicit answer — inject it as the result.\n const answer =\n typeof options.gateAnswer === 'string'\n ? options.gateAnswer\n : JSON.stringify(options.gateAnswer)\n await ctx.addToolResult(pending.toolUseId, answer, false)\n } else {\n // No answer — inject a synthetic tool_result + a retry\n // directive AS A SINGLE user message. Two separate user\n // messages (tool_result then text) trip the AI SDK's\n // MissingToolResultsError on openai-compatible providers;\n // combining them keeps the tool_use↔tool_result pairing\n // intact under all providers.\n //\n // The retry text is load-bearing: models treat tool_result\n // as passive feedback and often decide the work is \"done\"\n // without re-executing. An explicit instruction with the\n // original arguments makes retry reliable.\n const inputJson = JSON.stringify(pending.input ?? {}, null, 2)\n await ctx.addMixedUserMessage([\n {\n type: 'tool_result',\n tool_use_id: pending.toolUseId,\n content: `APPROVAL_GATE_RELEASED: the prior ${pending.toolName} call was paused for human approval and has now been approved. Retry is required.`,\n },\n {\n type: 'text',\n text:\n `The human has approved the paused ${pending.toolName} tool call. ` +\n `You MUST now re-issue the EXACT same tool call to complete the work — ` +\n `do not change the arguments, do not answer in text, do not declare the task done. ` +\n `Approved arguments (copy verbatim):\\n\\`\\`\\`json\\n${inputJson}\\n\\`\\`\\``,\n },\n ])\n }\n }\n\n await writer.setStatus('running')\n\n const loopResult = await agentLoop({\n context: ctx,\n client,\n executor,\n tools: registry.list(),\n system: systemPrompt,\n contextLimit: this.config.execution.contextLimit,\n compactionConfig: this.config.compaction,\n storage: storage.workspace,\n registry,\n maxToolConcurrency: this.config.execution.maxToolConcurrency,\n subagentRegistry,\n preTurnHooks: this.config.hooks.preTurn,\n postTurnHooks: this.config.hooks.postTurn,\n stopHooks: this.config.hooks.stopHooks,\n onProgress: this.buildHeartbeat(storage, snapshot.runId, snapshot.nodeId),\n ...(runTimeout.signal !== undefined\n ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs }\n : {}),\n ...(gate !== undefined ? { gateBeforeTool: gate } : {}),\n ...(_internal?.handoffToRunner === true ? { handoffToRunner: true } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n })\n\n const result = await this.finalizeResult(loopResult, writer, logPath, {\n ...(options.outputFormat !== undefined ? { outputFormat: options.outputFormat } : {}),\n ...(options.outputSchema !== undefined ? { outputSchema: options.outputSchema } : {}),\n })\n this.logRunEnd(log, snapshot.runId, snapshot.nodeId, result)\n await this.firePostRunHook(snapshot.runId, snapshot.nodeId, result, ctx, logPath)\n const capabilitiesMissing = ctx.getCapabilitiesMissing()\n return toResponse(result, {\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n durationMs: Date.now() - startTime,\n logPath,\n ...(capabilitiesMissing.length > 0 ? { capabilitiesMissing } : {}),\n })\n } finally {\n runTimeout.clear()\n await writer.close()\n }\n }\n\n /**\n * Load a paused snapshot from storage using runId (and optional nodeId).\n * If nodeId is not provided, finds the most recently paused node.\n */\n private async loadSnapshot(\n storage: EngineStorage,\n runId: string,\n nodeId?: string,\n ): Promise<RunSnapshot> {\n if (nodeId) {\n const snapPath = `projects/${runId}/nodes/${nodeId}/snapshot.json`\n const content = await storage.workspace.readFile(snapPath)\n if (!content) {\n throw new ConfigError(\n `engine.resume: no snapshot found at ${snapPath}. Check runId/nodeId.`,\n )\n }\n return JSON.parse(content) as RunSnapshot\n }\n\n // Scan all nodes under this runId for the most recently paused snapshot\n const nodesDir = `projects/${runId}/nodes`\n const nodeNames = await storage.workspace.listDir(nodesDir)\n if (nodeNames.length === 0) {\n throw new ConfigError(`engine.resume: no runs found for runId=${runId}`)\n }\n\n let newest: { snapshot: RunSnapshot; ts: number } | null = null\n for (const name of nodeNames) {\n const content = await storage.workspace.readFile(`${nodesDir}/${name}/snapshot.json`)\n if (!content) continue\n try {\n const snap = JSON.parse(content) as RunSnapshot\n const ts = Date.parse(snap.pausedAt)\n if (!newest || ts > newest.ts) newest = { snapshot: snap, ts }\n } catch {\n /* skip invalid */\n }\n }\n\n if (!newest) {\n throw new ConfigError(\n `engine.resume: no paused snapshots found for runId=${runId}. ` +\n `Pass nodeId to target a specific node.`,\n )\n }\n return newest.snapshot\n }\n\n // ================================================================\n // Async APIs — start / resumeAsync / getStatus / waitFor / cancelRun\n // ================================================================\n\n /**\n * Start a run asynchronously. Writes initial state, schedules the run\n * in the background, and returns immediately. Clients should track the\n * returned runId and poll via `getStatus(runId)` or wait for a webhook.\n *\n * Workers compatibility: provide a DurableObjectExecutor via\n * EngineInternals.backgroundExecutor — the default NodeBackgroundExecutor\n * uses fire-and-forget Promises which won't survive Worker request exit.\n */\n async start(\n options: StartOptions,\n ): Promise<{ runId: string; nodeId: string; status: RunStatus }> {\n const runId = options.runId ?? `run_${randomUUID()}`\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n const webhook = options.webhook\n ? {\n url: options.webhook.url,\n events: options.webhook.events ?? ['paused', 'done', 'failed'],\n ...(options.webhook.secret !== undefined ? { secret: options.webhook.secret } : {}),\n ...(options.webhook.headers !== undefined ? { headers: options.webhook.headers } : {}),\n deliveries: [],\n }\n : undefined\n\n const initial = RunStateManager.initial(runId, options.nodeId, webhook)\n await stateManager.write(initial)\n\n const handoffEnabled = this.config.runner !== undefined\n this.backgroundExecutor.schedule(runId, async (signal) => {\n await stateManager.update(runId, options.nodeId, { status: 'running' })\n try {\n const response = await this.run({ ...options, runId }, { handoffToRunner: handoffEnabled })\n if (signal.aborted) return\n // Plan 019 — when the run paused for runner handoff, fire the\n // POST before finalizing so any runner-dispatch failure flips\n // the response to failed with ERR_RUNNER_UNREACHABLE.\n const postHandoff = await this.maybeHandoffToRunner(runId, options.nodeId, response)\n await stateManager.finalize(runId, options.nodeId, postHandoff)\n await this.maybeFireWebhook(stateManager, runId, options.nodeId, postHandoff)\n } catch (err) {\n if (signal.aborted) return\n const errorMsg = err instanceof Error ? err.message : String(err)\n const failResponse: EngineResponse = {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: options.nodeId },\n errors: [{ code: 'RUN_FAILED', message: errorMsg }],\n timestamp: Date.now(),\n }\n await stateManager.finalize(runId, options.nodeId, failResponse)\n await this.maybeFireWebhook(stateManager, runId, options.nodeId, failResponse)\n }\n })\n\n return { runId, nodeId: options.nodeId, status: 'queued' }\n }\n\n /**\n * Resume a paused run asynchronously. Equivalent to engine.resume() but\n * dispatched via the background executor. Returns immediately.\n */\n async resumeAsync(\n options: ResumeAsyncOptions,\n ): Promise<{ runId: string; nodeId: string; status: RunStatus }> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n // Must know nodeId to write state — load snapshot if not provided\n let nodeId = options.nodeId\n if (nodeId === undefined) {\n const snap = options.snapshot ?? (await this.loadSnapshot(storage, options.runId))\n nodeId = snap.nodeId\n }\n\n const existing = await stateManager.read(options.runId, nodeId)\n const webhook = options.webhook\n ? {\n url: options.webhook.url,\n events: options.webhook.events ?? ['paused', 'done', 'failed'],\n ...(options.webhook.secret !== undefined ? { secret: options.webhook.secret } : {}),\n ...(options.webhook.headers !== undefined ? { headers: options.webhook.headers } : {}),\n deliveries: [],\n }\n : existing?.webhook\n\n const next: RunState = existing\n ? {\n ...existing,\n status: 'running',\n lastHeartbeat: Date.now(),\n response: null, // clear stale paused response so getStatus returns provisional\n ...(webhook !== undefined ? { webhook } : {}),\n }\n : { ...RunStateManager.initial(options.runId, nodeId, webhook), status: 'running' }\n await stateManager.write(next)\n\n const resumeNodeId = nodeId\n const handoffEnabled = this.config.runner !== undefined\n this.backgroundExecutor.schedule(options.runId, async (signal) => {\n try {\n const response = await this.resume(options, { handoffToRunner: handoffEnabled })\n if (signal.aborted) return\n const postHandoff = await this.maybeHandoffToRunner(options.runId, resumeNodeId, response)\n await stateManager.finalize(options.runId, resumeNodeId, postHandoff)\n await this.maybeFireWebhook(stateManager, options.runId, resumeNodeId, postHandoff)\n } catch (err) {\n if (signal.aborted) return\n const errorMsg = err instanceof Error ? err.message : String(err)\n const failResponse: EngineResponse = {\n runId: options.runId,\n status: 'failed',\n data: null,\n meta: { nodeId: resumeNodeId },\n errors: [{ code: 'RESUME_FAILED', message: errorMsg }],\n timestamp: Date.now(),\n }\n await stateManager.finalize(options.runId, resumeNodeId, failResponse)\n await this.maybeFireWebhook(stateManager, options.runId, resumeNodeId, failResponse)\n }\n })\n\n return { runId: options.runId, nodeId, status: 'running' }\n }\n\n /**\n * Read the current status of a run. Returns the full EngineResponse once\n * terminal; returns a provisional response with status='running'|'queued'\n * otherwise. If nodeId is omitted, picks the most recently updated node.\n */\n async getStatus(runId: string, nodeId?: string): Promise<EngineResponse> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let state: RunState | null\n if (nodeId !== undefined) {\n state = await stateManager.read(runId, nodeId)\n } else {\n const all = await stateManager.scanRun(runId)\n state = all.reduce<RunState | null>(\n (best, cur) => (best === null || cur.lastHeartbeat > best.lastHeartbeat ? cur : best),\n null,\n )\n }\n\n if (state === null) {\n return {\n runId,\n status: 'not_found',\n data: null,\n meta: { nodeId: nodeId ?? 'unknown' },\n errors: [{ code: 'NOT_FOUND', message: `No state found for runId=${runId}` }],\n timestamp: Date.now(),\n }\n }\n\n if (state.response !== null) return state.response\n\n // Non-terminal — build a provisional response from the state.\n return {\n runId: state.runId,\n status: state.status,\n data: null,\n meta: {\n nodeId: state.nodeId,\n turns: state.progress.turns,\n tokensUsed: state.progress.tokensUsed,\n activity: state.progress.currentActivity,\n ...(state.progress.lastTool !== undefined ? { lastTool: state.progress.lastTool } : {}),\n },\n errors: [],\n timestamp: state.lastHeartbeat,\n }\n }\n\n /**\n * Poll until the run reaches a terminal state (done | failed | paused |\n * cancelled) or the timeout expires. Returns the final EngineResponse.\n */\n async waitFor(runId: string, opts: WaitForOptions = {}): Promise<EngineResponse> {\n const pollInterval = opts.pollIntervalMs ?? 1000\n const timeoutMs = opts.timeoutMs ?? 0 // 0 = no timeout\n const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : Infinity\n\n for (;;) {\n const resp = await this.getStatus(runId, opts.nodeId)\n if (resp.status === 'done' || resp.status === 'failed' || resp.status === 'paused') {\n return resp\n }\n if (Date.now() >= deadline) {\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: opts.nodeId ?? 'unknown' },\n errors: [\n { code: 'WAIT_TIMEOUT', message: `waitFor timed out after ${String(timeoutMs)}ms` },\n ],\n timestamp: Date.now(),\n }\n }\n await new Promise((r) => setTimeout(r, pollInterval))\n }\n }\n\n /**\n * Cancel an async run. Aborts the background executor and marks the\n * state as cancelled. Idempotent — safe to call on already-terminal runs.\n */\n async cancelRun(runId: string, nodeId?: string): Promise<void> {\n await this.backgroundExecutor.cancel(runId)\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let targetNodeId = nodeId\n if (targetNodeId === undefined) {\n const all = await stateManager.scanRun(runId)\n const active = all.find((s) => s.status === 'running' || s.status === 'queued')\n if (active === undefined) return\n targetNodeId = active.nodeId\n }\n\n const current = await stateManager.read(runId, targetNodeId)\n if (current === null) return\n if (\n current.status === 'done' ||\n current.status === 'failed' ||\n current.status === 'cancelled'\n ) {\n return\n }\n\n const cancelledResponse: EngineResponse = {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: targetNodeId, cancelled: true },\n errors: [{ code: 'CANCELLED', message: 'Run was cancelled by client' }],\n timestamp: Date.now(),\n }\n await stateManager.update(runId, targetNodeId, {\n status: 'cancelled',\n lastHeartbeat: Date.now(),\n response: cancelledResponse,\n })\n }\n\n /**\n * Retry a specific webhook delivery. Useful when the client acknowledges\n * they missed an event (e.g., after downtime).\n */\n async retryWebhook(runId: string, deliveryId: string, nodeId?: string): Promise<void> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let targetNodeId = nodeId\n if (targetNodeId === undefined) {\n const all = await stateManager.scanRun(runId)\n const withHook = all.find((s) => s.webhook !== undefined)\n if (withHook === undefined) throw new Error(`retryWebhook: no webhook config for ${runId}`)\n targetNodeId = withHook.nodeId\n }\n\n const state = await stateManager.read(runId, targetNodeId)\n if (state === null || state.webhook === undefined || state.response === null) {\n throw new Error(`retryWebhook: no deliverable state for ${runId}/${targetNodeId}`)\n }\n\n const original = state.webhook.deliveries.find((d) => d.id === deliveryId)\n if (original === undefined) {\n throw new Error(`retryWebhook: delivery ${deliveryId} not found`)\n }\n\n await this.dispatchWebhookWithRetries(\n stateManager,\n runId,\n targetNodeId,\n original.event,\n state.response,\n 1,\n )\n }\n\n /**\n * Scan all runs for stale heartbeats and mark them as failed. Clients\n * should call this on startup to recover from crashes.\n *\n * @param opts.staleThresholdMs - Heartbeat age after which a running run\n * is considered orphaned. Default: 5 minutes.\n */\n async recoverOrphanedRuns(\n opts: { staleThresholdMs?: number } = {},\n ): Promise<readonly RunState[]> {\n const threshold = opts.staleThresholdMs ?? 5 * 60_000\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n const orphaned = await stateManager.findOrphaned(threshold)\n for (const state of orphaned) {\n const failResponse: EngineResponse = {\n runId: state.runId,\n status: 'failed',\n data: null,\n meta: { nodeId: state.nodeId, orphaned: true },\n errors: [\n {\n code: 'ORPHANED',\n message: `Run has stale heartbeat (last: ${String(new Date(state.lastHeartbeat).toISOString())})`,\n },\n ],\n timestamp: Date.now(),\n }\n await stateManager.update(state.runId, state.nodeId, {\n status: 'failed',\n lastHeartbeat: Date.now(),\n response: failResponse,\n })\n }\n return orphaned\n }\n\n // ---------- runner handoff (Plan 019) ----------\n\n /**\n * When the response indicates the run paused for runner handoff, POST\n * `{ runId }` to the configured runner URL. On success, return the\n * response unchanged — state stays `paused` and the runner will flip\n * it to `done` (or `failed`) on its side. On POST failure, convert\n * the response to `failed` with `ERR_RUNNER_UNREACHABLE` so the\n * caller sees a terminal state instead of a silent hang.\n *\n * Called only from `start()` / `resumeAsync()`. Sync `run()` never\n * produces a `handoff_to_runner` pause (see `_internal.handoffToRunner`).\n */\n private async maybeHandoffToRunner(\n runId: string,\n nodeId: string,\n response: EngineResponse,\n ): Promise<EngineResponse> {\n if (response.status !== 'paused') return response\n if (response.meta.pauseReason !== 'handoff_to_runner') return response\n const runner = this.config.runner\n if (runner === undefined) {\n // handoffToRunner was false — the loop shouldn't have produced\n // this pause reason. Guard against it just in case.\n return response\n }\n const fetchFn = this.internals.fetch ?? globalThis.fetch.bind(globalThis)\n try {\n const res = await fetchFn(runner.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${runner.secret}`,\n },\n body: JSON.stringify({ runId }),\n })\n if (!res.ok) {\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId },\n errors: [\n {\n code: 'ERR_RUNNER_UNREACHABLE',\n message: `Runner returned HTTP ${res.status}`,\n },\n ],\n timestamp: Date.now(),\n }\n }\n return response\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId },\n errors: [\n {\n code: 'ERR_RUNNER_UNREACHABLE',\n message: `Runner handoff failed: ${msg}`,\n },\n ],\n timestamp: Date.now(),\n }\n }\n }\n\n // ---------- webhook helpers ----------\n\n private async maybeFireWebhook(\n stateManager: RunStateManager,\n runId: string,\n nodeId: string,\n response: EngineResponse,\n ): Promise<void> {\n const state = await stateManager.read(runId, nodeId)\n if (state === null || state.webhook === undefined) return\n const event: WebhookEvent =\n response.status === 'done' ? 'done' : response.status === 'paused' ? 'paused' : 'failed'\n if (!state.webhook.events.includes(event)) return\n await this.dispatchWebhookWithRetries(stateManager, runId, nodeId, event, response, 1)\n }\n\n private async dispatchWebhookWithRetries(\n stateManager: RunStateManager,\n runId: string,\n nodeId: string,\n event: WebhookEvent,\n payload: EngineResponse,\n startAttempt: number,\n ): Promise<void> {\n const state = await stateManager.read(runId, nodeId)\n if (state === null || state.webhook === undefined) return\n const hook = state.webhook\n\n let attempt = startAttempt\n while (attempt <= MAX_ATTEMPTS) {\n const delay = RETRY_DELAYS_MS[attempt - 1] ?? 0\n if (delay > 0) {\n await new Promise((r) => setTimeout(r, delay))\n }\n\n const result = await this.webhookDispatcher.deliver({\n url: hook.url,\n event,\n payload,\n ...(hook.secret !== undefined ? { secret: hook.secret } : {}),\n ...(hook.headers !== undefined ? { headers: hook.headers } : {}),\n attempt,\n })\n\n // Append delivery record to state\n const latest = await stateManager.read(runId, nodeId)\n if (latest !== null && latest.webhook !== undefined) {\n const updated: WebhookConfig = {\n ...latest.webhook,\n deliveries: [...latest.webhook.deliveries, result.delivery],\n }\n await stateManager.update(runId, nodeId, { webhook: updated })\n }\n\n if (!result.shouldRetry) return\n attempt += 1\n }\n }\n\n /**\n * Shut down engine-owned background resources — currently just the\n * `McpManager`'s connection pool. Long-running hosts (servers,\n * daemons) SHOULD call this before dropping their engine reference,\n * otherwise MCP subprocesses leak until the parent process exits.\n *\n * Idempotent. Safe to call multiple times.\n */\n async shutdown(): Promise<void> {\n await this.mcpManager.shutdownAll()\n createLogger(this.config.logging).info('engine.shutdown complete', {\n mcpConnectedCount: this.mcpManager.connectedCount,\n })\n }\n\n /**\n * Structured orchestration — decomposes a task into a plan, executes\n * each step with specialized agents (planner, researcher, implementer,\n * verifier, reviewer, finalizer), enforces retry policies, and reverts\n * failed implementations.\n *\n * Unlike `run()` (single agent, best effort), `orchestrate()` guarantees\n * a result: done (all steps passed), partial (some failed + reverted),\n * or failed (planning failed entirely).\n *\n * Requires `config.orchestrator.enabled = true` or the method throws.\n * The orchestrator calls `engine.run()` internally for each phase —\n * it's a state machine layer above the existing agent loop.\n *\n * Pure JS — works on both Node.js and Cloudflare Workers.\n */\n async orchestrate(\n options: import('../orchestrator/types.js').OrchestrateOptions,\n ): Promise<import('../orchestrator/types.js').OrchestratorResult> {\n if (!this.config.orchestrator.enabled) {\n throw new ConfigError('engine.orchestrate() requires config.orchestrator.enabled = true')\n }\n const { orchestrate: doOrchestrate } = await import('../orchestrator/orchestrate.js')\n const storage = await this.buildStorage()\n const log = createLogger(this.config.logging)\n return doOrchestrate(this, options, this.config.orchestrator, storage.workspace, log)\n }\n\n /**\n * Emit a terminal log line per run. `done` is info; `paused` is info;\n * `failed` is error (with the error message in `meta.error`).\n */\n private logRunEnd(log: Logger, runId: string, nodeId: string, result: RunResult): void {\n if (result.status === 'done') {\n log.info('engine.run done', {\n runId,\n nodeId,\n turns: result.turns,\n tokensUsed: result.tokensUsed,\n })\n return\n }\n if (result.status === 'paused') {\n log.info('engine.run paused', { runId, nodeId, reason: result.reason })\n return\n }\n log.error('engine.run failed', {\n runId,\n nodeId,\n error: result.error.message,\n errorName: result.error.name,\n })\n }\n\n /**\n * Collect the names of all tools that will be registered — used to\n * populate the system prompt's tool-specific instructions BEFORE\n * building the registry itself (the prompt goes into the registry's\n * Agent tool as the child system prompt, so the prompt must exist\n * first).\n */\n private collectToolNames(mcpTools: ReadonlyArray<Tool>): Set<string> {\n const names = new Set<string>()\n const builtins = [\n // Bash is conditional on canSpawnProcesses() — but for prompt\n // generation we include it anyway; the prompt should mention\n // Bash even if it won't be registered (the model will get an\n // \"unknown tool\" error if it tries, which is informative).\n 'Bash',\n 'Read',\n 'Write',\n 'Edit',\n 'Glob',\n 'Grep',\n 'WebFetch',\n 'WebSearch',\n 'Agent',\n 'SkillPage',\n 'Sleep',\n 'NotebookEdit',\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n 'Memorize',\n 'Recall',\n 'ToolSearch',\n ]\n const enabled = new Set(this.config.tools.enabled)\n const disabled = new Set(this.config.tools.disabled)\n const wantAll = enabled.has('*')\n for (const name of builtins) {\n if (disabled.has(name)) continue\n if (wantAll || enabled.has(name)) names.add(name)\n }\n // ApiCall is conditional (Plan 020) — only present when config.api\n // has services. Per-run override via RunOptions.api can add it too\n // but that's handled at registry build time; for prompt generation\n // we include it when the engine-level config advertises services.\n if ((this.config.api?.services.length ?? 0) > 0) {\n if (!disabled.has('ApiCall') && (wantAll || enabled.has('ApiCall'))) {\n names.add('ApiCall')\n }\n }\n // FetchData is conditional (Plan 021) — only present when offload\n // is enabled at engine level. Per-run override adds at registry\n // build time; prompt listing covers the engine-level case.\n if (this.config.compaction.toolResultOffload?.enabled === true) {\n if (!disabled.has('FetchData') && (wantAll || enabled.has('FetchData'))) {\n names.add('FetchData')\n }\n }\n // SearchKnowledge / ReadKnowledge are conditional (Plan 023) —\n // only present when knowledge is enabled at engine level. The\n // actual tool registration also depends on per-run folders /\n // external links, but for prompt listing the engine-level flag\n // is the right granularity.\n if (this.config.knowledge?.enabled === true) {\n if (!disabled.has('SearchKnowledge') && (wantAll || enabled.has('SearchKnowledge'))) {\n names.add('SearchKnowledge')\n }\n if (!disabled.has('ReadKnowledge') && (wantAll || enabled.has('ReadKnowledge'))) {\n names.add('ReadKnowledge')\n }\n }\n for (const tool of this.config.tools.custom as ReadonlyArray<Tool>) {\n names.add(tool.name)\n }\n for (const tool of mcpTools) {\n if (disabled.has(tool.name)) continue\n if (wantAll || enabled.has(tool.name)) names.add(tool.name)\n }\n return names\n }\n\n /**\n * Resolve the subagent catalogue the Agent tool will dispatch against.\n *\n * Merge semantics:\n * 1. Start with `config.agents.builtins` — each name becomes a\n * placeholder definition that inherits the parent's system prompt.\n * (The only builtin v0.1 knows about is `'general-purpose'`.)\n * 2. If `config.agents.customPath` is set, load any `.md` files from\n * that directory (relative to the workspace adapter) and append as\n * full `AgentDefinition` records with their own system prompts.\n * 3. Custom-loaded agents with the same name as a builtin REPLACE the\n * builtin — last-wins dedup happens inside `createAgentTool`.\n *\n * Throws `ConfigError` if the merged list is empty.\n */\n private async resolveAgents(storage: EngineStorage): Promise<AgentDefinition[]> {\n const agents: AgentDefinition[] = []\n for (const name of this.config.agents.builtins) {\n agents.push({\n name,\n description:\n name === 'general-purpose'\n ? 'Default general-purpose subagent. Inherits the parent system prompt.'\n : `Builtin subagent: ${name}`,\n })\n }\n if (this.config.agents.customPath !== undefined) {\n const loaded = await loadAgents(storage.workspace, this.config.agents.customPath)\n agents.push(...loaded)\n }\n // In coordinator mode, auto-register a 'worker' agent with\n // restricted tools and a focused system prompt.\n if (isCoordinatorMode(this.config)) {\n agents.push(buildWorkerAgent(this.config.coordinator))\n }\n if (agents.length === 0) {\n throw new ConfigError(\n 'config.agents: at least one builtin or custom agent is required (got empty builtins and no customPath)',\n )\n }\n return agents\n }\n\n /**\n * Pick the effective gate callback:\n * 1. `EngineInternals.gateBeforeTool` (test seam) — highest priority\n * 2. `config.hooks.gateBeforeTool` (user config) — the public path\n * 3. `undefined` (no gate) — default\n */\n private resolveGate(): GateBeforeTool | undefined {\n if (this.internals.gateBeforeTool !== undefined) return this.internals.gateBeforeTool\n if (this.config.hooks.gateBeforeTool !== undefined) {\n // The schema types `gateBeforeTool` as `Function`; we know the\n // shape matches GateBeforeTool at runtime.\n return this.config.hooks.gateBeforeTool as unknown as GateBeforeTool\n }\n return undefined\n }\n\n /**\n * Start the run-level timeout. Returns an AbortController signal if\n * `runTimeoutMs > 0`, otherwise returns an empty handle. The caller\n * MUST invoke `clear()` in a finally block to cancel the timer.\n */\n private startRunTimeout(): { signal: AbortSignal | undefined; clear: () => void } {\n const ms = this.config.execution.runTimeoutMs\n if (ms <= 0) return { signal: undefined, clear: () => {} }\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n // `unref()` lets node exit if this timer is the only thing pending.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof (timer as any).unref === 'function') (timer as any).unref()\n return {\n signal: controller.signal,\n clear: () => clearTimeout(timer),\n }\n }\n\n private async firePostRunHook(\n runId: string,\n nodeId: string,\n result: RunResult,\n ctx: RunContext,\n logPath?: string,\n ): Promise<void> {\n const usage = ctx.getTokensUsed()\n const event: PostRunEvent = {\n runId,\n nodeId,\n status: result.status,\n tokensUsed: {\n input: usage.input,\n output: usage.output,\n ...(usage.cacheCreationInput !== undefined\n ? { cacheCreationInput: usage.cacheCreationInput }\n : {}),\n ...(usage.cacheReadInput !== undefined ? { cacheReadInput: usage.cacheReadInput } : {}),\n },\n turnsUsed: ctx.getTurnCount(),\n ...(result.status === 'done' ? { output: result.output } : {}),\n ...(result.status === 'failed' ? { error: result.error } : {}),\n ...(result.status === 'done' ? { toolCallCount: result.turns } : {}),\n ...(logPath !== undefined ? { transcriptPath: logPath } : {}),\n }\n await dispatchHooks(this.config.hooks.postRun, event)\n }\n\n private async finalizeResult(\n loopResult: Awaited<ReturnType<typeof agentLoop>>,\n writer: TranscriptWriter,\n _logPath: string,\n jsonOptions?: { outputFormat?: 'text' | 'json'; outputSchema?: import('zod').ZodTypeAny },\n ): Promise<RunResult> {\n if (loopResult.status === 'done') {\n await writer.setStatus('done')\n\n // Structured output: parse + validate JSON\n let data: unknown\n if (jsonOptions?.outputFormat === 'json') {\n const parsed = tryParseJSON(loopResult.output)\n if (parsed.ok) {\n if (jsonOptions.outputSchema) {\n const validated = validateOutput(parsed.value, jsonOptions.outputSchema)\n data = validated.ok ? validated.data : undefined\n } else {\n data = parsed.value\n }\n }\n // If parsing failed, data stays undefined — caller checks result.data\n }\n\n return {\n status: 'done',\n output: loopResult.output,\n ...(data !== undefined ? { data } : {}),\n tokensUsed: loopResult.tokensUsed,\n turns: loopResult.turns,\n }\n }\n if (loopResult.status === 'paused') {\n await writer.setStatus('paused')\n return {\n status: 'paused',\n snapshot: loopResult.snapshot,\n reason: loopResult.reason,\n }\n }\n await writer.setStatus('failed')\n return {\n status: 'failed',\n error: loopResult.error,\n transcript: loopResult.transcript,\n }\n }\n\n /**\n * Pick the effective `SkillSource` for a run.\n *\n * - Per-run override (`options.skills`) → `InlineSkillSource`\n * - else `config.skills.autoload === true` → `StorageSkillSource`\n * - else → undefined (SkillPage tool not registered)\n */\n private resolveSkillSource(\n overrides: ReadonlyArray<import('../skills/source.js').SkillOverride> | undefined,\n storage: EngineStorage,\n ): SkillSource | undefined {\n if (overrides !== undefined) {\n return new InlineSkillSource(overrides, {\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n ...(this.config.skills.allowedHosts !== undefined\n ? { allowedHosts: this.config.skills.allowedHosts }\n : {}),\n })\n }\n if (this.config.skills.autoload) {\n return new StorageSkillSource({\n storage,\n ...(this.config.skills.path !== undefined ? { baseDir: this.config.skills.path } : {}),\n })\n }\n return undefined\n }\n\n /**\n * Plan 020 — resolve the effective ApiCall config for a run.\n *\n * Precedence (each field independently):\n * RunOptions.api.X > config.api.X\n *\n * If neither side provides any services, returns undefined so the\n * tool isn't registered at all. Env + resolveAuth + hooks flow\n * through untouched — they never hit the Zod schema.\n */\n /**\n * Plan 021 — resolve the effective tool-result offload config.\n *\n * Precedence (each field independently):\n * RunOptions.compaction.toolResultOffload.X >\n * config.compaction.toolResultOffload.X\n *\n * When neither side enables offload, returns undefined and no\n * `FetchData` tool is registered.\n */\n private resolveOffloadConfig(\n // Run + Resume share the same override shape, so we pick either.\n override: NonNullable<RunOptions['compaction']>['toolResultOffload'],\n ): import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1 | undefined {\n const base = this.config.compaction.toolResultOffload\n if (override === undefined && base === undefined) return undefined\n const enabled = override?.enabled ?? base?.enabled ?? false\n if (!enabled) return undefined\n const thresholdBytes = override?.thresholdBytes ?? base?.thresholdBytes ?? 2048\n const maxPreviewChars = override?.maxPreviewChars ?? base?.maxPreviewChars ?? 500\n const summarizer = override?.summarizer ?? base?.summarizer\n return {\n enabled: true,\n thresholdBytes,\n maxPreviewChars,\n ...(summarizer !== undefined ? { summarizer } : {}),\n }\n }\n\n /**\n * Plan 023 — resolve the effective runtime knowledge bundle for a\n * single run.\n *\n * Engine-level config (`config.knowledge`) carries the capability\n * flag + scalar caps. The actual folders + external links are\n * RUNTIME-only, supplied via `RunOptions.knowledge`. Returning\n * `undefined` means \"don't register the knowledge tools\" — callers\n * skip the bundle entirely.\n *\n * Three gates must all pass:\n * 1. `config.knowledge.enabled === true` (engine opt-in)\n * 2. `storage.knowledge !== undefined` (adapter was built)\n * 3. There IS something to look at — at least one folder OR\n * one external link supplied for this run.\n */\n private resolveKnowledgeRuntime(\n // RunOptions['knowledge'] === ResumeOptions['knowledge'] — same\n // shape on both sides (RunKnowledgeOptionsV1).\n override: RunOptions['knowledge'],\n storage: EngineStorage,\n ):\n | {\n readonly adapter: import('../storage/interface.js').StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxSearchResults: number\n readonly maxReadBytes: number\n }\n | undefined {\n if (this.config.knowledge?.enabled !== true) return undefined\n if (storage.knowledge === undefined) return undefined\n const folders = override?.folders ?? []\n const external = override?.external ?? []\n if (folders.length === 0 && external.length === 0) return undefined\n return {\n adapter: storage.knowledge,\n folders,\n external,\n maxSearchResults: this.config.knowledge.maxSearchResults,\n maxReadBytes: this.config.knowledge.maxReadBytes,\n }\n }\n\n private resolveApiConfig(\n override: RunOptions['api'] | ResumeOptions['api'],\n ): ResolvedApiConfig | undefined {\n const base = this.config.api\n if (override === undefined && base === undefined) return undefined\n const services = override?.services ?? base?.services\n if (services === undefined || services.length === 0) return undefined\n const env = override?.env ?? base?.env\n const resolveAuth = override?.resolveAuth ?? base?.resolveAuth\n const onRequest =\n (override as { onRequest?: ResolvedApiConfig['onRequest'] })?.onRequest ?? base?.onRequest\n const onResponse =\n (override as { onResponse?: ResolvedApiConfig['onResponse'] })?.onResponse ?? base?.onResponse\n return {\n services,\n ...(env !== undefined ? { env } : {}),\n ...(resolveAuth !== undefined ? { resolveAuth } : {}),\n ...(onRequest !== undefined ? { onRequest } : {}),\n ...(onResponse !== undefined ? { onResponse } : {}),\n ...(base?.maxResponseBytes !== undefined ? { maxResponseBytes: base.maxResponseBytes } : {}),\n }\n }\n\n /**\n * Build a throttled heartbeat callback for agentLoop's `onProgress` hook.\n *\n * Only writes to `state.json` if one already exists for this run\n * (i.e., the run was started via `engine.start()` or `resumeAsync()`).\n * Sync `engine.run()` callers without a pre-existing state file get a\n * no-op heartbeat.\n *\n * Throttled to at most one write per 500ms AND only when activity\n * changes, so R2 writes stay cheap even for long runs.\n */\n private buildHeartbeat(\n storage: EngineStorage,\n runId: string,\n nodeId: string,\n ): (p: import('./agentLoop.js').LoopProgress) => Promise<void> {\n const stateManager = new RunStateManager(storage.workspace)\n let lastWriteAt = 0\n let lastActivity: string | undefined\n let lastTool: string | undefined\n const MIN_INTERVAL_MS = 500\n return async (progress) => {\n const now = Date.now()\n const activityChanged =\n progress.currentActivity !== lastActivity || progress.lastTool !== lastTool\n if (!activityChanged && now - lastWriteAt < MIN_INTERVAL_MS) return\n lastWriteAt = now\n lastActivity = progress.currentActivity\n lastTool = progress.lastTool\n // stateManager.heartbeat is a no-op when state.json doesn't exist.\n try {\n await stateManager.heartbeat(runId, nodeId, {\n turns: progress.turns,\n tokensUsed: progress.tokensUsed,\n currentActivity: progress.currentActivity,\n ...(progress.lastTool !== undefined ? { lastTool: progress.lastTool } : {}),\n })\n } catch {\n /* heartbeat is best-effort */\n }\n }\n }\n\n /**\n * Build the engine's storage pair. Uses the `EngineInternals.buildStorage`\n * override when provided (for Workers / custom adapters), otherwise\n * defers to the standard `createEngineStorage()` factory.\n */\n private async buildStorage(): Promise<EngineStorage> {\n if (this.internals.buildStorage !== undefined) {\n return this.internals.buildStorage()\n }\n return createEngineStorage(this.config.storage, {\n withKnowledge: this.config.knowledge?.enabled === true,\n })\n }\n\n private buildClient(): ModelAdapter {\n return createModelAdapter(this.config.model, {\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n }\n}\n\ninterface BuildRegistryOptions {\n readonly config: ResolvedConfig\n readonly storage: EngineStorage\n readonly client: ModelAdapter\n readonly parentLogPath: string\n readonly parentAgentId: string | null\n readonly subagentRegistry: SubagentRegistry\n readonly system: string\n readonly agents: ReadonlyArray<AgentDefinition>\n readonly mcpTools: ReadonlyArray<Tool>\n readonly memory: import('../memory/memoryConfig.js').SmartMemory\n /**\n * Gate to propagate to subagents when\n * `config.hooks.propagateGateToSubagents === true`. Undefined\n * otherwise, even if the parent has a gate configured.\n */\n readonly subagentGate?: GateBeforeTool\n /**\n * SkillSource powering the `SkillPage` tool. When undefined the\n * tool is not registered. The engine constructs either a\n * `StorageSkillSource` (default when `config.skills.autoload`) or an\n * `InlineSkillSource` (when `RunOptions.skills` is set).\n */\n readonly skillSource?: import('../skills/source.js').SkillSource\n /**\n * Plan 020 — effective api config for this run. When defined AND\n * `services` is non-empty, the engine auto-registers the `ApiCall`\n * built-in tool. Env + resolveAuth flow through here.\n */\n readonly apiConfig?: ResolvedApiConfig\n /**\n * Optional fetch override. Threaded into tools that issue HTTP\n * calls (currently just `ApiCall`) so Workers / test harnesses\n * can inject their own implementation.\n */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Plan 021 — tool-result offload config. When enabled, the\n * engine auto-registers the `FetchData` built-in bound to the\n * parent's log path. Subagents rebuild their own `FetchData`\n * inside `runAgent` so each agent can only rehydrate its own\n * offloaded blobs.\n */\n readonly toolResultOffload?: import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n /**\n * Plan 023 — knowledge runtime bundle. When provided, the engine\n * auto-registers `SearchKnowledge` + `ReadKnowledge` on BOTH the\n * parent and child registries. Folders + externals are shared\n * across all agents in the run (no per-agent rebuild needed —\n * the index cache lives inside the tool factory closure and is\n * harmless to share).\n */\n readonly knowledge?: {\n readonly adapter: import('../storage/interface.js').StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxSearchResults: number\n readonly maxReadBytes: number\n }\n}\n\nfunction buildToolRegistry(options: BuildRegistryOptions): ToolRegistry {\n const {\n config,\n storage,\n client,\n parentLogPath,\n parentAgentId,\n subagentRegistry,\n system,\n agents,\n mcpTools,\n memory,\n subagentGate,\n } = options\n const registry = new ToolRegistry()\n const enabled = new Set(config.tools.enabled)\n const disabled = new Set(config.tools.disabled)\n const wantAll = enabled.has('*')\n\n const childRegistry = new ToolRegistry()\n // In coordinator mode:\n // - Workers get ONLY tools listed in workerTools (implementation tools)\n // - Coordinator gets ONLY delegation tools (Agent, Tasks, Memory, ToolSearch, Sleep, SkillPage)\n // - This is CODE-ENFORCED, not prompt-enforced — the coordinator physically\n // cannot call Read/Write/Edit/Bash because they're not in its registry.\n const isCoord = isCoordinatorMode(config)\n const workerToolSet = isCoord ? new Set(config.coordinator.workerTools) : null\n const COORDINATOR_TOOLS = new Set([\n 'Agent',\n 'SendMessage',\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n 'Memorize',\n 'Recall',\n 'ToolSearch',\n 'Sleep',\n 'SkillPage',\n 'WebSearch',\n ])\n\n // TaskStore — shared across all task tools within this run.\n const taskStore = new TaskStore({\n storage: storage.workspace,\n logPath: parentLogPath,\n })\n\n // FileTracker — shared between Read and Write for staleness detection.\n const fileTracker = new FileTracker()\n\n // Tools that require subprocess spawning (Bash, Grep-via-ripgrep)\n // are registered on every runtime. When the host can't spawn\n // (Workers without nodejs_compat, or nodejs_compat where spawn\n // probes fail), `withCapabilityCheck` swaps in a capability stub so\n // the tool stays in the catalogue: the model still sees it and can\n // decide whether to call it, and the engine can intercept the call\n // to hand off to a Node runner when `config.runner` is set\n // (Plan 019). Tools not flagged `requiresNode` pass through.\n const spawnAvailable = canSpawnProcesses()\n\n const candidates: Array<{ name: string; tool: Tool }> = [\n // Bash — requires child_process.spawn. Stubbed on Workers.\n { name: 'Bash', tool: withCapabilityCheck(createBashTool(), spawnAvailable) },\n {\n name: 'Read',\n tool: createFileReadTool({ storage: storage.workspace, tracker: fileTracker }),\n },\n {\n name: 'Write',\n tool: createFileWriteTool({ storage: storage.workspace, tracker: fileTracker }),\n },\n { name: 'Edit', tool: createFileEditTool(storage.workspace) },\n { name: 'Glob', tool: createGlobTool(storage.workspace) },\n { name: 'Grep', tool: createGrepTool(storage.workspace) },\n { name: 'WebFetch', tool: createWebFetchTool() },\n { name: 'WebSearch', tool: createWebSearchTool() },\n { name: 'Sleep', tool: createSleepTool() },\n { name: 'NotebookEdit', tool: createNotebookEditTool(storage.workspace) },\n { name: 'TaskCreate', tool: createTaskCreateTool(taskStore) },\n { name: 'TaskGet', tool: createTaskGetTool(taskStore) },\n { name: 'TaskList', tool: createTaskListTool(taskStore) },\n { name: 'TaskUpdate', tool: createTaskUpdateTool(taskStore) },\n { name: 'Memorize', tool: createMemorizeTool(memory) },\n { name: 'Recall', tool: createRecallTool(memory) },\n ]\n\n for (const c of candidates) {\n if (disabled.has(c.name)) continue\n if (wantAll || enabled.has(c.name)) {\n if (isCoord) {\n // Coordinator mode: split tools between coordinator and workers.\n // Coordinator gets only delegation/management tools.\n // Workers get only implementation tools from workerTools config.\n if (COORDINATOR_TOOLS.has(c.name)) {\n registry.register(c.tool)\n }\n if (workerToolSet!.has(c.name)) {\n childRegistry.register(c.tool)\n }\n } else {\n // Normal mode: parent gets everything, child gets everything minus Agent.\n registry.register(c.tool)\n childRegistry.register(c.tool)\n }\n }\n }\n\n // SkillPage tool — registered when a SkillSource is provided (either\n // the disk-backed default when skills.autoload is on, or the inline\n // override when RunOptions.skills was supplied). It's available to\n // BOTH parent and children since loading a skill page is a pure read\n // and doesn't recurse.\n if (options.skillSource !== undefined) {\n const skillTool = createSkillPageTool({ source: options.skillSource })\n if (!disabled.has('SkillPage') && (wantAll || enabled.has('SkillPage'))) {\n registry.register(skillTool)\n childRegistry.register(skillTool)\n }\n }\n\n // ApiCall tool (Plan 020) — registered when apiConfig has services.\n // Pure HTTP fetch, works identically on Workers and Node; no\n // requiresNode. Available to parent + children so subagents can\n // call external APIs too.\n if (options.apiConfig !== undefined && options.apiConfig.services.length > 0) {\n if (!disabled.has('ApiCall') && (wantAll || enabled.has('ApiCall'))) {\n const apiTool = createApiCallTool({\n services: options.apiConfig.services,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n ...(options.apiConfig.env !== undefined ? { env: options.apiConfig.env } : {}),\n ...(options.apiConfig.resolveAuth !== undefined\n ? { resolveAuth: options.apiConfig.resolveAuth }\n : {}),\n ...(options.apiConfig.onRequest !== undefined\n ? { onRequest: options.apiConfig.onRequest }\n : {}),\n ...(options.apiConfig.onResponse !== undefined\n ? { onResponse: options.apiConfig.onResponse }\n : {}),\n ...(options.apiConfig.maxResponseBytes !== undefined\n ? { maxResponseBytes: options.apiConfig.maxResponseBytes }\n : {}),\n })\n registry.register(apiTool)\n childRegistry.register(apiTool)\n }\n }\n\n // FetchData tool (Plan 021) — registered on the PARENT registry\n // only, bound to the parent's log path. Subagents reconstruct\n // their own FetchData bound to `childLogPath` inside `runAgent`\n // so each agent can only rehydrate its own offloaded blobs.\n if (options.toolResultOffload?.enabled === true) {\n if (!disabled.has('FetchData') && (wantAll || enabled.has('FetchData'))) {\n const fetchDataTool = createFetchDataTool({\n storage: storage.workspace,\n logPath: options.parentLogPath,\n })\n registry.register(fetchDataTool)\n // NOTE: intentionally NOT registered on childRegistry — the\n // subagent runner builds its own child-scoped instance.\n }\n }\n\n // SearchKnowledge + ReadKnowledge tools (Plan 023) — registered\n // on BOTH parent and child registries. Unlike FetchData these\n // tools are stateless w.r.t. log paths: the knowledge adapter is\n // tenant-scoped and shared, and the per-call index/file caches\n // live in the factory closure (cheap to share across agents in\n // one run). External link `headers` close over the factory and\n // never reach any persisted surface — see externalLinkSecrets test.\n if (options.knowledge !== undefined) {\n const k = options.knowledge\n if (!disabled.has('SearchKnowledge') && (wantAll || enabled.has('SearchKnowledge'))) {\n const searchTool = createSearchKnowledgeTool({\n adapter: k.adapter,\n folders: k.folders,\n external: k.external,\n maxSearchResults: k.maxSearchResults,\n })\n registry.register(searchTool)\n childRegistry.register(searchTool)\n }\n if (!disabled.has('ReadKnowledge') && (wantAll || enabled.has('ReadKnowledge'))) {\n const readTool = createReadKnowledgeTool({\n adapter: k.adapter,\n folders: k.folders,\n external: k.external,\n maxReadBytes: k.maxReadBytes,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n })\n registry.register(readTool)\n childRegistry.register(readTool)\n }\n }\n\n // The Agent tool is registered ONLY on the parent registry.\n const agentTool = createAgentTool({\n storage: storage.workspace,\n client,\n childRegistry,\n parentLogPath,\n parentAgentId,\n subagentRegistry,\n system,\n maxTurns: config.execution.maxTurns,\n contextLimit: 200_000,\n turnTimeoutMs: config.execution.turnTimeoutMs,\n flushPolicy: config.transcript.flushPolicy,\n idleFlushMs: config.transcript.idleFlushMs,\n agents,\n coordinatorMode: isCoordinatorMode(config),\n ...(subagentGate !== undefined ? { gateBeforeTool: subagentGate } : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n })\n if (!disabled.has('Agent') && (wantAll || enabled.has('Agent'))) {\n registry.register(agentTool)\n }\n\n // SendMessage tool — registered on parent only (like Agent).\n // Enables inter-agent communication within coordinator workflows.\n const sendMessageTool = createSendMessageTool({ registry: subagentRegistry })\n if (!disabled.has('SendMessage') && (wantAll || enabled.has('SendMessage'))) {\n registry.register(sendMessageTool)\n }\n\n // Custom tools — registered as-is on both parent and child registries.\n for (const custom of config.tools.custom) {\n registry.register(custom as Tool)\n childRegistry.register(custom as Tool)\n }\n\n // MCP-sourced tools — already adapted by McpManager, already prefixed\n // `mcp__{server}__{tool}`. Registered on both parent and child so\n // subagents can also dispatch to external tool servers.\n for (const tool of mcpTools) {\n if (disabled.has(tool.name)) continue\n if (wantAll || enabled.has(tool.name)) {\n registry.register(tool)\n childRegistry.register(tool)\n }\n }\n\n // ToolSearch — needs the populated registry as input, so it's\n // registered after all other tools. Available to both parent and child.\n if (!disabled.has('ToolSearch') && (wantAll || enabled.has('ToolSearch'))) {\n const toolSearchTool = createToolSearchTool(registry)\n registry.register(toolSearchTool)\n childRegistry.register(createToolSearchTool(childRegistry))\n }\n\n return registry\n}\n","/**\n * Model adapter factory — routes config to the right adapter.\n *\n * Same pattern as storage/factory.ts:\n * createEngineStorage(config.storage) → StorageAdapter\n * createModelAdapter(config.model) → ModelAdapter\n */\n\nimport type { ResolvedModelConfig } from '../config/types.js'\nimport { selectProvider } from '../api/providerSelector.js'\nimport type { ModelAdapter } from './adapter.js'\nimport { AnthropicAdapter } from './anthropicAdapter.js'\nimport { AISdkAdapter } from './aiSdkAdapter.js'\n\nexport interface CreateModelAdapterOptions {\n /** Custom fetch for the Anthropic adapter (OpenRouter auth override). */\n readonly fetch?: typeof globalThis.fetch | undefined\n}\n\n/**\n * Create a ModelAdapter from the resolved model config.\n *\n * Routing:\n * - 'anthropic' (no sdk override) → AnthropicAdapter (@anthropic-ai/sdk)\n * - 'proxy' → AnthropicAdapter with baseURL\n * - 'openai', 'google', 'openai-compatible' → AISdkAdapter\n * - 'anthropic' + sdk: 'ai-sdk' → AISdkAdapter with @ai-sdk/anthropic\n */\nexport function createModelAdapter(\n config: ResolvedModelConfig,\n options: CreateModelAdapterOptions = {},\n): ModelAdapter {\n const provider = config.provider\n const sdk = (config as { sdk?: string }).sdk\n\n // Legacy path: Anthropic SDK (default for 'anthropic' and 'proxy')\n if ((provider === 'anthropic' && sdk !== 'ai-sdk') || provider === 'proxy') {\n const plan = selectProvider(config)\n return new AnthropicAdapter({\n plan,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n })\n }\n\n // AI SDK path: everything else\n return new AISdkAdapter({\n provider: provider === 'anthropic' ? 'anthropic' : provider,\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxRetries: config.maxRetries,\n })\n}\n","/**\n * providerSelector — translate a `ResolvedModelConfig` into a typed\n * `ProviderPlan` describing what API client to construct and how.\n *\n * The plan is a thin, validated intermediate between user config and the\n * actual SDK construction so that:\n * 1. Invalid combinations (proxy provider without baseURL, anthropic\n * without apiKey) are rejected at this layer, not at runtime inside\n * the SDK's message send\n * 2. Deferred backends (Bedrock, Vertex, Foundry) can be flagged here\n * with a clear `NotImplementedError` pointing at the v0.2 milestone\n * 3. Tests can exercise selection logic independently of actual client\n * construction\n */\n\nimport type { ResolvedModelConfig } from '../config/types.js'\nimport { ConfigError, NotImplementedError } from '../engine/errors.js'\n\nexport interface AnthropicProviderPlan {\n readonly kind: 'anthropic'\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL: string | undefined\n readonly maxTokens: number\n readonly temperature: number\n readonly maxRetries: number\n}\n\nexport interface ProxyProviderPlan {\n readonly kind: 'proxy'\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL: string\n readonly maxTokens: number\n readonly temperature: number\n readonly maxRetries: number\n}\n\nexport type ProviderPlan = AnthropicProviderPlan | ProxyProviderPlan\n\nexport function selectProvider(config: ResolvedModelConfig): ProviderPlan {\n switch (config.provider) {\n case 'anthropic':\n if (config.apiKey.length === 0) {\n throw new ConfigError('anthropic provider requires a non-empty apiKey')\n }\n return {\n kind: 'anthropic',\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n maxRetries: config.maxRetries,\n }\n\n case 'proxy':\n if (config.baseURL === undefined || config.baseURL.length === 0) {\n throw new ConfigError('proxy provider requires a non-empty baseURL')\n }\n return {\n kind: 'proxy',\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n maxRetries: config.maxRetries,\n }\n\n case 'bedrock':\n throw new NotImplementedError('bedrock provider', 'v0.2')\n\n case 'vertex':\n throw new NotImplementedError('vertex provider', 'v0.2')\n\n default:\n // New providers (openai, google, openai-compatible) go through\n // the AI SDK adapter, not selectProvider. If we get here, the\n // factory routed incorrectly.\n throw new ConfigError(\n `selectProvider: \"${config.provider}\" should use the AI SDK adapter, not the Anthropic SDK`,\n )\n }\n}\n","/**\n * Error taxonomy for la-machina-engine.\n *\n * Every thrown error must be a subclass of `EngineError`, so callers can\n * `instanceof` discriminate at the library boundary. Phase 1 defines only\n * the errors needed for config resolution and unimplemented methods.\n * Later phases extend this hierarchy (see plan 002 §4 Phase 4).\n */\n\nexport class EngineError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = this.constructor.name\n this.code = code\n }\n}\n\n/**\n * Thrown when config is invalid or incomplete. Raised by `initEngine()` when\n * `apiKey` cannot be resolved, or when schema validation fails.\n */\nexport class ConfigError extends EngineError {\n constructor(message: string) {\n super('ERR_CONFIG', message)\n }\n}\n\n/**\n * Thrown when a method is called in a phase where its implementation has\n * not yet landed. Used by `engine.run()` and `engine.resume()` during\n * Phases 1–6 before the loop is wired, and by provider selectors for\n * backends deferred to v0.2 (Bedrock, Vertex, Foundry).\n */\nexport class NotImplementedError extends EngineError {\n constructor(feature: string, target: string) {\n super('ERR_NOT_IMPLEMENTED', `${feature} is not implemented until ${target}`)\n }\n}\n\n// ---------- API errors (Phase 4) ----------\n\n/**\n * Thrown when the provider rejects a request with HTTP 401/403 (missing\n * or invalid API key). Callers should not retry.\n */\nexport class AuthError extends EngineError {\n constructor(message: string) {\n super('ERR_AUTH', message)\n }\n}\n\n/**\n * Thrown when the provider returns HTTP 429 (rate limited). Callers\n * should back off and retry. `retryAfterMs` reflects the provider's\n * hint when available, otherwise null.\n */\nexport class RateLimitError extends EngineError {\n readonly retryAfterMs: number | null\n\n constructor(message: string, retryAfterMs: number | null = null) {\n super('ERR_RATE_LIMIT', message)\n this.retryAfterMs = retryAfterMs\n }\n}\n\n/**\n * Thrown when a streaming response can't be parsed into a normalized\n * event — typically malformed SSE or a JSON parse failure in a delta.\n * This is a hard error; the stream is not recoverable.\n */\nexport class StreamParseError extends EngineError {\n constructor(message: string) {\n super('ERR_STREAM_PARSE', message)\n }\n}\n\n/**\n * Thrown when a streaming response ends without a terminal event\n * (`message_stop`). The caller cannot know whether the assistant\n * actually finished — almost always safer to fail the run and retry.\n */\nexport class StreamIncompleteError extends EngineError {\n constructor(message: string) {\n super('ERR_STREAM_INCOMPLETE', message)\n }\n}\n\n/**\n * Generic provider-side API error — non-auth, non-rate-limit failures\n * like 500s, network drops, and unrecognized shapes. `status` is the\n * HTTP status code when available, otherwise null.\n */\nexport class ApiError extends EngineError {\n readonly status: number | null\n\n constructor(message: string, status: number | null = null) {\n super('ERR_API', message)\n this.status = status\n }\n}\n\n/**\n * Thrown when a run exceeds `execution.runTimeoutMs`. The agent loop is\n * aborted at the next checkpoint (top of the turn loop or after a tool\n * dispatch). The transcript so far is preserved.\n */\nexport class RunTimeoutError extends EngineError {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super('ERR_RUN_TIMEOUT', `Run exceeded runTimeoutMs=${timeoutMs}`)\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Thrown from inside the Agent tool when a subagent's loop paused due to\n * a gate denial. The parent's agentLoop catches this and surfaces it as\n * its own `paused` result, carrying the child's snapshot for future\n * resume support.\n *\n * Only thrown when `hooks.propagateGateToSubagents: true` is set on the\n * parent engine config. Without that flag, subagents can't use the\n * parent's gate and this error never appears.\n */\nexport class SubagentPausedError extends EngineError {\n readonly childSnapshot: import('./types.js').RunSnapshot\n readonly parentToolUseId: string\n readonly subagentType: string\n\n constructor(params: {\n childSnapshot: import('./types.js').RunSnapshot\n parentToolUseId: string\n subagentType: string\n }) {\n super(\n 'ERR_SUBAGENT_PAUSED',\n `Subagent \"${params.subagentType}\" paused at tool \"${params.childSnapshot.pendingToolCall?.toolName ?? 'unknown'}\"`,\n )\n this.childSnapshot = params.childSnapshot\n this.parentToolUseId = params.parentToolUseId\n this.subagentType = params.subagentType\n }\n}\n","/**\n * AnthropicAdapter — wraps the existing @anthropic-ai/sdk client as a\n * ModelAdapter. Default provider.\n */\n\nimport { AnthropicClient, type AnthropicClientOptions } from '../api/anthropicClient.js'\nimport type { ModelAdapter, StreamRequest } from './adapter.js'\nimport type { NormalizedEvent } from '../api/streaming.js'\n\nexport class AnthropicAdapter implements ModelAdapter {\n private readonly client: AnthropicClient\n\n constructor(options: AnthropicClientOptions) {\n this.client = new AnthropicClient(options)\n }\n\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n yield* this.client.streamMessage(request as any)\n }\n}\n","/**\n * AnthropicClient — thin wrapper around `@anthropic-ai/sdk`.\n *\n * Responsibilities:\n * 1. Construct an `Anthropic` instance from a `ProviderPlan` (anthropic\n * first-party or proxy). Passes a custom `fetch` when supplied so\n * tests can drive the client with a scripted fetch without any real\n * network I/O.\n * 2. Expose `streamMessage(request)` as an async generator of\n * `NormalizedEvent`, with Anthropic SDK stream events passed through\n * `normalizeStream` on the way out.\n * 3. Translate SDK-level errors into the engine's typed error taxonomy\n * (`AuthError`, `RateLimitError`, `ApiError`, etc.) so callers can\n * discriminate without instanceof-checking third-party classes.\n *\n * The client is stateless — each `streamMessage` call is independent.\n * Callers should reuse a single `AnthropicClient` per run; the\n * underlying SDK already pools HTTP connections internally.\n */\n\nimport Anthropic, {\n APIError,\n AuthenticationError as SdkAuthenticationError,\n PermissionDeniedError as SdkPermissionDeniedError,\n RateLimitError as SdkRateLimitError,\n} from '@anthropic-ai/sdk'\nimport type {\n MessageCreateParamsStreaming,\n MessageStreamEvent,\n Tool,\n} from '@anthropic-ai/sdk/resources/messages'\nimport { ApiError, AuthError, EngineError, RateLimitError } from '../engine/errors.js'\nimport { computeBetaHeaders } from './betaHeaders.js'\nimport type { ProviderPlan } from './providerSelector.js'\nimport { normalizeStream, type NormalizedEvent } from './streaming.js'\n\nexport interface StreamRequest {\n readonly messages: MessageCreateParamsStreaming['messages']\n readonly system?: MessageCreateParamsStreaming['system']\n readonly tools?: Tool[]\n readonly maxTokens?: number\n readonly temperature?: number\n}\n\nexport interface AnthropicClientOptions {\n readonly plan: ProviderPlan\n /** Custom fetch for tests. Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport class AnthropicClient {\n private readonly plan: ProviderPlan\n private readonly sdk: Anthropic\n\n constructor(options: AnthropicClientOptions) {\n this.plan = options.plan\n\n const baseURL = this.plan.kind === 'proxy' ? this.plan.baseURL : this.plan.baseURL\n\n const sdkOptions: ConstructorParameters<typeof Anthropic>[0] = {\n apiKey: this.plan.apiKey,\n // SDK handles retry with exponential backoff on 429/500.\n // Default: 2 retries. Configurable via config.model.maxRetries.\n maxRetries: this.plan.maxRetries,\n }\n if (baseURL !== undefined) sdkOptions.baseURL = baseURL\n if (options.fetch !== undefined) sdkOptions.fetch = options.fetch\n\n this.sdk = new Anthropic(sdkOptions)\n }\n\n /**\n * Stream a message and yield normalized events. The caller should\n * consume the iterator to completion or abort via AbortSignal upstream.\n */\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n const betas = computeBetaHeaders(\n this.plan.kind === 'proxy' ? this.plan.baseURL : this.plan.baseURL,\n this.plan.modelId,\n )\n\n const params: MessageCreateParamsStreaming = {\n model: this.plan.modelId,\n max_tokens: request.maxTokens ?? this.plan.maxTokens,\n temperature: request.temperature ?? this.plan.temperature,\n messages: request.messages,\n stream: true,\n ...(request.system !== undefined ? { system: request.system } : {}),\n ...(request.tools !== undefined ? { tools: request.tools } : {}),\n }\n\n const requestOptions: { headers?: Record<string, string> } = {}\n if (betas.length > 0) {\n requestOptions.headers = { 'anthropic-beta': betas.join(',') }\n }\n\n let stream: AsyncIterable<MessageStreamEvent>\n try {\n stream = this.sdk.messages.stream(params, requestOptions)\n } catch (err) {\n throw mapSdkError(err)\n }\n\n try {\n yield* normalizeStream(wrapSdkErrors(stream))\n } catch (err) {\n if (err instanceof EngineError) throw err\n throw mapSdkError(err)\n }\n }\n}\n\n/**\n * Wrap an SDK stream in an async iterable that translates SDK errors\n * into engine errors as they occur during iteration.\n */\nasync function* wrapSdkErrors(\n source: AsyncIterable<MessageStreamEvent>,\n): AsyncGenerator<MessageStreamEvent, void, void> {\n try {\n for await (const event of source) yield event\n } catch (err) {\n throw mapSdkError(err)\n }\n}\n\nfunction mapSdkError(err: unknown): Error {\n if (err instanceof EngineError) return err\n if (err instanceof SdkAuthenticationError || err instanceof SdkPermissionDeniedError) {\n return new AuthError(err.message)\n }\n if (err instanceof SdkRateLimitError) {\n const retryAfterMs = parseRetryAfter(err.headers)\n return new RateLimitError(err.message, retryAfterMs)\n }\n if (err instanceof APIError) {\n const status = typeof err.status === 'number' ? err.status : null\n return new ApiError(err.message, status)\n }\n if (err instanceof Error) {\n return new ApiError(err.message, null)\n }\n return new ApiError(String(err), null)\n}\n\nfunction parseRetryAfter(headers: unknown): number | null {\n if (headers === null || typeof headers !== 'object') return null\n const h = headers as { get?: (key: string) => string | null; 'retry-after'?: unknown }\n let raw: string | null | undefined\n if (typeof h.get === 'function') {\n raw = h.get('retry-after')\n } else if (typeof h['retry-after'] === 'string') {\n raw = h['retry-after']\n }\n if (raw === null || raw === undefined || raw === '') return null\n const seconds = Number(raw)\n if (Number.isFinite(seconds)) return Math.round(seconds * 1000)\n return null\n}\n","/**\n * Beta headers — Anthropic-specific `anthropic-beta` header values.\n *\n * Each header toggles an opt-in feature on the Anthropic API (1M context\n * window, interleaved thinking, tool use enhancements, etc.). They are\n * recognized ONLY by `api.anthropic.com`. Sending them to a third-party\n * proxy (OpenRouter, LiteLLM, a custom gateway) returns HTTP 400.\n *\n * This module preserves La-Machina's behavior from commit 6efec3b:\n *\n * - First-party base URL → include the engine's default beta set.\n * - Non-first-party base URL → strip all defaults; only honor explicit\n * `ANTHROPIC_BETAS=...` user opt-in.\n *\n * The \"default beta set\" is deliberately small. The engine ships with:\n * - `claude-code-20250219` — the main feature flag\n *\n * Additional betas (1M context, interleaved thinking, etc.) can be added\n * via `ANTHROPIC_BETAS` env var merging. We avoid hard-coding beta values\n * that are model-specific or experiment-gated in La-Machina — those\n * decisions belong to the caller.\n */\n\nconst DEFAULT_BETAS = ['claude-code-20250219']\n\n/**\n * Returns true if the given base URL points at the first-party Anthropic\n * API (or is unset). Any other host — including a URL that happens to\n * contain \"anthropic\" as a substring — returns false.\n *\n * Matches La-Machina's `isFirstPartyAnthropicBaseUrl` minus the\n * ant-internal staging host (we have no USER_TYPE concept).\n */\nexport function isFirstPartyBaseUrl(baseURL: string | undefined): boolean {\n if (!baseURL) return true\n let host: string\n try {\n host = new URL(baseURL).host\n } catch {\n return false\n }\n return host === 'api.anthropic.com'\n}\n\n/**\n * Compute the `anthropic-beta` header values for a given base URL + model.\n *\n * `_modelId` is reserved for future model-specific betas (1M context,\n * interleaved thinking) but is unused in v0.1. The engine's caller can\n * opt in via `ANTHROPIC_BETAS` env var, which merges into the default set\n * in first-party mode and REPLACES it in proxy mode.\n */\nexport function computeBetaHeaders(baseURL: string | undefined, _modelId: string): string[] {\n const userOptIn = parseEnvBetas()\n\n if (!isFirstPartyBaseUrl(baseURL)) {\n return userOptIn\n }\n\n // First-party mode: merge defaults with any user opt-in.\n const seen = new Set<string>()\n const result: string[] = []\n for (const beta of [...DEFAULT_BETAS, ...userOptIn]) {\n if (!seen.has(beta)) {\n seen.add(beta)\n result.push(beta)\n }\n }\n return result\n}\n\nfunction parseEnvBetas(): string[] {\n const raw = process.env.ANTHROPIC_BETAS\n if (raw === undefined || raw === '') return []\n return raw\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n","/**\n * streaming — normalize raw Anthropic stream events into a small,\n * well-shaped union that the engine's agent loop can consume.\n *\n * The Anthropic SDK emits a discriminated union of six raw events per\n * stream:\n * message_start — metadata and initial usage\n * content_block_start — begin a text or tool_use block\n * content_block_delta — partial text or input_json chunk\n * content_block_stop — end of a block\n * message_delta — stop_reason + final output_tokens\n * message_stop — terminal event\n *\n * This module collects deltas into complete blocks and emits a cleaner\n * union: `text` / `tool_use` / `message_stop`. Tool_use input JSON is\n * assembled and parsed once at content_block_stop so downstream code\n * sees a typed object rather than raw partial JSON.\n *\n * Errors:\n * - Malformed tool_use JSON → `StreamParseError`\n * - Stream ends without `message_stop` → `StreamIncompleteError`\n */\n\nimport type { MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages'\nimport { StreamIncompleteError, StreamParseError } from '../engine/errors.js'\n\nexport interface TokenUsage {\n readonly input: number\n readonly output: number\n readonly cacheCreationInput?: number | undefined\n readonly cacheReadInput?: number | undefined\n}\n\n/**\n * Common Anthropic stop reasons. The `(string & {})` pattern preserves\n * autocomplete for the documented values while still allowing arbitrary\n * strings from third-party proxies that may use other vocabularies.\n */\nexport type StopReason =\n | 'end_turn'\n | 'tool_use'\n | 'max_tokens'\n | 'stop_sequence'\n | 'refusal'\n | 'pause_turn'\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n | (string & Record<never, never>)\n\nexport type NormalizedEvent =\n | {\n readonly type: 'text'\n readonly index: number\n readonly text: string\n }\n | {\n readonly type: 'tool_use'\n readonly index: number\n readonly id: string\n readonly name: string\n readonly input: unknown\n }\n | {\n readonly type: 'thinking'\n readonly index: number\n readonly thinking: string\n }\n | {\n readonly type: 'message_stop'\n readonly stopReason: StopReason\n readonly usage: TokenUsage\n }\n\ninterface InFlightBlock {\n readonly index: number\n readonly kind: 'text' | 'tool_use' | 'thinking'\n textBuffer: string\n toolUseId: string\n toolUseName: string\n inputJsonBuffer: string\n}\n\ninterface StreamState {\n blocks: Map<number, InFlightBlock>\n inputTokens: number\n outputTokens: number\n cacheCreationInput?: number\n cacheReadInput?: number\n stopReason: StopReason | null\n sawStop: boolean\n}\n\n/**\n * Consume an async iterable of raw Anthropic stream events and yield\n * normalized events. Throws on malformed or incomplete streams.\n */\nexport async function* normalizeStream(\n source: AsyncIterable<MessageStreamEvent>,\n): AsyncGenerator<NormalizedEvent, void, void> {\n const state: StreamState = {\n blocks: new Map(),\n inputTokens: 0,\n outputTokens: 0,\n stopReason: null,\n sawStop: false,\n }\n\n for await (const event of source) {\n const emitted = handleEvent(event, state)\n if (emitted) yield emitted\n }\n\n if (!state.sawStop) {\n throw new StreamIncompleteError(\n 'Stream ended without a message_stop event; assistant output is partial',\n )\n }\n\n // After the final message_stop we emit our own terminal event with the\n // aggregated stop reason and usage so the caller has a single place to\n // read them.\n yield {\n type: 'message_stop',\n stopReason: state.stopReason ?? 'end_turn',\n usage: buildUsage(state),\n }\n}\n\nfunction handleEvent(event: MessageStreamEvent, state: StreamState): NormalizedEvent | null {\n switch (event.type) {\n case 'message_start': {\n const usage = event.message.usage\n state.inputTokens = usage.input_tokens\n state.outputTokens = usage.output_tokens\n if (typeof usage.cache_creation_input_tokens === 'number') {\n state.cacheCreationInput = usage.cache_creation_input_tokens\n }\n if (typeof usage.cache_read_input_tokens === 'number') {\n state.cacheReadInput = usage.cache_read_input_tokens\n }\n return null\n }\n\n case 'content_block_start': {\n const block = event.content_block\n if (block.type === 'text') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'text',\n textBuffer: block.text,\n toolUseId: '',\n toolUseName: '',\n inputJsonBuffer: '',\n })\n } else if (block.type === 'tool_use') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'tool_use',\n textBuffer: '',\n toolUseId: block.id,\n toolUseName: block.name,\n inputJsonBuffer: '',\n })\n }\n // Thinking blocks — preserve for extended thinking support.\n if (block.type === 'thinking') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'thinking',\n textBuffer: (block as { thinking?: string }).thinking ?? '',\n toolUseId: '',\n toolUseName: '',\n inputJsonBuffer: '',\n })\n }\n // Other block types (server_tool_use, etc.) silently ignored.\n return null\n }\n\n case 'content_block_delta': {\n const block = state.blocks.get(event.index)\n if (!block) return null\n const delta = event.delta\n if (delta.type === 'text_delta' && block.kind === 'text') {\n block.textBuffer += delta.text\n } else if (delta.type === 'input_json_delta' && block.kind === 'tool_use') {\n block.inputJsonBuffer += delta.partial_json\n } else if (delta.type === 'thinking_delta' && block.kind === 'thinking') {\n block.textBuffer += (delta as { thinking?: string }).thinking ?? ''\n }\n return null\n }\n\n case 'content_block_stop': {\n const block = state.blocks.get(event.index)\n if (!block) return null\n state.blocks.delete(event.index)\n if (block.kind === 'text') {\n return { type: 'text', index: block.index, text: block.textBuffer }\n }\n if (block.kind === 'thinking') {\n return { type: 'thinking', index: block.index, thinking: block.textBuffer }\n }\n // tool_use — parse the accumulated JSON input\n let input: unknown = {}\n if (block.inputJsonBuffer.length > 0) {\n try {\n input = JSON.parse(block.inputJsonBuffer)\n } catch (err) {\n throw new StreamParseError(\n `Failed to parse tool_use input JSON for \"${block.toolUseName}\": ${(err as Error).message}`,\n )\n }\n }\n return {\n type: 'tool_use',\n index: block.index,\n id: block.toolUseId,\n name: block.toolUseName,\n input,\n }\n }\n\n case 'message_delta': {\n if (event.delta.stop_reason) {\n state.stopReason = event.delta.stop_reason\n }\n if (typeof event.usage.output_tokens === 'number') {\n state.outputTokens = event.usage.output_tokens\n }\n return null\n }\n\n case 'message_stop': {\n state.sawStop = true\n return null\n }\n }\n}\n\nfunction buildUsage(state: StreamState): TokenUsage {\n const usage: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n } = {\n input: state.inputTokens,\n output: state.outputTokens,\n }\n if (state.cacheCreationInput !== undefined) {\n usage.cacheCreationInput = state.cacheCreationInput\n }\n if (state.cacheReadInput !== undefined) {\n usage.cacheReadInput = state.cacheReadInput\n }\n return usage\n}\n","/**\n * AISdkAdapter — ModelAdapter using the Vercel AI SDK for 75+ providers.\n *\n * Properly converts Anthropic-format messages to AI SDK v4 ModelMessage\n * format, including tool_use/tool_result round-trips. The key is that\n * AI SDK v4 requires tool result output as { type: 'text', value: '...' }\n * (not a plain string or generic object).\n */\n\nimport { streamText, type LanguageModel } from 'ai'\nimport type { ModelAdapter, StreamRequest } from './adapter.js'\nimport type { NormalizedEvent, StopReason } from '../api/streaming.js'\nimport { toAISdkMessages } from './messageConverter.js'\nimport { toAISdkTools } from './toolConverter.js'\n\nexport interface AISdkAdapterOptions {\n readonly provider: string\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL?: string | undefined\n readonly maxRetries?: number | undefined\n}\n\nexport class AISdkAdapter implements ModelAdapter {\n private readonly options: AISdkAdapterOptions\n private model: LanguageModel | null = null\n\n constructor(options: AISdkAdapterOptions) {\n this.options = options\n }\n\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n const model = await this.getModel()\n const messages = toAISdkMessages(request.messages as unknown as Record<string, unknown>[])\n const tools = toAISdkTools(\n request.tools as unknown as readonly Record<string, unknown>[] | undefined,\n )\n\n const result = streamText({\n model,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: messages as any,\n ...(request.system !== undefined ? { system: request.system } : {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tools: tools as any,\n ...(request.maxTokens !== undefined ? { maxOutputTokens: request.maxTokens } : {}),\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n maxRetries: this.options.maxRetries ?? 2,\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for await (const event of result.fullStream as AsyncIterable<any>) {\n switch (event.type) {\n case 'text-delta':\n yield {\n type: 'text' as const,\n index: 0,\n text: (event.text ?? event.textDelta ?? '') as string,\n }\n break\n case 'tool-call':\n yield {\n type: 'tool_use' as const,\n index: 0,\n id: (event.toolCallId ?? '') as string,\n name: (event.toolName ?? '') as string,\n // AI SDK v4: tool args are in `event.input` (not `event.args`)\n input: event.input ?? event.args ?? {},\n }\n break\n case 'finish': {\n const usage = event.totalUsage ?? event.usage ?? {}\n yield {\n type: 'message_stop' as const,\n stopReason: mapFinishReason(event.finishReason),\n usage: {\n input: usage.inputTokens ?? usage.promptTokens ?? 0,\n output: usage.outputTokens ?? usage.completionTokens ?? 0,\n },\n }\n break\n }\n }\n }\n }\n\n private async getModel(): Promise<LanguageModel> {\n if (this.model !== null) return this.model\n const { provider, modelId, apiKey, baseURL } = this.options\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let mod: any\n switch (provider) {\n case 'anthropic':\n mod = await importOrThrow('@ai-sdk/anthropic', provider)\n this.model = mod.createAnthropic({ apiKey })(modelId)\n break\n case 'openai':\n mod = await importOrThrow('@ai-sdk/openai', provider)\n this.model = mod.createOpenAI({ apiKey, ...(baseURL ? { baseURL } : {}) })(modelId)\n break\n case 'google':\n mod = await importOrThrow('@ai-sdk/google', provider)\n this.model = mod.createGoogleGenerativeAI({ apiKey })(modelId)\n break\n case 'openai-compatible':\n mod = await importOrThrow('@ai-sdk/openai-compatible', provider)\n this.model = mod.createOpenAICompatible({ name: 'custom', apiKey, baseURL: baseURL ?? '' })(\n modelId,\n )\n break\n default:\n throw new Error(`AI SDK: unsupported provider \"${provider}\".`)\n }\n return this.model!\n }\n}\n\nfunction mapFinishReason(reason: string | undefined | null): StopReason {\n switch (reason) {\n case 'stop':\n return 'end_turn'\n case 'tool-calls':\n return 'tool_use'\n case 'length':\n return 'max_tokens'\n default:\n return 'end_turn'\n }\n}\n\nasync function importOrThrow(pkg: string, provider: string): Promise<Record<string, unknown>> {\n try {\n return (await import(pkg)) as Record<string, unknown>\n } catch {\n throw new Error(`Provider \"${provider}\" requires \"${pkg}\". Install: npm i ${pkg}`)\n }\n}\n","/**\n * Convert Anthropic-format messages → AI SDK v4 ModelMessage format.\n *\n * Key: AI SDK v4 tool results require:\n * { type: 'tool-result', toolCallId, toolName, output: { type: 'text', value: '...' } }\n *\n * The Anthropic format puts toolName only in the assistant's tool_use\n * block. AI SDK v4 requires it in both places. We map toolCallId →\n * toolName during conversion.\n */\n\nexport function toAISdkMessages(messages: readonly Record<string, unknown>[]): unknown[] {\n const out: unknown[] = []\n const toolNames = new Map<string, string>()\n\n for (const msg of messages) {\n const role = msg.role as string\n const content = msg.content\n\n if (role === 'user') {\n if (typeof content === 'string') {\n out.push({ role: 'user', content })\n continue\n }\n if (!Array.isArray(content)) continue\n\n const textParts: unknown[] = []\n const toolResults: unknown[] = []\n\n for (const block of content as Record<string, unknown>[]) {\n if (block.type === 'tool_result') {\n const id = block.tool_use_id as string\n const resultText =\n typeof block.content === 'string' ? block.content : JSON.stringify(block.content ?? '')\n toolResults.push({\n type: 'tool-result',\n toolCallId: id,\n toolName: toolNames.get(id) ?? 'unknown',\n output: { type: 'text', value: resultText },\n })\n } else if (block.type === 'text') {\n textParts.push({ type: 'text', text: block.text as string })\n }\n }\n\n // Order matters — AI SDK validates tool_call ↔ tool_result pairing\n // in prompt order. A `tool` message closes the pairing; a `user`\n // message must come AFTER all pending tool_results are resolved,\n // or the validator throws `MissingToolResultsError`.\n //\n // When a single Anthropic user message carries both a tool_result\n // and a follow-up text (the engine's synthetic-retry injection\n // pattern, Plan 019), we split into `tool` FIRST, then `user`.\n if (toolResults.length > 0) out.push({ role: 'tool', content: toolResults })\n if (textParts.length > 0) out.push({ role: 'user', content: textParts })\n } else if (role === 'assistant') {\n if (typeof content === 'string') {\n out.push({ role: 'assistant', content })\n continue\n }\n if (!Array.isArray(content)) {\n out.push({ role: 'assistant', content: '' })\n continue\n }\n\n const parts: unknown[] = []\n for (const block of content as Record<string, unknown>[]) {\n if (block.type === 'text') {\n parts.push({ type: 'text', text: block.text as string })\n } else if (block.type === 'tool_use') {\n const id = block.id as string\n const name = block.name as string\n toolNames.set(id, name)\n parts.push({\n type: 'tool-call',\n toolCallId: id,\n toolName: name,\n args: block.input ?? {},\n })\n }\n }\n out.push({ role: 'assistant', content: parts })\n }\n }\n\n return out\n}\n","/**\n * Convert engine tool definitions to AI SDK tool format.\n *\n * Handles both ModelToolDefinition (inputSchema) and Anthropic-format\n * tools (input_schema) since the agentLoop's toAnthropicTool() produces\n * the latter.\n */\n\nimport { jsonSchema } from 'ai'\n\nexport function toAISdkTools(\n tools: readonly Record<string, unknown>[] | undefined,\n): Record<string, { description: string; parameters: unknown }> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const out: Record<string, { description: string; parameters: unknown }> = {}\n\n for (const tool of tools) {\n const name = tool.name as string\n const description = (tool.description ?? '') as string\n // Handle both inputSchema (ModelToolDefinition) and input_schema (Anthropic format).\n const schema = (tool.inputSchema ?? tool.input_schema ?? { type: 'object' }) as Record<\n string,\n unknown\n >\n\n out[name] = {\n description,\n parameters: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n }\n }\n\n return out\n}\n","/**\n * Runtime detection — determines whether the engine is running in\n * Node.js or a restricted runtime (Cloudflare Workers, etc.)\n *\n * Detection strategy:\n * - Node.js has `process.versions.node` set to a version string\n * - Workers have `process` (polyfilled) but `process.versions` is\n * undefined or `process.versions.node` is undefined\n * - As a fallback, probe whether child_process.spawn is functional\n */\n\nexport type RuntimeKind = 'node' | 'worker'\n\nlet cached: RuntimeKind | null = null\n\n/**\n * Detect the runtime. Result is cached after first call.\n */\nexport function detectRuntime(): RuntimeKind {\n if (cached !== null) return cached\n cached = isNodeRuntime() ? 'node' : 'worker'\n return cached\n}\n\nfunction isNodeRuntime(): boolean {\n // Primary check: Node.js always has process.versions.node\n if (\n typeof globalThis.process !== 'undefined' &&\n globalThis.process.versions != null &&\n typeof globalThis.process.versions.node === 'string'\n ) {\n return true\n }\n return false\n}\n\n/**\n * Whether subprocess spawning (Bash, ripgrep, MCP stdio) is available.\n */\nexport function canSpawnProcesses(): boolean {\n return detectRuntime() === 'node'\n}\n\n/**\n * Whether process lifecycle hooks (process.on('exit')) are available.\n */\nexport function hasProcessLifecycle(): boolean {\n return (\n typeof process !== 'undefined' &&\n typeof process.on === 'function' &&\n typeof process.removeListener === 'function' &&\n detectRuntime() === 'node'\n )\n}\n","/**\n * Capability stub — replaces a Node-only tool with a placeholder that\n * returns a structured `isError` result when invoked in a runtime that\n * can't execute it (e.g. Cloudflare Workers for Bash / stdio MCP).\n *\n * The stub preserves the original tool's name and description so the\n * model still sees the tool in its toolset and can decide whether to\n * call it. When called, the stub returns a clear message naming the\n * tool and pointing at the runner-handoff escape hatch (Plan 019).\n *\n * In async runs with `config.runner` configured, the agent loop\n * intercepts stub invocations BEFORE they execute and pauses the run\n * with `pauseReason: 'handoff_to_runner'` so a Node-side runner can\n * resume it. In sync runs (or async runs with no runner configured),\n * the stub's `execute` actually runs and the model adapts its answer.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from './contract.js'\n\n/** Accept any input shape — the stub errors regardless. */\nconst anyInput = z.unknown()\n\n/**\n * Build a stub tool that mirrors `original.name` and `original.description`\n * but returns an `isError` result when invoked. Used by the engine when\n * a tool declares `requiresNode: true` and `canSpawnProcesses()` is false.\n */\nexport function capabilityStub(original: Pick<Tool, 'name' | 'description'>): Tool {\n return defineTool({\n name: original.name,\n description: original.description,\n inputSchema: anyInput,\n isCapabilityStub: true,\n execute: async () => ({\n isError: true,\n content:\n `Tool \"${original.name}\" requires Node runtime and cannot execute ` +\n `in this environment. To use this tool, run async via engine.start() ` +\n `with config.runner configured so the run can hand off to a Node ` +\n `runner. See README §\"Runner contract\" for setup.`,\n metadata: { capabilityMissing: original.name },\n }),\n })\n}\n\n/**\n * Convenience: given a tool, return the real tool when the runtime can\n * execute it, otherwise a capability stub standing in for it. Callers\n * that already know the spawn-availability flag (e.g. engine.ts which\n * caches it) pass it directly instead of re-probing.\n */\nexport function withCapabilityCheck(tool: Tool, spawnAvailable: boolean): Tool {\n if (tool.requiresNode === true && !spawnAvailable) {\n return capabilityStub(tool)\n }\n return tool\n}\n","/**\n * SubagentRegistry — tracks parent→child relationships across a single\n * `engine.run()`. Mints unique `agentId`s, computes spawn depth, and\n * enforces `maxDepth` so a runaway loop can't recursively spawn forever.\n *\n * The registry's lifetime is one engine run. A fresh instance is built\n * inside `engine.run()` and shared with every Agent tool invocation\n * during that run, including children that themselves spawn grandchildren.\n *\n * Tracking is in-memory only. We don't persist parent→child relationships\n * to the transcript here — that's the runner's job, which writes\n * `subagent_spawn` and `subagent_done` entries to the parent's transcript.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\n\nexport interface SubagentRegistryOptions {\n /** Maximum spawn depth. Depth 1 = a direct child of the root run. */\n readonly maxDepth: number\n}\n\nexport interface SpawnResult {\n readonly agentId: string\n readonly depth: number\n}\n\n/** Result from a background agent, stored on completion. */\nexport interface BackgroundAgentResult {\n readonly agentId: string\n readonly output: string\n readonly isError: boolean\n readonly description?: string\n}\n\ninterface RegisteredAgent {\n readonly parentId: string | null\n readonly depth: number\n name?: string\n status: 'running' | 'stopped' | 'completed'\n pendingMessages: string[]\n backgroundResult?: BackgroundAgentResult\n isBackground?: boolean\n /** Tracked Promise for background agents — enables draining before pause. */\n backgroundPromise?: Promise<void>\n}\n\n/** Serialized form for persistence alongside transcripts. */\nexport interface SerializedAgent {\n readonly agentId: string\n readonly parentId: string | null\n readonly depth: number\n readonly name?: string\n readonly status: 'running' | 'stopped' | 'completed'\n}\n\nexport class SubagentRegistry {\n private readonly maxDepth: number\n private readonly agents = new Map<string, RegisteredAgent>()\n\n constructor(options: SubagentRegistryOptions) {\n if (!Number.isInteger(options.maxDepth) || options.maxDepth < 1) {\n throw new Error('SubagentRegistry: maxDepth must be a positive integer')\n }\n this.maxDepth = options.maxDepth\n }\n\n /**\n * Mint a new subagent under `parentAgentId` (null = direct child of\n * the root run). Throws if the resulting depth would exceed `maxDepth`.\n */\n spawn(parentAgentId: string | null): SpawnResult {\n const parentDepth = parentAgentId === null ? 0 : this.requireAgent(parentAgentId).depth\n const depth = parentDepth + 1\n if (depth > this.maxDepth) {\n throw new Error(`Subagent depth limit exceeded: ${depth} > maxDepth ${this.maxDepth}`)\n }\n const agentId = `agent_${randomUUID()}`\n this.agents.set(agentId, {\n parentId: parentAgentId,\n depth,\n status: 'running',\n pendingMessages: [],\n })\n return { agentId, depth }\n }\n\n getDepth(agentId: string): number {\n return this.requireAgent(agentId).depth\n }\n\n getParent(agentId: string): string | null {\n return this.requireAgent(agentId).parentId\n }\n\n count(): number {\n return this.agents.size\n }\n\n // ---------- name registry ----------\n\n /** Set a human-readable name for routing (e.g. subagent_type or task description). */\n setName(agentId: string, name: string): void {\n this.requireAgent(agentId).name = name\n }\n\n /** Find an agent by its human-readable name. Returns the first match. */\n findByName(name: string): string | undefined {\n for (const [id, entry] of this.agents) {\n if (entry.name === name) return id\n }\n return undefined\n }\n\n // ---------- status ----------\n\n setStatus(agentId: string, status: 'running' | 'stopped' | 'completed'): void {\n this.requireAgent(agentId).status = status\n }\n\n getStatus(agentId: string): 'running' | 'stopped' | 'completed' {\n return this.requireAgent(agentId).status\n }\n\n // ---------- message queue (for SendMessage) ----------\n\n /** Queue a message for a running agent. */\n queueMessage(agentId: string, message: string): void {\n this.requireAgent(agentId).pendingMessages.push(message)\n }\n\n /** Drain all pending messages. Returns empty array if none. */\n drainMessages(agentId: string): string[] {\n const agent = this.requireAgent(agentId)\n const msgs = agent.pendingMessages.splice(0)\n return msgs\n }\n\n // ---------- background agents ----------\n\n /** Mark an agent as background (fire-and-forget). */\n setBackground(agentId: string): void {\n this.requireAgent(agentId).isBackground = true\n }\n\n /** Track a background agent's Promise for drain-before-pause. */\n setBackgroundPromise(agentId: string, promise: Promise<void>): void {\n this.requireAgent(agentId).backgroundPromise = promise\n }\n\n /** Store a background agent's result on completion. */\n setBackgroundResult(agentId: string, result: BackgroundAgentResult): void {\n this.requireAgent(agentId).backgroundResult = result\n }\n\n /**\n * Drain all completed background agent results. Returns them and\n * clears the stored results so they're only delivered once.\n * Called at the top of each turn in agentLoop.\n */\n drainCompletedBackgroundResults(): BackgroundAgentResult[] {\n const results: BackgroundAgentResult[] = []\n for (const [, entry] of this.agents) {\n if (entry.isBackground && entry.backgroundResult) {\n results.push(entry.backgroundResult)\n delete entry.backgroundResult\n }\n }\n return results\n }\n\n /**\n * Wait for all running background agents to complete (with timeout).\n * Called before pause to drain in-flight work. Returns results from\n * agents that finished within the timeout.\n */\n async awaitBackgroundAgents(timeoutMs = 10_000): Promise<BackgroundAgentResult[]> {\n const pending: Promise<void>[] = []\n for (const [, entry] of this.agents) {\n if (entry.isBackground && entry.status === 'running' && entry.backgroundPromise) {\n pending.push(entry.backgroundPromise)\n }\n }\n if (pending.length === 0) return this.drainCompletedBackgroundResults()\n\n // Race all pending against a timeout\n await Promise.race([\n Promise.allSettled(pending),\n new Promise<void>((r) => setTimeout(r, timeoutMs)),\n ])\n\n return this.drainCompletedBackgroundResults()\n }\n\n // ---------- persistence ----------\n\n /** Serialize all agents for sidecar persistence. */\n toJSON(): SerializedAgent[] {\n const out: SerializedAgent[] = []\n for (const [agentId, entry] of this.agents) {\n out.push({\n agentId,\n parentId: entry.parentId,\n depth: entry.depth,\n ...(entry.name !== undefined ? { name: entry.name } : {}),\n status: entry.status,\n })\n }\n return out\n }\n\n /** Rebuild registry from serialized data (e.g. on resume). */\n static fromJSON(data: SerializedAgent[], maxDepth: number): SubagentRegistry {\n const reg = new SubagentRegistry({ maxDepth })\n for (const entry of data) {\n reg.agents.set(entry.agentId, {\n parentId: entry.parentId,\n depth: entry.depth,\n ...(entry.name !== undefined ? { name: entry.name } : {}),\n status: entry.status,\n pendingMessages: [],\n })\n }\n return reg\n }\n\n private requireAgent(agentId: string): RegisteredAgent {\n const a = this.agents.get(agentId)\n if (!a) throw new Error(`SubagentRegistry: unknown agentId \"${agentId}\"`)\n return a\n }\n}\n","/**\n * Cross-runtime UUID v4 generator.\n *\n * Uses `crypto.randomUUID()` which is available in:\n * - Node.js 19+ (global `crypto`)\n * - Cloudflare Workers (Web Crypto API)\n * - Deno, Bun, modern browsers\n *\n * Falls back to `node:crypto` for older Node.js versions.\n * Never crashes on Workers — no top-level `node:crypto` import.\n */\n\nlet _randomUUID: () => string\n\nif (typeof globalThis.crypto?.randomUUID === 'function') {\n // Web Crypto API — works everywhere (Node 19+, Workers, Deno, Bun)\n _randomUUID = () => globalThis.crypto.randomUUID()\n} else {\n // Fallback for older Node.js — lazy import\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeCrypto = require('node:crypto') as { randomUUID: () => string }\n _randomUUID = nodeCrypto.randomUUID\n } catch {\n // Last resort — manual UUID v4\n _randomUUID = () => {\n const bytes = new Uint8Array(16)\n // Use whatever crypto is available\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256)\n }\n // Set version (4) and variant (10xx)\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n }\n }\n}\n\nexport const randomUUID = _randomUUID\n","/**\n * Agent tool — lets the parent assistant spawn a child agent.\n *\n * The Agent tool is a closure factory that captures the parent's\n * subsystems (storage, API client, registry, subagent registry,\n * config) at engine.run() time. When the parent calls it via the\n * usual tool dispatch mechanism, the closure runs `runAgent` to drive\n * a child loop and returns the child's final answer as the\n * tool_result content.\n *\n * Depth and uniqueness are enforced via `SubagentRegistry`. If the\n * spawn would exceed `maxSubagentDepth`, the tool returns an error\n * result instead of throwing — the parent assistant can read the\n * error and adapt.\n *\n * The factory's `parentAgentId` parameter is null at the top level\n * (root run) and set to the parent's agentId for nested invocations.\n */\n\nimport { z } from 'zod'\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { SubagentRegistry } from '../subagent/registry.js'\nimport { runAgent, type RunAgentResult } from '../subagent/runner.js'\nimport { isInForkChild, buildForkedMessages } from '../subagent/fork.js'\nimport type { FlushPolicy } from '../transcript/writer.js'\nimport { SubagentPausedError } from '../engine/errors.js'\nimport type { GateBeforeTool } from '../engine/agentLoop.js'\nimport { defineTool, type Tool, type ToolRegistry, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n description: z.string().min(1),\n subagent_type: z.string().optional(),\n run_in_background: z.boolean().optional(),\n})\n\n/**\n * A subagent definition the parent can dispatch to via `Agent({ subagent_type })`.\n *\n * `systemPrompt` overrides the parent's system prompt when the child runs.\n * Leave it undefined to inherit the parent's prompt — which is what the\n * `'general-purpose'` builtin does.\n */\nexport interface AgentDefinition {\n readonly name: string\n readonly description: string\n readonly systemPrompt?: string\n /**\n * When true, marks this agent as safe for parallel execution\n * alongside other readOnly agents. The Agent tool uses this via\n * `isConcurrencySafe` so the batch dispatcher can run multiple\n * research agents concurrently. Default: false.\n */\n readonly readOnly?: boolean\n}\n\nexport interface AgentToolOptions {\n /** Storage adapter the child writes its transcript through. */\n readonly storage: StorageAdapter\n /** API client the child uses (shared with parent). */\n readonly client: ModelAdapter\n /**\n * Registry passed to the child. Typically the parent's full\n * registry minus the Agent tool itself in v0.1, OR the same\n * registry to allow nested spawning (depth-bounded).\n */\n readonly childRegistry: ToolRegistry\n /** Parent's transcript log path: \"projects/{runId}/nodes/{nodeId}\". */\n readonly parentLogPath: string\n /** Parent's agentId, or null if this is at the root run. */\n readonly parentAgentId: string | null\n /** The shared SubagentRegistry for this run. */\n readonly subagentRegistry: SubagentRegistry\n /** System prompt the child sees. */\n readonly system: string\n /** Per-child execution caps. */\n readonly maxTurns: number\n readonly contextLimit: number\n readonly turnTimeoutMs: number\n /** Transcript flush configuration mirrors the parent's. */\n readonly flushPolicy: FlushPolicy\n readonly idleFlushMs: number\n /** Whether the parent is in coordinator mode — controls result format. */\n readonly coordinatorMode?: boolean\n /**\n * Parent's current message history — needed for fork path.\n * When `subagent_type` is omitted and fork is enabled, the child\n * inherits these messages as context.\n */\n readonly parentMessages?: () => readonly MessageParam[]\n /** Enable fork behavior when subagent_type is omitted. Default: true. */\n readonly enableFork?: boolean\n /**\n * Available subagent definitions. The tool's description surfaces this\n * list to the model, and `execute()` rejects `subagent_type` values\n * not in this set. An empty array throws at construction time.\n */\n readonly agents: ReadonlyArray<AgentDefinition>\n /**\n * When provided, the parent's gate is passed down to every subagent's\n * inner loop. A gate denial inside the child then throws\n * `SubagentPausedError`, which the parent's agentLoop catches and\n * surfaces as its own `paused` result. Only set by engine.ts when\n * `config.hooks.propagateGateToSubagents === true`.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /**\n * Plan 021 — when set, every subagent spawned by this tool inherits\n * offload behaviour and rebuilds its own FetchData bound to the\n * child's log path.\n */\n readonly toolResultOffload?: import('../engine/toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n}\n\nexport function createAgentTool(options: AgentToolOptions): Tool<typeof inputSchema> {\n if (options.agents.length === 0) {\n throw new Error(\n 'createAgentTool: at least one agent definition is required (check config.agents.builtins + agents.customPath)',\n )\n }\n // Dedup by name; later entries win (customPath agents override builtins).\n const byName = new Map<string, AgentDefinition>()\n for (const a of options.agents) byName.set(a.name, a)\n const agentList = Array.from(byName.values())\n const defaultAgent = agentList[0]!\n\n // Surface available agents to the model via the tool description.\n const agentCatalogue = agentList.map((a) => ` - ${a.name}: ${a.description}`).join('\\n')\n const description =\n `Spawn a subagent to handle a focused task. Returns the subagent's final answer.\\n` +\n `Available subagent_type values:\\n${agentCatalogue}\\n` +\n `If omitted, defaults to \"${defaultAgent.name}\".`\n\n return defineTool({\n name: 'Agent',\n description,\n inputSchema,\n isConcurrencySafe: (input: unknown) => {\n const typed = input as { subagent_type?: string } | undefined\n const typeName = typed?.subagent_type ?? defaultAgent.name\n const agentDef = byName.get(typeName)\n return agentDef?.readOnly === true\n },\n execute: async ({\n description: taskDescription,\n subagent_type,\n run_in_background,\n }): Promise<ToolResult> => {\n // Fork path — when subagent_type is omitted and fork is enabled,\n // child inherits parent's full message context. Ported from\n // La-Machina's forkSubagent.ts.\n const forkEnabled = options.enableFork !== false\n const parentMsgs = options.parentMessages?.() ?? []\n if (\n subagent_type === undefined &&\n forkEnabled &&\n !options.coordinatorMode &&\n parentMsgs.length > 0 &&\n !isInForkChild(parentMsgs)\n ) {\n let spawn: ReturnType<SubagentRegistry['spawn']>\n try {\n spawn = options.subagentRegistry.spawn(options.parentAgentId)\n } catch (err) {\n return { content: `Cannot spawn fork: ${(err as Error).message}`, isError: true }\n }\n options.subagentRegistry.setName(spawn.agentId, `fork-${taskDescription.slice(0, 40)}`)\n\n // Get last assistant content for placeholder building\n const lastAssistant = [...parentMsgs].reverse().find((m) => m.role === 'assistant')\n const assistantContent = lastAssistant\n ? Array.isArray(lastAssistant.content)\n ? lastAssistant.content\n : []\n : []\n const forkedMsgs = buildForkedMessages(taskDescription, assistantContent)\n\n const result = await runAgent({\n agentId: spawn.agentId,\n description: taskDescription,\n storage: options.storage,\n client: options.client,\n registry: options.childRegistry,\n parentLogPath: options.parentLogPath,\n system: options.system, // inherit parent's system prompt\n maxTurns: options.maxTurns,\n contextLimit: options.contextLimit,\n turnTimeoutMs: options.turnTimeoutMs,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n // Fork: prepend parent messages + forked messages\n prependMessages: [...parentMsgs, ...forkedMsgs],\n ...(options.gateBeforeTool !== undefined\n ? { gateBeforeTool: options.gateBeforeTool }\n : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n })\n\n // Fork path doesn't have a tool_use_id (no subagent_type). Pass\n // the fork agentId as a stand-in so the pause-propagation error\n // still carries identity for observability.\n handlePausedResult(result, spawn.agentId, 'fork')\n const t = result as Extract<RunAgentResult, { kind: 'terminal' }>\n options.subagentRegistry.setStatus(spawn.agentId, t.isError ? 'stopped' : 'completed')\n return {\n content: t.output,\n ...(t.isError ? { isError: true } : {}),\n metadata: {\n agentId: spawn.agentId,\n fork: true,\n depth: spawn.depth,\n turns: t.turns,\n tokensUsed: t.tokensUsed,\n },\n }\n }\n\n // Normal agent path\n const typeName = subagent_type ?? defaultAgent.name\n const agentDef = byName.get(typeName)\n if (!agentDef) {\n return {\n content: `Unknown subagent_type \"${typeName}\". Available types: ${agentList.map((a) => a.name).join(', ')}.`,\n isError: true,\n }\n }\n\n let spawn: ReturnType<SubagentRegistry['spawn']>\n try {\n spawn = options.subagentRegistry.spawn(options.parentAgentId)\n } catch (err) {\n return {\n content: `Cannot spawn subagent: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Register the agent's name for SendMessage routing\n options.subagentRegistry.setName(spawn.agentId, typeName || taskDescription.slice(0, 60))\n\n const childSystem = agentDef.systemPrompt ?? options.system\n\n const runOpts = {\n agentId: spawn.agentId,\n description: taskDescription,\n storage: options.storage,\n client: options.client,\n registry: options.childRegistry,\n parentLogPath: options.parentLogPath,\n system: childSystem,\n maxTurns: options.maxTurns,\n contextLimit: options.contextLimit,\n turnTimeoutMs: options.turnTimeoutMs,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n ...(options.gateBeforeTool !== undefined ? { gateBeforeTool: options.gateBeforeTool } : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n }\n\n // Background path — fire-and-forget, return immediately.\n // Ported from La-Machina's async_launched pattern.\n const shouldRunAsync = run_in_background === true || options.coordinatorMode === true\n if (shouldRunAsync) {\n options.subagentRegistry.setBackground(spawn.agentId)\n\n // Fire-and-forget — don't await. Result stored in registry.\n // Promise tracked for drain-before-pause. Background agents do\n // NOT participate in gate propagation — their pause would be\n // invisible to the parent anyway (parent already moved on).\n const bgPromise = runAgent(runOpts)\n .then((result) => {\n // Background agents that \"pause\" are treated as stopped —\n // there's nobody waiting to observe the pause.\n if (result.kind !== 'terminal') {\n options.subagentRegistry.setStatus(spawn.agentId, 'stopped')\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: `Background agent paused mid-execution (pause not supported for async).`,\n isError: true,\n description: taskDescription,\n })\n return\n }\n options.subagentRegistry.setStatus(\n spawn.agentId,\n result.isError ? 'stopped' : 'completed',\n )\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: result.output,\n isError: result.isError,\n description: taskDescription,\n })\n })\n .catch((err) => {\n options.subagentRegistry.setStatus(spawn.agentId, 'stopped')\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: `Agent crashed: ${(err as Error).message}`,\n isError: true,\n description: taskDescription,\n })\n })\n options.subagentRegistry.setBackgroundPromise(spawn.agentId, bgPromise)\n\n return {\n content:\n `Async agent launched.\\nagentId: ${spawn.agentId}\\n` +\n `The agent is working in the background. You will be notified when it completes.\\n` +\n `Use SendMessage with to: '${spawn.agentId}' to communicate with this agent.`,\n metadata: {\n agentId: spawn.agentId,\n subagent_type: typeName,\n status: 'async_launched',\n depth: spawn.depth,\n },\n }\n }\n\n // Synchronous path — block until child finishes\n const result = await runAgent(runOpts)\n\n // Gate propagation: a paused child bubbles up as a throw.\n // toolUseId is not directly accessible here; encode identity as\n // `${spawn.agentId}/${typeName}` so the parent snapshot can\n // surface which subagent blocked.\n handlePausedResult(result, spawn.agentId, typeName)\n const t = result as Extract<RunAgentResult, { kind: 'terminal' }>\n\n // Update registry status\n options.subagentRegistry.setStatus(spawn.agentId, t.isError ? 'stopped' : 'completed')\n\n // In coordinator mode, wrap the result in <task-notification> XML\n // so the coordinator can reliably parse status/summary/result.\n // Ported from La-Machina's coordinatorMode.ts.\n const content = options.coordinatorMode\n ? formatTaskNotification(spawn.agentId, taskDescription, t)\n : t.output\n\n return {\n content,\n ...(t.isError ? { isError: true } : {}),\n metadata: {\n agentId: t.agentId,\n subagent_type: typeName,\n depth: spawn.depth,\n turns: t.turns,\n tokensUsed: t.tokensUsed,\n },\n }\n },\n })\n}\n\nfunction formatTaskNotification(\n agentId: string,\n description: string,\n result: { output: string; isError?: boolean; turns: number; tokensUsed: unknown },\n): string {\n const status = result.isError ? 'failed' : 'completed'\n const summary = result.isError\n ? `Agent \"${description}\" failed`\n : `Agent \"${description}\" completed`\n return [\n '<task-notification>',\n `<task-id>${agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>${summary}</summary>`,\n `<result>${result.output}</result>`,\n `<usage>`,\n ` <turns>${result.turns}</turns>`,\n `</usage>`,\n '</task-notification>',\n ].join('\\n')\n}\n\n/**\n * Throw SubagentPausedError when `result.kind === 'paused'` so the\n * parent's agentLoop catches it and produces its own `paused` result.\n * No-op for terminal results.\n */\nfunction handlePausedResult(result: RunAgentResult, agentId: string, subagentType: string): void {\n if (result.kind === 'paused') {\n throw new SubagentPausedError({\n childSnapshot: result.childSnapshot,\n parentToolUseId: agentId,\n subagentType,\n })\n }\n}\n","/**\n * runAgent — headless execution of a child agent.\n *\n * Builds an isolated `RunContext` and `TranscriptWriter` for the child,\n * dispatches `agentLoop`, and returns the child's final output as a\n * string suitable for the parent's `tool_result` block.\n *\n * Isolation guarantees:\n * - The child's transcript shards live under\n * `{parent-log-path}/subagents/{agentId}/`, completely separate from\n * the parent's transcript files.\n * - The child has its own `RunContext`, so its message history, turn\n * counter, and token usage are independent.\n * - The child shares the parent's storage adapter, API client, and\n * tool registry — those are stateless.\n *\n * The function never throws. Errors become `{ output, isError: true }`\n * results that the Agent tool surfaces to the parent as a tool_result\n * with `isError: true`.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport { agentLoop } from '../engine/agentLoop.js'\nimport { RunContext } from '../engine/runContext.js'\nimport { ToolExecutor } from '../engine/toolRuntime.js'\nimport type { ToolExecutorHooks } from '../engine/toolRuntime.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { Tool, ToolRegistry } from '../tools/contract.js'\nimport { TranscriptWriter, type FlushPolicy } from '../transcript/writer.js'\n\nexport interface RunAgentOptions {\n readonly agentId: string\n readonly description: string\n readonly storage: StorageAdapter\n readonly client: ModelAdapter\n readonly registry: ToolRegistry\n readonly parentLogPath: string\n readonly system: string\n readonly maxTurns: number\n readonly contextLimit: number\n readonly turnTimeoutMs: number\n readonly flushPolicy: FlushPolicy\n readonly idleFlushMs: number\n readonly hooks?: ToolExecutorHooks\n /**\n * Messages to prepend to the child's context before the task message.\n * Used by fork subagent to pass parent's full conversation history.\n */\n readonly prependMessages?: readonly MessageParam[]\n /**\n * Optional gate callback propagated from the parent engine. When the\n * child's agentLoop is about to dispatch a tool, this runs first. A\n * denial pauses the child, surfaced to the parent via the paused\n * RunAgentResult variant.\n */\n readonly gateBeforeTool?: import('../engine/agentLoop.js').GateBeforeTool\n /**\n * Plan 021 — when set, the child inherits offload behaviour AND\n * gets its own `FetchData` registered on the shared registry\n * scoped to the child's log path. The parent's `FetchData` (if\n * any) is replaced for the duration of this subagent run so the\n * child can't read the parent's offloaded refs.\n */\n readonly toolResultOffload?: import('../engine/toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n}\n\nexport type RunAgentResult =\n | {\n readonly kind: 'terminal'\n readonly agentId: string\n readonly output: string\n readonly isError: boolean\n readonly turns: number\n readonly tokensUsed: { input: number; output: number }\n }\n | {\n readonly kind: 'paused'\n readonly agentId: string\n readonly childSnapshot: import('../engine/types.js').RunSnapshot\n readonly turns: number\n readonly tokensUsed: { input: number; output: number }\n }\n\nexport async function runAgent(options: RunAgentOptions): Promise<RunAgentResult> {\n const childLogPath = `${options.parentLogPath}/subagents/${options.agentId}`\n\n // Plan 021 — when offload is enabled, swap in a child-scoped\n // FetchData so the child can only rehydrate its OWN offloaded\n // refs. We unregister any parent-scoped FetchData first (the\n // parent registry may have one) and restore it in `finally`.\n let restorePrevFetchData: (() => void) | null = null\n if (options.toolResultOffload !== undefined && options.toolResultOffload.enabled) {\n const { createFetchDataTool } = await import('../tools/fetchData.js')\n const existing = options.registry.get('FetchData')\n options.registry.unregister('FetchData')\n options.registry.register(\n createFetchDataTool({ storage: options.storage, logPath: childLogPath }),\n )\n restorePrevFetchData = () => {\n options.registry.unregister('FetchData')\n if (existing !== undefined) options.registry.register(existing)\n }\n }\n\n const writer = new TranscriptWriter({\n storage: options.storage,\n logPath: childLogPath,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n })\n\n const ctx = new RunContext({\n runId: options.agentId,\n nodeId: options.agentId,\n writer,\n maxTurns: options.maxTurns,\n })\n\n const executor = new ToolExecutor({\n registry: options.registry,\n timeoutMs: options.turnTimeoutMs,\n ...(options.hooks !== undefined ? { hooks: options.hooks } : {}),\n })\n\n try {\n await writer.setStatus('running')\n\n // Fork path: prepend parent's message history so the child\n // sees the full conversation context before its task.\n if (options.prependMessages && options.prependMessages.length > 0) {\n ctx.rehydrate({\n messages: options.prependMessages,\n turnCount: 0,\n tokensUsed: { input: 0, output: 0 },\n lastUuid: null,\n })\n }\n\n await ctx.addUserMessage(options.description)\n\n const tools: Tool[] = options.registry.list()\n const result = await agentLoop({\n context: ctx,\n client: options.client,\n executor,\n tools,\n system: options.system,\n contextLimit: options.contextLimit,\n registry: options.registry,\n // Propagate parent's gate + storage into the child loop when set.\n // Without `storage`, a gate denial would fail the child instead of\n // pausing it, so both must travel together.\n ...(options.gateBeforeTool !== undefined\n ? { gateBeforeTool: options.gateBeforeTool, storage: options.storage }\n : {}),\n // Plan 021 — the child needs its own storage + offload config\n // so its own large tool results get offloaded into\n // `childLogPath/toolResults/...`, not the parent's folder.\n ...(options.toolResultOffload !== undefined\n ? {\n storage: options.storage,\n toolResultOffload: options.toolResultOffload,\n offloadLogPath: childLogPath,\n }\n : {}),\n })\n\n if (result.status === 'done') {\n await writer.setStatus('done')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: result.output,\n isError: false,\n turns: result.turns,\n tokensUsed: { input: result.tokensUsed.input, output: result.tokensUsed.output },\n }\n }\n\n if (result.status === 'paused') {\n await writer.setStatus('paused')\n return {\n kind: 'paused',\n agentId: options.agentId,\n childSnapshot: result.snapshot,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n }\n\n await writer.setStatus('failed')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: `Subagent failed: ${result.error.message}`,\n isError: true,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n } catch (err) {\n await writer.setStatus('failed')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: `Subagent crashed: ${(err as Error).message}`,\n isError: true,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n } finally {\n // Write agent metadata sidecar for registry persistence on resume\n try {\n await options.storage.writeFile(\n `${childLogPath}/agent-meta.json`,\n JSON.stringify({\n agentId: options.agentId,\n parentLogPath: options.parentLogPath,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }),\n )\n } catch {\n // Best-effort — don't let metadata write failure crash the run\n }\n await writer.close()\n // Plan 021 — restore any parent-scoped FetchData we replaced\n // for the duration of this subagent's run.\n restorePrevFetchData?.()\n }\n}\n","/**\n * agentLoop — the heart of the engine. Drives turns until the run\n * completes, fails, or hits a limit.\n *\n * Per turn:\n * 1. Bail out if `ctx.shouldContinue()` is false (max turns).\n * 2. Optionally compact messages if the context window is full.\n * 3. Convert our `Tool[]` registry shape into Anthropic's `Tool[]`\n * JSON-schema shape.\n * 4. Call `client.streamMessage(...)`. Consume the normalized event\n * stream into:\n * - text blocks (joined into the assistant's text reply)\n * - tool_use blocks (dispatched after the stream ends)\n * - the terminal `message_stop` event (stop reason + usage)\n * 5. Append the assembled assistant message to context (which writes\n * a transcript entry).\n * 6. If there are tool calls: dispatch each through the executor,\n * append each tool_result to context, and loop.\n * 7. If `stopReason === 'end_turn'` and there were no tool calls:\n * finish the run with status `'done'`.\n *\n * Errors during streaming or unhandled stop reasons surface as\n * `{ status: 'failed' }` results — the loop never throws.\n */\n\nimport type { Tool as AnthropicTool, ContentBlockParam } from '@anthropic-ai/sdk/resources/messages'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { ModelAdapter, NormalizedEvent, StopReason } from '../model/adapter.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { writeSnapshot } from '../transcript/snapshot.js'\nimport { maybeOffloadToolResult } from './toolResultOffload.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { dispatchHooks } from '../hooks/dispatch.js'\nimport type { PostTurnHook, PreTurnHook, StopHook, StopHookResult } from '../hooks/types.js'\nimport {\n ApiError,\n EngineError,\n RateLimitError,\n RunTimeoutError,\n SubagentPausedError,\n} from './errors.js'\nimport { normalizeMessages } from './normalizeMessages.js'\nimport { compactIfNeeded } from '../compact/compactor.js'\nimport type { ResolvedCompactionConfig } from '../compact/types.js'\nimport type { RunContext } from './runContext.js'\nimport type { ToolExecutor } from './toolRuntime.js'\nimport { StreamingToolExecutor } from './streamingExecutor.js'\nimport type { Tool } from '../tools/contract.js'\nimport type { ToolRegistry } from '../tools/contract.js'\nimport type { PauseReason, RunSnapshot, TranscriptLocation } from './types.js'\n\n/**\n * Result of `gateBeforeTool` callback. `allow: true` runs the tool;\n * `allow: false` pauses the run with the given reason. The pending\n * tool call is captured in the snapshot.\n */\nexport interface GateDecision {\n readonly allow: boolean\n readonly reason?: string\n}\n\nexport type GateBeforeTool = (\n toolName: string,\n input: unknown,\n) => GateDecision | Promise<GateDecision>\n\nexport interface AgentLoopOptions {\n readonly context: RunContext\n readonly client: ModelAdapter\n readonly executor: ToolExecutor\n readonly tools: ReadonlyArray<Tool>\n readonly system: string\n readonly contextLimit: number\n readonly compactionConfig?: ResolvedCompactionConfig | undefined\n readonly transcriptLocation?: TranscriptLocation\n /**\n * Optional storage adapter for writing the snapshot.json sidecar\n * when the loop pauses. Required if pause is wanted; if omitted,\n * gateBeforeTool denies will surface as failed runs instead.\n */\n readonly storage?: StorageAdapter\n /**\n * Pre-tool gate. Called before EVERY tool dispatch. Return\n * `{ allow: false }` to pause the run with the pending tool\n * captured in the snapshot. Default = always allow.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /** Hooks fired before each turn's API call. */\n readonly preTurnHooks?: ReadonlyArray<PreTurnHook>\n /** Hooks fired after each turn's tool dispatch completes. */\n readonly postTurnHooks?: ReadonlyArray<PostTurnHook>\n /**\n * Optional abort signal for run-level timeout. When aborted, the loop\n * returns `failed(RunTimeoutError)` at the next checkpoint (top of the\n * turn loop or after a tool dispatch).\n */\n readonly runSignal?: AbortSignal\n /** Run-level timeout in milliseconds — carried for error messages. */\n readonly runTimeoutMs?: number\n /** Tool registry for concurrency-safety lookup during batch dispatch. */\n readonly registry?: ToolRegistry\n /** Max concurrent tool executions for safe batches. Default: 10. */\n readonly maxToolConcurrency?: number\n /**\n * Subagent registry — when set, completed background agents are\n * drained at the start of each turn and their results injected as\n * `<task-notification>` user messages.\n */\n readonly subagentRegistry?: import('../subagent/registry.js').SubagentRegistry\n /**\n * Token budget. When total tokens (input + output) exceed this,\n * the run stops gracefully. Ported from La-Machina's task_budget.\n */\n readonly tokenBudget?: number\n /**\n * Stop hooks — fire after each turn. Can return `{ preventContinuation: true }`\n * to stop the run gracefully. Ported from La-Machina's executeStopHooks().\n */\n readonly stopHooks?: ReadonlyArray<StopHook>\n /**\n * Progress callback fired at turn boundaries. Receives a `LoopProgress`\n * snapshot with current activity, turn count, tokens, and last tool\n * name. Used by `engine.start()` to keep `state.json` warm so\n * `getStatus()` returns non-zero progress during long runs.\n *\n * Errors from the callback are swallowed — progress reporting is\n * best-effort and must not break the loop.\n */\n readonly onProgress?: (progress: LoopProgress) => Promise<void> | void\n /**\n * Plan 019 — when true, the loop pauses with reason\n * `'handoff_to_runner'` as soon as a capability-stubbed tool is about\n * to be dispatched, so the async wrapper (`engine.start()` /\n * `resumeAsync()`) can POST `{ runId }` to the configured runner.\n *\n * Sync runs (`engine.run()`) never set this flag — stubs execute\n * normally and the model adapts its answer to the missing capability.\n */\n readonly handoffToRunner?: boolean\n /**\n * Plan 021 — when set, tool results exceeding `thresholdBytes`\n * are written to `{transcript.path}/toolResults/{toolUseId}.json`\n * and replaced in the message context with a short summary that\n * includes the ref. The model rehydrates via `FetchData({ ref })`.\n * Absent / `enabled: false` → all tool results pass through\n * verbatim as before.\n */\n readonly toolResultOffload?: import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n /**\n * Plan 021 — log path where offloaded tool results should be\n * written (`{offloadLogPath}/toolResults/{toolUseId}.json`). When\n * omitted, defaults to the transcript's `path`. Subagent runners\n * pass their `childLogPath` here because subagent transcripts\n * and snapshots live at different paths today.\n */\n readonly offloadLogPath?: string\n}\n\n/**\n * Progress payload fired by `onProgress` at turn boundaries. Maps\n * directly to `RunStateManager.RunProgress` on the engine side.\n */\nexport interface LoopProgress {\n /** Current turn index (1-based). */\n readonly turns: number\n /** Cumulative token usage across all turns so far. */\n readonly tokensUsed: TokenUsage\n /** What the loop is doing right now. */\n readonly currentActivity: 'idle' | 'streaming' | 'tool_dispatch' | 'compacting'\n /** Most recent tool name (when `currentActivity === 'tool_dispatch'`). */\n readonly lastTool?: string\n}\n\nexport type AgentLoopResult =\n | {\n readonly status: 'done'\n readonly output: string\n readonly tokensUsed: TokenUsage\n readonly turns: number\n }\n | {\n readonly status: 'paused'\n readonly snapshot: RunSnapshot\n readonly reason: PauseReason\n }\n | {\n readonly status: 'failed'\n readonly error: Error\n readonly transcript: TranscriptLocation\n }\n\nconst DEFAULT_COMPACTION: ResolvedCompactionConfig = {\n strategy: 'drop-middle',\n threshold: 0.85,\n keepLast: 6,\n summaryMaxTokens: 4096,\n microcompact: false,\n microcompactAgeMs: 300_000,\n}\n\nexport async function agentLoop(options: AgentLoopOptions): Promise<AgentLoopResult> {\n const { context: ctx, client, executor, tools, system, contextLimit } = options\n const compactionConfig = options.compactionConfig ?? DEFAULT_COMPACTION\n const transcript = options.transcriptLocation ?? {\n path: `projects/${ctx.runId}/nodes/${ctx.nodeId}`,\n lastShardIndex: 0,\n }\n\n const anthropicTools = tools.map(toAnthropicTool)\n let lastAssistantText = ''\n\n // Reactive recovery state — ported from La-Machina's query.ts.\n // On max_tokens, three-stage recovery:\n // 1. Escalate cap (8K → 64K) and retry same turn\n // 2. Inject recovery message and re-query (up to 3 attempts)\n // 3. Fail after exhaustion\n const MAX_OUTPUT_TOKENS_RECOVERY_LIMIT = 3\n const ESCALATED_MAX_TOKENS = 64_000\n let recoveryCount = 0\n let maxTokensEscalated = false\n let escalatedMaxTokens: number | undefined\n let compactedThisTurn = false\n\n // API retry state — application-level backoff for 429/500/529.\n const MAX_API_RETRIES = 3\n const BASE_BACKOFF_MS = 1000\n let apiRetryCount = 0\n let consecutive529 = 0\n const MAX_CONSECUTIVE_529 = 5\n\n const fireProgress = async (\n activity: LoopProgress['currentActivity'],\n lastTool?: string,\n ): Promise<void> => {\n if (options.onProgress === undefined) return\n try {\n await options.onProgress({\n turns: ctx.getTurnCount(),\n tokensUsed: ctx.getTokensUsed(),\n currentActivity: activity,\n ...(lastTool !== undefined ? { lastTool } : {}),\n })\n } catch {\n // Progress reporting is best-effort — never break the loop.\n }\n }\n\n for (;;) {\n compactedThisTurn = false\n if (options.runSignal?.aborted === true) {\n return failed(new RunTimeoutError(options.runTimeoutMs ?? 0), transcript)\n }\n if (!ctx.shouldContinue()) {\n return failed(new EngineError('ERR_MAX_TURNS', 'Run exceeded max turns'), transcript)\n }\n\n // Token budget enforcement — stop gracefully when budget exhausted.\n if (options.tokenBudget !== undefined) {\n const used = ctx.getTokensUsed()\n if (used.input + used.output >= options.tokenBudget) {\n return {\n status: 'done',\n output: lastAssistantText || '[Token budget exhausted]',\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n }\n\n // Drain completed background agents — inject their results as\n // task-notification messages so the model sees them.\n if (options.subagentRegistry) {\n const bgResults = options.subagentRegistry.drainCompletedBackgroundResults()\n for (const bg of bgResults) {\n const status = bg.isError ? 'failed' : 'completed'\n const notification = [\n '<task-notification>',\n `<task-id>${bg.agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>Background agent \"${bg.description ?? bg.agentId}\" ${status}</summary>`,\n `<result>${bg.output}</result>`,\n '</task-notification>',\n ].join('\\n')\n await ctx.addUserMessage(notification)\n }\n }\n\n // preTurn hooks\n if (options.preTurnHooks && options.preTurnHooks.length > 0) {\n await dispatchHooks(options.preTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount(),\n messageCount: ctx.getMessages().length,\n })\n }\n\n // Compact if needed — uses the configurable compaction system.\n let messages = ctx.getMessages()\n // Fire a 'compacting' progress signal only when compaction will actually\n // run; otherwise callers see noise for no-op turns.\n const mightCompact =\n ctx.getTokensUsed().input + ctx.getTokensUsed().output >\n contextLimit * compactionConfig.threshold\n if (mightCompact) await fireProgress('compacting')\n const compactResult = await compactIfNeeded({\n messages,\n usage: ctx.getTokensUsed(),\n contextLimit,\n config: compactionConfig,\n client,\n system,\n })\n if (compactResult.compacted) {\n messages = compactResult.messages\n }\n\n // Streaming — fire progress BEFORE we open the SSE so clients can\n // see \"streaming…\" activity during the longest wait of a turn.\n await fireProgress('streaming')\n\n // Stream this turn\n const textBlocks: string[] = []\n const thinkingBlocks: string[] = []\n const toolCalls: Array<{ id: string; name: string; input: unknown }> = []\n let stopReason: StopReason | null = null\n let turnUsage: TokenUsage = { input: 0, output: 0 }\n\n // Normalize messages before API call — merge consecutive same-role,\n // strip empty blocks. Prevents API 400 errors from malformed sequences.\n const normalizedMessages = normalizeMessages(\n messages as import('@anthropic-ai/sdk/resources/messages').MessageParam[],\n )\n\n try {\n for await (const event of client.streamMessage({\n messages: normalizedMessages as never,\n system,\n tools: anthropicTools as never,\n ...(escalatedMaxTokens !== undefined ? { maxTokens: escalatedMaxTokens } : {}),\n })) {\n const handled = consumeEvent(event)\n if (handled.text !== undefined) textBlocks.push(handled.text)\n if (handled.thinking !== undefined) thinkingBlocks.push(handled.thinking)\n if (handled.toolCall) toolCalls.push(handled.toolCall)\n if (handled.stop) {\n stopReason = handled.stop.reason\n turnUsage = handled.stop.usage\n }\n }\n } catch (err) {\n // 413 prompt-too-long recovery — emergency compact and retry once.\n // Ported from La-Machina's query.ts (lines 1067-1182).\n if (isPromptTooLong(err) && !compactedThisTurn) {\n compactedThisTurn = true\n const emergency = await compactIfNeeded({\n messages: messages as import('@anthropic-ai/sdk/resources/messages').MessageParam[],\n usage: ctx.getTokensUsed(),\n contextLimit: Math.floor(contextLimit * 0.6), // force below threshold\n config: { ...compactionConfig, threshold: 0, keepLast: 4 },\n client,\n system,\n })\n if (emergency.compacted) {\n // Replace context messages with compacted version and retry\n ctx.rehydrate({\n messages: emergency.messages,\n turnCount: ctx.getTurnCount(),\n tokensUsed: ctx.getTokensUsed(),\n lastUuid: ctx.getLastUuid(),\n })\n continue\n }\n }\n\n // Retryable error backoff (429/500/529) — exponential with Retry-After respect.\n if (isRetryable(err) && apiRetryCount < MAX_API_RETRIES) {\n apiRetryCount++\n\n // 529 overload counter — fail fast if API is persistently overloaded\n if (is529Overloaded(err)) {\n consecutive529++\n if (consecutive529 >= MAX_CONSECUTIVE_529) {\n return failed(\n new EngineError(\n 'ERR_API_OVERLOADED',\n `API overloaded (529) ${MAX_CONSECUTIVE_529} consecutive times`,\n ),\n transcript,\n )\n }\n } else {\n consecutive529 = 0\n }\n\n // Backoff: respect Retry-After header, otherwise exponential\n const retryAfter =\n err instanceof RateLimitError && err.retryAfterMs\n ? err.retryAfterMs\n : BASE_BACKOFF_MS * Math.pow(2, apiRetryCount - 1)\n const delay = Math.min(retryAfter, 30_000) // cap at 30s\n await new Promise((r) => setTimeout(r, delay))\n continue // retry the turn\n }\n\n return failed(toError(err), transcript)\n }\n\n ctx.addTokenUsage(turnUsage)\n\n // Build the assistant message and append it to context.\n // Thinking blocks come first (preserved for reasoning chain continuity),\n // then text, then tool_use — same order as La-Machina.\n const assistantContent: ContentBlockParam[] = []\n for (const thinking of thinkingBlocks) {\n if (thinking.length > 0) {\n assistantContent.push({ type: 'thinking', thinking } as unknown as ContentBlockParam)\n }\n }\n for (const text of textBlocks) {\n if (text.length > 0) assistantContent.push({ type: 'text', text })\n }\n for (const tc of toolCalls) {\n assistantContent.push({\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: (tc.input ?? {}) as Record<string, unknown>,\n })\n }\n if (assistantContent.length > 0) {\n await ctx.addAssistantMessage(assistantContent)\n } else if (stopReason !== null) {\n // Empty assistant response — model returned message_stop with no\n // content. Append a synthetic empty text block to prevent transcript\n // gaps and stale lastAssistantText. Ported from La-Machina.\n await ctx.addAssistantMessage([{ type: 'text', text: '' }])\n }\n\n lastAssistantText = textBlocks.join('').trim() || lastAssistantText\n\n // Tool dispatch — batch consecutive concurrency-safe tools for parallel execution\n if (toolCalls.length > 0) {\n // Duplicate tool_use ID detection — model bug, prevent double execution\n const seenIds = new Set<string>()\n const dedupedCalls = toolCalls.filter((call) => {\n if (seenIds.has(call.id)) return false\n seenIds.add(call.id)\n return true\n })\n const toolCallsToDispatch = dedupedCalls\n\n // Gate check: ALL tools must pass gate before any execution\n for (const call of toolCallsToDispatch) {\n if (options.gateBeforeTool) {\n const decision = await options.gateBeforeTool(call.name, call.input)\n if (!decision.allow) {\n const paused = await pauseHere({\n ctx,\n transcript,\n reason: 'gate_required',\n pendingToolCall: {\n toolName: call.name,\n toolUseId: call.id,\n input: call.input,\n calledAt: new Date().toISOString(),\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n return paused\n }\n }\n }\n\n // Plan 019 — runner handoff. When an async wrapper set\n // `handoffToRunner: true`, we pause before dispatching the first\n // capability-stubbed tool in the batch so a Node-side runner can\n // resume the run in its own process. Sync runs leave the flag\n // false and fall through to regular dispatch (the stub executes\n // and returns an isError result the model adapts to).\n if (options.handoffToRunner === true) {\n for (const call of toolCallsToDispatch) {\n const tool = options.registry?.get(call.name)\n if (tool?.isCapabilityStub === true) {\n const paused = await pauseHere({\n ctx,\n transcript,\n reason: 'handoff_to_runner',\n pendingToolCall: {\n toolName: call.name,\n toolUseId: call.id,\n input: call.input,\n calledAt: new Date().toISOString(),\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n return paused\n }\n }\n }\n\n // Tool dispatch — fire progress once before the batch starts,\n // carrying the name of the first tool so `getStatus` shows\n // something like \"tool_dispatch / Read\".\n const firstTool = toolCallsToDispatch[0]?.name\n await fireProgress('tool_dispatch', firstTool)\n\n // StreamingToolExecutor handles concurrency, ordering, and Bash\n // error cascading — ported 1:1 from La-Machina's StreamingToolExecutor.\n const streamExec = new StreamingToolExecutor(executor)\n for (const call of toolCallsToDispatch) {\n const tool = options.registry?.get(call.name)\n const safe = tool?.isConcurrencySafe?.(call.input) ?? false\n streamExec.addTool(call.id, call.name, call.input, safe)\n }\n try {\n for await (const { id, result } of streamExec.results()) {\n // Plan 019 — capability-stub invocations surface a\n // `metadata.capabilityMissing` field; record it so\n // `engine.toResponse()` can emit `meta.capabilitiesMissing`.\n const missing = result.metadata?.capabilityMissing\n if (typeof missing === 'string') {\n ctx.recordCapabilityMissing(missing)\n }\n\n // Plan 021 — offload large tool results. Helper is a\n // pass-through no-op when disabled / below threshold / on\n // error results.\n const call = toolCallsToDispatch.find((c) => c.id === id)\n let contentForTranscript: string\n if (options.toolResultOffload !== undefined && options.storage !== undefined) {\n try {\n contentForTranscript = await maybeOffloadToolResult({\n offloadConfig: options.toolResultOffload,\n storage: options.storage,\n logPath: options.offloadLogPath ?? transcript.path,\n toolUseId: id,\n toolName: call?.name ?? 'unknown',\n toolInput: call?.input,\n rawContent: result.content,\n rawIsError: result.isError === true,\n })\n } catch (err) {\n // Storage write failed mid-offload. Don't silently\n // drop the data — surface the failure to the model so\n // it knows the last tool call's output is unreadable.\n const msg = err instanceof Error ? err.message : String(err)\n contentForTranscript = `[tool-result offload failed: ${msg}] ${result.content.slice(0, 500)}`\n }\n } else {\n contentForTranscript = result.content\n }\n\n await ctx.addToolResult(\n id,\n truncateToolResult(contentForTranscript),\n result.isError === true,\n )\n }\n } catch (err) {\n // Gate propagation — a subagent's own gate denial throws\n // SubagentPausedError. Surface it as the parent's own pause\n // pointing at the Agent tool_use that spawned the child.\n if (err instanceof SubagentPausedError) {\n const parentCall = toolCallsToDispatch.find((c) => c.name === 'Agent')\n const pendingTool =\n parentCall !== undefined\n ? {\n toolName: parentCall.name,\n toolUseId: parentCall.id,\n input: parentCall.input,\n calledAt: new Date().toISOString(),\n }\n : undefined\n return pauseHere({\n ctx,\n transcript,\n reason: 'subagent_gate_required',\n ...(pendingTool !== undefined ? { pendingToolCall: pendingTool } : {}),\n pendingSubagent: {\n subagentType: err.subagentType,\n parentToolUseId: err.parentToolUseId,\n childSnapshot: err.childSnapshot,\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n }\n throw err\n }\n\n // Successful tool dispatch — reset recovery state\n recoveryCount = 0\n maxTokensEscalated = false\n escalatedMaxTokens = undefined\n apiRetryCount = 0\n consecutive529 = 0\n\n await ctx.endTurn()\n // Turn-end progress — clients see turns count advance + activity idle.\n await fireProgress('idle')\n if (options.postTurnHooks && options.postTurnHooks.length > 0) {\n await dispatchHooks(options.postTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n })\n }\n\n // Stop hooks — can prevent continuation after tool dispatch\n if (options.stopHooks && options.stopHooks.length > 0) {\n const stopResult = await runStopHooks(options.stopHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n lastAssistantText,\n toolsCalled: toolCallsToDispatch.map((c) => c.name),\n status: 'tool_use',\n })\n if (stopResult?.preventContinuation) {\n return {\n status: 'done',\n output: lastAssistantText || '[Stopped by stop hook]',\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n }\n\n continue\n }\n\n // No tool calls — terminal turn\n await ctx.endTurn()\n if (options.postTurnHooks && options.postTurnHooks.length > 0) {\n await dispatchHooks(options.postTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n })\n }\n if (stopReason === 'end_turn' || stopReason === 'stop_sequence' || stopReason === null) {\n // Successful turn — reset recovery state\n recoveryCount = 0\n maxTokensEscalated = false\n escalatedMaxTokens = undefined\n apiRetryCount = 0\n consecutive529 = 0\n // Final heartbeat before returning — heartbeat consumers get a\n // clean \"idle\" marker on terminal state.\n await fireProgress('idle')\n return {\n status: 'done',\n output: lastAssistantText,\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n if (stopReason === 'max_tokens') {\n // Stage 1: Escalate max_tokens cap (8K → 64K) and retry\n if (!maxTokensEscalated) {\n maxTokensEscalated = true\n escalatedMaxTokens = ESCALATED_MAX_TOKENS\n continue // re-stream with higher cap — assistant message already appended\n }\n\n // Stage 2: Inject recovery message and re-query (up to 3 attempts)\n if (recoveryCount < MAX_OUTPUT_TOKENS_RECOVERY_LIMIT) {\n recoveryCount++\n escalatedMaxTokens = undefined // reset escalation for next attempt\n await ctx.addUserMessage(\n 'Output token limit hit. Resume directly — no apology, no recap of what you were doing. ' +\n 'Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces.',\n )\n continue // re-query with recovery directive\n }\n\n // Stage 3: Exhaustion — fail after 3 attempts\n return failed(\n new EngineError(\n 'ERR_MAX_TOKENS',\n `max_tokens recovery exhausted after ${MAX_OUTPUT_TOKENS_RECOVERY_LIMIT} attempts`,\n ),\n transcript,\n )\n }\n // Any other stop reason without tool calls\n return failed(\n new EngineError('ERR_UNEXPECTED_STOP', `Unexpected stop reason: ${stopReason}`),\n transcript,\n )\n }\n}\n\ninterface ConsumedEvent {\n text?: string\n thinking?: string\n toolCall?: { id: string; name: string; input: unknown }\n stop?: { reason: StopReason; usage: TokenUsage }\n}\n\nfunction consumeEvent(event: NormalizedEvent): ConsumedEvent {\n if (event.type === 'text') return { text: event.text }\n if (event.type === 'thinking') return { thinking: event.thinking }\n if (event.type === 'tool_use') {\n return { toolCall: { id: event.id, name: event.name, input: event.input } }\n }\n return { stop: { reason: event.stopReason, usage: event.usage } }\n}\n\nfunction toAnthropicTool(tool: Tool): AnthropicTool {\n // MCP-adapted tools carry their native JSON Schema directly; prefer\n // that over running the Zod passthrough schema through zodToJsonSchema,\n // which would produce `{}`.\n if (tool.anthropicSchemaOverride !== undefined) {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.anthropicSchemaOverride as AnthropicTool['input_schema'],\n }\n }\n // zod-to-json-schema's signature accepts ZodSchema; our Tool generic\n // uses ZodTypeAny which is a structural superset, so we cast through\n // unknown rather than chase a more elaborate generic.\n const schema = zodToJsonSchema(tool.inputSchema as Parameters<typeof zodToJsonSchema>[0], {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>\n // Anthropic expects { type, properties, required } directly — strip\n // schema metadata that would otherwise confuse the API.\n const { $schema: _schema, ...inputSchema } = schema\n return {\n name: tool.name,\n description: tool.description,\n input_schema: inputSchema as AnthropicTool['input_schema'],\n }\n}\n\n// ---------- tool batching ----------\n\ninterface ToolBatch {\n concurrent: boolean\n calls: Array<{ id: string; name: string; input: unknown }>\n}\n\n/**\n * Partition tool calls into batches: consecutive concurrency-safe tools\n * are grouped together for parallel execution; each unsafe tool becomes\n * its own serial batch. Mirrors La-Machina's toolOrchestration.ts pattern.\n */\nexport function partitionToolCalls(\n calls: ReadonlyArray<{ id: string; name: string; input: unknown }>,\n registry?: ToolRegistry,\n): ToolBatch[] {\n const batches: ToolBatch[] = []\n for (const call of calls) {\n const tool = registry?.get(call.name)\n const safe = tool?.isConcurrencySafe?.(call.input) ?? false\n const last = batches[batches.length - 1]\n if (safe && last?.concurrent) {\n last.calls.push(call)\n } else {\n batches.push({ concurrent: safe, calls: [call] })\n }\n }\n return batches\n}\n\n// ---------- stop hooks ----------\n\n/**\n * Run stop hooks sequentially. If any returns `{ preventContinuation: true }`,\n * stop processing and return the result. Errors are isolated — a throwing\n * hook does not prevent other hooks from running.\n * Ported from La-Machina's executeStopHooks().\n */\nasync function runStopHooks(\n hooks: ReadonlyArray<StopHook>,\n event: import('../hooks/types.js').StopHookEvent,\n): Promise<StopHookResult | null> {\n for (const hook of hooks) {\n try {\n const result = await hook(event)\n if (result?.preventContinuation) return result\n } catch {\n // Hook errors are isolated — never abort the run\n }\n }\n return null\n}\n\n// ---------- retryable error detection ----------\n\n/** Check if an error is retryable (429 rate limit, 500 server error, 529 overloaded). */\nfunction isRetryable(err: unknown): boolean {\n if (err instanceof RateLimitError) return true\n if (err instanceof ApiError) {\n const s = err.status\n if (s === 429 || s === 500 || s === 502 || s === 503 || s === 529) return true\n }\n if (!(err instanceof Error)) return false\n const msg = err.message.toLowerCase()\n return (\n msg.includes('429') ||\n msg.includes('rate_limit') ||\n msg.includes('rate limit') ||\n msg.includes('500') ||\n msg.includes('overloaded') ||\n msg.includes('529') ||\n msg.includes('server error') ||\n msg.includes('service unavailable') ||\n msg.includes('network') ||\n msg.includes('connection') ||\n msg.includes('timeout') ||\n msg.includes('econnreset') ||\n msg.includes('socket hang up')\n )\n}\n\n/** Check if error is specifically a 529 overloaded response. */\nfunction is529Overloaded(err: unknown): boolean {\n if (err instanceof ApiError && err.status === 529) return true\n if (!(err instanceof Error)) return false\n return err.message.includes('529') || err.message.toLowerCase().includes('overloaded')\n}\n\n// ---------- 413 detection ----------\n\n/**\n * Detect prompt-too-long errors (HTTP 413 or API-level message).\n * Ported from La-Machina's isPromptTooLongMessage().\n */\nfunction isPromptTooLong(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n const msg = err.message.toLowerCase()\n return (\n msg.includes('prompt is too long') ||\n msg.includes('request too large') ||\n msg.includes('413') ||\n msg.includes('too many tokens')\n )\n}\n\n// ---------- tool result truncation ----------\n\n/**\n * Cap tool result size to prevent exceeding API per-message limits.\n * Ported from La-Machina's toolResultStorage.ts budget enforcement.\n */\nconst MAX_TOOL_RESULT_CHARS = 100_000\n\nexport function truncateToolResult(content: string): string {\n if (content.length <= MAX_TOOL_RESULT_CHARS) return content\n return (\n content.slice(0, MAX_TOOL_RESULT_CHARS) +\n `\\n\\n[TRUNCATED — showing first ${MAX_TOOL_RESULT_CHARS.toLocaleString()} chars of ${content.length.toLocaleString()} total]`\n )\n}\n\n// ---------- helpers ----------\n\nfunction failed(error: Error, transcript: TranscriptLocation): AgentLoopResult {\n return { status: 'failed', error, transcript }\n}\n\nfunction toError(err: unknown): Error {\n if (err instanceof Error) return err\n return new Error(String(err))\n}\n\ninterface PauseHereOptions {\n readonly ctx: RunContext\n readonly transcript: TranscriptLocation\n readonly reason: PauseReason\n readonly pendingToolCall?: RunSnapshot['pendingToolCall'] | undefined\n readonly pendingSubagent?: RunSnapshot['pendingSubagent'] | undefined\n readonly storage?: StorageAdapter | undefined\n readonly subagentRegistry?: import('../subagent/registry.js').SubagentRegistry | undefined\n}\n\nasync function pauseHere(options: PauseHereOptions): Promise<AgentLoopResult> {\n const { ctx, transcript, reason, pendingToolCall, pendingSubagent, storage } = options\n\n // Drain running background agents before pausing — wait up to 10s for\n // in-flight work to complete so their results aren't lost. Results are\n // injected as task-notification messages into the context.\n if (options.subagentRegistry) {\n const bgResults = await options.subagentRegistry.awaitBackgroundAgents(10_000)\n for (const bg of bgResults) {\n const status = bg.isError ? 'failed' : 'completed'\n const notification = [\n '<task-notification>',\n `<task-id>${bg.agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>Background agent \"${bg.description ?? bg.agentId}\" ${status}</summary>`,\n `<result>${bg.output}</result>`,\n '</task-notification>',\n ].join('\\n')\n await ctx.addUserMessage(notification)\n }\n }\n\n // Flush any buffered transcript entries BEFORE writing the snapshot.\n // Without this, entries written this turn (the user message, the\n // assistant tool_use call) would still be in memory and never reach\n // disk — resume would replay an incomplete history.\n await ctx.flushTranscript()\n\n const usage = ctx.getTokensUsed()\n const tokensUsed: RunSnapshot['tokensUsedSoFar'] = {\n input: usage.input,\n output: usage.output,\n ...(usage.cacheCreationInput !== undefined\n ? { cacheCreationInput: usage.cacheCreationInput }\n : {}),\n ...(usage.cacheReadInput !== undefined ? { cacheReadInput: usage.cacheReadInput } : {}),\n }\n const snapshot: RunSnapshot = {\n version: 1,\n status: 'paused',\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n pausedAt: new Date().toISOString(),\n pauseReason: reason,\n messageCount: ctx.getMessages().length,\n lastShardIndex: transcript.lastShardIndex,\n lastMessageUuid: ctx.getLastUuid() ?? '00000000-0000-4000-8000-000000000000',\n ...(pendingToolCall ? { pendingToolCall } : {}),\n ...(pendingSubagent ? { pendingSubagent } : {}),\n tokensUsedSoFar: tokensUsed,\n turnsUsed: ctx.getTurnCount(),\n }\n if (storage) {\n await writeSnapshot(storage, transcript.path, snapshot)\n }\n return { status: 'paused', snapshot, reason }\n}\n","/**\n * RunSnapshot — JSON sidecar capturing the state of a paused run.\n *\n * Lives at `{logPath}/snapshot.json`. Written when the agent loop\n * decides to pause (gate required, max turns, explicit signal); read\n * by `engine.resume()` to rebuild the run state and continue.\n *\n * The snapshot is intentionally small — it does NOT contain the full\n * conversation history. The transcript shards are the source of\n * truth for messages; the snapshot just points at where to pick up\n * (lastShardIndex) and what was about to happen (pendingToolCall).\n *\n * Schema validation is strict on read: a corrupted or version-\n * mismatched snapshot is a hard error, not a silent fallback. Resume\n * state must be trustworthy.\n */\n\nimport { z } from 'zod'\nimport type { RunSnapshot } from '../engine/types.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nconst SNAPSHOT_FILENAME = 'snapshot.json'\n\nconst TokenUsageSchema = z\n .object({\n input: z.number().int().nonnegative(),\n output: z.number().int().nonnegative(),\n cacheCreationInput: z.number().int().nonnegative().optional(),\n cacheReadInput: z.number().int().nonnegative().optional(),\n })\n .strict()\n\nconst PendingToolCallSchema = z\n .object({\n toolName: z.string().min(1),\n toolUseId: z.string().min(1),\n input: z.unknown(),\n calledAt: z.string().datetime({ offset: true }),\n })\n .strict()\n\n// Lazy — RunSnapshot can embed another RunSnapshot inside\n// pendingSubagent.childSnapshot. Use z.lazy to let the schema reference itself.\nconst PendingSubagentSchema = z.lazy(() =>\n z\n .object({\n subagentType: z.string().min(1),\n parentToolUseId: z.string().min(1),\n childSnapshot: RunSnapshotSchema,\n })\n .strict(),\n)\n\nconst RunSnapshotSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n version: z.literal(1),\n status: z.literal('paused'),\n runId: z.string().min(1),\n nodeId: z.string().min(1),\n pausedAt: z.string().datetime({ offset: true }),\n pauseReason: z.enum([\n 'gate_required',\n 'subagent_gate_required',\n 'handoff_to_runner',\n 'max_turns',\n 'explicit',\n 'timeout',\n ]),\n messageCount: z.number().int().nonnegative(),\n lastShardIndex: z.number().int().nonnegative(),\n lastMessageUuid: z.string().uuid(),\n pendingToolCall: PendingToolCallSchema.optional(),\n pendingSubagent: PendingSubagentSchema.optional(),\n tokensUsedSoFar: TokenUsageSchema,\n turnsUsed: z.number().int().nonnegative(),\n })\n .strict(),\n)\n\nfunction snapshotPath(logPath: string): string {\n return `${logPath}/${SNAPSHOT_FILENAME}`\n}\n\n/**\n * Read and validate the snapshot at `{logPath}/snapshot.json`.\n * Returns null if the file does not exist; throws on corruption,\n * schema violation, or unknown version.\n */\nexport async function readSnapshot(\n storage: StorageAdapter,\n logPath: string,\n): Promise<RunSnapshot | null> {\n const raw = await storage.readFile(snapshotPath(logPath))\n if (raw === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (err) {\n throw new Error(\n `readSnapshot: invalid JSON at ${snapshotPath(logPath)}: ${(err as Error).message}`,\n )\n }\n\n // Surface a clearer error for version mismatch BEFORE schema parse\n // so callers can branch on it specifically (future versions will need\n // a migration shim here).\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'version' in parsed &&\n (parsed as { version: unknown }).version !== 1\n ) {\n throw new Error(\n `readSnapshot: unsupported snapshot version ${String(\n (parsed as { version: unknown }).version,\n )}; engine v0.1 only supports version 1`,\n )\n }\n\n const result = RunSnapshotSchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(\n `readSnapshot: schema violation at ${snapshotPath(logPath)}: ${result.error.message}`,\n )\n }\n return result.data as RunSnapshot\n}\n\n/**\n * Validate + atomically write the snapshot. Throws if the snapshot\n * fails schema validation BEFORE the write so we never persist a\n * malformed payload.\n */\nexport async function writeSnapshot(\n storage: StorageAdapter,\n logPath: string,\n snapshot: RunSnapshot,\n): Promise<void> {\n const validated = RunSnapshotSchema.parse(snapshot)\n await storage.writeFile(snapshotPath(logPath), JSON.stringify(validated, null, 2))\n}\n","/**\n * Offload helper — called from `agentLoop` immediately after a tool\n * result streams back, before `ctx.addToolResult` writes the content\n * into the transcript / message context (Plan 021 §4).\n *\n * Behavior:\n * - Offload disabled, content below threshold, or `isError: true`\n * → pass content through unchanged. (Errors MUST stay inline;\n * the model needs the error text verbatim to adapt.)\n * - Content above threshold → write full payload to\n * `{logPath}/toolResults/{toolUseId}.json` via the workspace\n * adapter, then build a short summary string (default or\n * user-supplied) and return that instead.\n *\n * The summary — not the raw content — is what lands in the\n * transcript. Rehydrate therefore reconstructs the same reduced\n * message history on resume. A new `FetchData` tool (built alongside)\n * reads the blob back when the model needs the full payload.\n */\n\nimport { defaultToolResultSummarizer } from './toolResultSummarizer.js'\nimport type { ResolvedToolResultOffloadConfigV1 } from './toolResultOffload.types.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface MaybeOffloadInput {\n readonly offloadConfig: ResolvedToolResultOffloadConfigV1 | undefined\n readonly storage: StorageAdapter\n readonly logPath: string\n readonly toolUseId: string\n readonly toolName: string\n readonly toolInput: unknown\n readonly rawContent: string\n readonly rawIsError: boolean\n}\n\n/**\n * Returns the content that should be written to the transcript:\n * either the raw content (when offload is off / below threshold /\n * error) or a summary string carrying the ref.\n *\n * Writes to storage as a side effect when offload fires. Storage\n * failures bubble up so the caller can surface them to the model\n * as a tool_result error rather than silently dropping the data.\n */\nexport async function maybeOffloadToolResult(input: MaybeOffloadInput): Promise<string> {\n const {\n offloadConfig,\n storage,\n logPath,\n toolUseId,\n toolName,\n toolInput,\n rawContent,\n rawIsError,\n } = input\n\n if (offloadConfig === undefined || offloadConfig.enabled !== true) {\n return rawContent\n }\n if (rawIsError) {\n // Errors always stay inline.\n return rawContent\n }\n if (toolName === 'FetchData') {\n // Never offload FetchData's own output — it's what the model\n // asked for after the original offload, and re-offloading would\n // replace the rehydrated content with another ref, trapping\n // the model in a hydrate loop.\n return rawContent\n }\n\n const rawBytes = byteLength(rawContent)\n if (rawBytes <= offloadConfig.thresholdBytes) {\n return rawContent\n }\n\n // Over threshold — offload.\n const path = `${logPath}/toolResults/${toolUseId}.json`\n await storage.writeFile(path, rawContent)\n\n const summarizer = offloadConfig.summarizer ?? defaultToolResultSummarizer\n const summary = await summarizer({\n toolName,\n toolInput,\n rawContent,\n rawBytes,\n ref: toolUseId,\n maxPreviewChars: offloadConfig.maxPreviewChars,\n })\n\n // Safety net — if a caller's custom summarizer forgot the ref,\n // append it so the model can still rehydrate. Better than silent\n // loss of access to the full payload.\n if (!summary.includes(toolUseId)) {\n return `${summary}\\n[offloaded — ref=${toolUseId}, use FetchData to read the full content]`\n }\n return summary\n}\n\nfunction byteLength(s: string): number {\n return new TextEncoder().encode(s).byteLength\n}\n","/**\n * Default deterministic summarizer for offloaded tool results\n * (Plan 021 §2).\n *\n * No LLM calls. Shape-aware for JSON arrays and top-level JSON\n * objects; falls back to first-N-chars for arbitrary text. The\n * returned string ALWAYS includes the `ref` token so the model\n * knows to call `FetchData({ ref })` when it needs the raw content.\n *\n * Users who want richer summarization (semantic summaries, tool-\n * specific extractors) can plug their own `ToolResultSummarizerV1`\n * via `config.compaction.toolResultOffload.summarizer`. An LLM-based\n * summarizer is on the roadmap — see Plan 021 \"Deferred with\n * triggers\" and the README.\n */\n\nimport type {\n ToolResultSummarizerCtxV1,\n ToolResultSummarizerV1,\n} from './toolResultOffload.types.js'\n\nconst MAX_ITEM_PREVIEW_CHARS = 150\nconst MAX_TOP_LEVEL_KEYS = 8\n\nexport const defaultToolResultSummarizer: ToolResultSummarizerV1 = (ctx) => {\n return summarize(ctx)\n}\n\nfunction summarize(ctx: ToolResultSummarizerCtxV1): string {\n const { toolName, rawContent, rawBytes, ref, maxPreviewChars } = ctx\n\n const parsed = tryParseJSON(rawContent)\n if (parsed.ok) {\n if (Array.isArray(parsed.value)) {\n return summarizeArray(toolName, parsed.value, ref, rawBytes)\n }\n if (parsed.value !== null && typeof parsed.value === 'object') {\n return summarizeObject(toolName, parsed.value as Record<string, unknown>, ref, rawBytes)\n }\n }\n\n // Arbitrary text path.\n const preview = rawContent.slice(0, maxPreviewChars)\n const truncated = rawContent.length > maxPreviewChars ? '…' : ''\n return (\n `[${toolName}] ${formatBytes(rawBytes)} offloaded.\\n` +\n (preview.length > 0 ? `Preview: ${preview}${truncated}\\n` : '') +\n `Use FetchData with ref=\"${ref}\" to read the full content.`\n )\n}\n\nfunction summarizeArray(toolName: string, arr: unknown[], ref: string, bytes: number): string {\n const count = arr.length\n const firstHint = arr.length > 0 ? compactPreview(arr[0]) : ''\n const hintLine = firstHint ? `First item preview: ${firstHint}\\n` : ''\n return (\n `[${toolName}] Array of ${count} item${count === 1 ? '' : 's'} (${formatBytes(bytes)}).\\n` +\n hintLine +\n `Use FetchData with ref=\"${ref}\" to read the full array.`\n )\n}\n\nfunction summarizeObject(\n toolName: string,\n obj: Record<string, unknown>,\n ref: string,\n bytes: number,\n): string {\n const keys = Object.keys(obj)\n const shown = keys.slice(0, MAX_TOP_LEVEL_KEYS)\n const overflow = keys.length > MAX_TOP_LEVEL_KEYS ? ` (+${keys.length - shown.length} more)` : ''\n const parts = shown.map((k) => `${k}=${compactPreview(obj[k])}`).join(', ')\n return (\n `[${toolName}] Object (${formatBytes(bytes)}). Keys: ${parts}${overflow}\\n` +\n `Use FetchData with ref=\"${ref}\" to read the full object.`\n )\n}\n\n/** One-line preview of any JSON value, capped at MAX_ITEM_PREVIEW_CHARS. */\nfunction compactPreview(value: unknown): string {\n let str: string\n if (value === null) {\n str = 'null'\n } else if (typeof value === 'string') {\n str = JSON.stringify(value) // quoted, so escaped newlines are visible\n } else if (Array.isArray(value)) {\n str = `[${value.length} item${value.length === 1 ? '' : 's'}]`\n } else if (typeof value === 'object') {\n const keys = Object.keys(value)\n str = `{${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', …' : ''}}`\n } else {\n str = String(value)\n }\n if (str.length > MAX_ITEM_PREVIEW_CHARS) {\n return str.slice(0, MAX_ITEM_PREVIEW_CHARS) + '…'\n }\n return str\n}\n\nfunction tryParseJSON(text: string): { ok: true; value: unknown } | { ok: false } {\n // Strip BOM if present — JSON.parse rejects it.\n const trimmed = text.replace(/^\\uFEFF/, '').trim()\n if (trimmed.length === 0) return { ok: false }\n // Cheap early reject — only attempt parse if it starts like JSON.\n const first = trimmed[0]\n if (first !== '{' && first !== '[' && first !== '\"') return { ok: false }\n try {\n return { ok: true, value: JSON.parse(trimmed) as unknown }\n } catch {\n return { ok: false }\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/**\n * dispatchHooks — fire every hook in a list, in registration order,\n * sequentially. Awaits async hooks. Isolates errors so a thrown hook\n * never propagates to the agent loop or engine.run() caller.\n *\n * The function takes a tuple of `(hookList, event)` and returns a\n * Promise that resolves once every hook has been awaited (or thrown\n * and been swallowed). Empty lists are silent no-ops.\n *\n * Hook errors are deliberately silent in v0.1 — they're caught and\n * dropped. Phase 11.5 / v0.2 may surface them via the logger sink so\n * caller-side observability tools can see misbehaving hooks. For now\n * the contract is \"hooks are best-effort, never load-bearing.\"\n */\n\ntype AnyHook<E> = (event: E) => void | Promise<void>\n\nexport async function dispatchHooks<E>(hooks: ReadonlyArray<AnyHook<E>>, event: E): Promise<void> {\n for (const hook of hooks) {\n try {\n const result = hook(event)\n if (result instanceof Promise) {\n await result.catch(() => undefined)\n }\n } catch {\n // Hook errors are isolated.\n }\n }\n}\n","/**\n * normalizeMessages — clean message arrays before sending to the API.\n *\n * Ported from La-Machina's normalizeMessagesForAPI(). The Anthropic\n * Messages API requires strict alternating user/assistant messages,\n * non-empty content blocks, and no consecutive same-role messages.\n *\n * This function:\n * 1. Strips internal blocks (advisor, signature, tool_reference, caller)\n * 2. Strips empty/whitespace-only text blocks and thinking blocks\n * 3. Drops messages with no content after filtering\n * 4. Merges consecutive same-role messages into one\n * 5. Ensures first message is user and strict alternation\n * 6. Validates tool_use ↔ tool_result pairing (injects synthetic results for orphans)\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ContentBlockParam, MessageParam } from '@anthropic-ai/sdk/resources/messages'\n\n// ---------- internal block patterns ----------\n\n/**\n * Regex patterns for internal blocks that should be stripped before API.\n * Ported from La-Machina's stripAdvisorBlocks, stripSignatureBlocks,\n * stripToolReferenceBlocks, stripCallerField.\n */\nconst INTERNAL_BLOCK_PATTERNS = [\n /<advisor>[\\s\\S]*?<\\/advisor>/g,\n /<tool_reference>[\\s\\S]*?<\\/tool_reference>/g,\n /<git_signature>[\\s\\S]*?<\\/git_signature>/g,\n /<caller>[\\s\\S]*?<\\/caller>/g,\n]\n\nfunction stripInternalBlocks(text: string): string {\n let result = text\n for (const pattern of INTERNAL_BLOCK_PATTERNS) {\n // Reset regex state (global flag)\n pattern.lastIndex = 0\n result = result.replace(pattern, '')\n }\n return result.trim()\n}\n\n// ---------- main normalization ----------\n\nexport function normalizeMessages(messages: readonly MessageParam[]): MessageParam[] {\n const result: MessageParam[] = []\n\n for (const msg of messages) {\n // Normalize content to array form\n let content: ContentBlockParam[]\n if (typeof msg.content === 'string') {\n const stripped = stripInternalBlocks(msg.content)\n if (stripped.length === 0) continue\n content = [{ type: 'text', text: stripped }]\n } else if (Array.isArray(msg.content)) {\n // Filter and clean each block\n content = msg.content\n .map((b) => {\n if (b.type === 'text') {\n const stripped = stripInternalBlocks((b as { type: 'text'; text: string }).text)\n if (stripped.length === 0) return null\n return { ...b, text: stripped } as ContentBlockParam\n }\n // Strip thinking blocks — preserved in transcript but not sent to API\n if ((b as { type: string }).type === 'thinking') return null\n if ((b as { type: string }).type === 'redacted_thinking') return null\n return b\n })\n .filter((b): b is ContentBlockParam => b !== null)\n\n if (content.length === 0) continue\n } else {\n continue\n }\n\n // Merge consecutive same-role messages\n const prev = result[result.length - 1]\n if (prev !== undefined && prev.role === msg.role) {\n const prevContent = Array.isArray(prev.content)\n ? prev.content\n : [{ type: 'text' as const, text: prev.content }]\n result[result.length - 1] = {\n role: msg.role,\n content: [...prevContent, ...content],\n }\n continue\n }\n\n result.push({ role: msg.role, content })\n }\n\n // Ensure first message is from user (API requirement)\n if (result.length > 0 && result[0]!.role !== 'user') {\n result.unshift({\n role: 'user',\n content: [{ type: 'text', text: '[system: conversation start]' }],\n })\n }\n\n // Ensure strict alternation\n const fixed: MessageParam[] = []\n for (const msg of result) {\n const prev = fixed[fixed.length - 1]\n if (prev && prev.role === msg.role) {\n const fillerRole = msg.role === 'user' ? 'assistant' : 'user'\n fixed.push({\n role: fillerRole,\n content: [{ type: 'text', text: '[continued]' }],\n })\n }\n fixed.push(msg)\n }\n\n // Tool result pairing — ensure every tool_use has a matching tool_result.\n // Ported from La-Machina's ensureToolResultPairing().\n return ensureToolResultPairing(fixed)\n}\n\n// ---------- tool result pairing ----------\n\n/**\n * Scan messages for orphaned tool_use blocks (no matching tool_result)\n * and inject synthetic error results. Prevents API 400 errors from\n * incomplete tool call sequences.\n */\nfunction ensureToolResultPairing(messages: MessageParam[]): MessageParam[] {\n const pendingToolUseIds = new Set<string>()\n\n for (const msg of messages) {\n if (!Array.isArray(msg.content)) continue\n for (const b of msg.content) {\n const block = b as { type: string; id?: string; tool_use_id?: string }\n if (block.type === 'tool_use' && block.id) {\n pendingToolUseIds.add(block.id)\n }\n if (block.type === 'tool_result' && block.tool_use_id) {\n pendingToolUseIds.delete(block.tool_use_id)\n }\n }\n }\n\n // All paired — no fix needed\n if (pendingToolUseIds.size === 0) return messages\n\n // Inject synthetic error results for orphaned tool_use blocks\n const syntheticResults: ContentBlockParam[] = [...pendingToolUseIds].map((id) => ({\n type: 'tool_result' as const,\n tool_use_id: id,\n content: '[Tool result missing — execution was interrupted]',\n is_error: true,\n }))\n\n // Append as a user message (tool_results must be in user messages)\n messages.push({ role: 'user', content: syntheticResults })\n\n return messages\n}\n","/**\n * Compactor — the top-level compaction orchestrator.\n *\n * Decides WHEN to compact (token threshold) and HOW (strategy selection).\n *\n * Called by the agent loop at the top of each turn. Returns either the\n * original messages (no compaction needed) or compacted messages with a\n * result describing what happened.\n *\n * Strategy selection in 'auto' mode:\n * 1. If `microcompact` is enabled, run it first (cheap, no LLM call).\n * 2. If tokens still over threshold, try `summarize` (LLM-driven).\n * 3. If summarize fails or is unavailable, fall back to `drop-middle`.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { dropMiddle } from './dropMiddle.js'\nimport { microcompact } from './microcompact.js'\nimport { summarizeCompact } from './summarize.js'\nimport type { CompactionResult, ResolvedCompactionConfig } from './types.js'\n\nexport interface CompactIfNeededOptions {\n readonly messages: readonly MessageParam[]\n readonly usage: TokenUsage\n readonly contextLimit: number\n readonly config: ResolvedCompactionConfig\n readonly client: ModelAdapter\n readonly system: string\n}\n\nexport async function compactIfNeeded(\n options: CompactIfNeededOptions,\n): Promise<{ compacted: boolean; result: CompactionResult | null; messages: MessageParam[] }> {\n const { messages, usage, contextLimit, config, client, system } = options\n\n // Check if compaction is needed.\n const used =\n usage.input + usage.output + (usage.cacheReadInput ?? 0) + (usage.cacheCreationInput ?? 0)\n const ratio = used / contextLimit\n\n if (ratio <= config.threshold) {\n // Below threshold — no compaction needed.\n // But if microcompact is enabled, still run it opportunistically\n // to keep old tool results trimmed.\n if (config.microcompact && messages.length > config.keepLast + 4) {\n const mcResult = microcompact({\n messages,\n keepRecent: config.keepLast,\n })\n if (mcResult.dropped > 0) {\n return { compacted: true, result: mcResult, messages: mcResult.messages }\n }\n }\n return { compacted: false, result: null, messages: [...messages] }\n }\n\n // Above threshold — compact using the configured strategy.\n const result = await executeStrategy(messages, config, client, system)\n return { compacted: true, result, messages: result.messages }\n}\n\nasync function executeStrategy(\n messages: readonly MessageParam[],\n config: ResolvedCompactionConfig,\n client: ModelAdapter,\n system: string,\n): Promise<CompactionResult> {\n // Run microcompact first if enabled (cheap, might bring us under).\n let workingMessages = [...messages]\n if (config.microcompact) {\n const mcResult = microcompact({\n messages: workingMessages,\n keepRecent: config.keepLast,\n })\n workingMessages = mcResult.messages\n }\n\n switch (config.strategy) {\n case 'drop-middle':\n return dropMiddle(workingMessages, config.keepLast)\n\n case 'summarize':\n return summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n\n case 'session-memory':\n // Session memory compaction would extract facts to persistent memory.\n // For v0.2, we fall through to summarize — session-memory is a v0.3\n // refinement that needs tighter integration with the Hippocampus.\n return summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n\n case 'auto':\n default:\n // Auto: try summarize, fall back to drop-middle on failure.\n try {\n return await summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n } catch {\n return dropMiddle(workingMessages, config.keepLast)\n }\n }\n}\n","/**\n * Drop-middle compaction — the v0.1 strategy, kept as a fallback.\n *\n * Drops everything between the first user message and the last K\n * messages, replacing the gap with a placeholder marker.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { CompactionResult } from './types.js'\n\nexport function dropMiddle(messages: readonly MessageParam[], keepLast: number): CompactionResult {\n const firstUserIndex = messages.findIndex((m) => m.role === 'user')\n if (firstUserIndex === -1) {\n return { messages: [...messages], strategy: 'drop-middle', dropped: 0 }\n }\n\n const tailStart = Math.max(messages.length - keepLast, firstUserIndex + 1)\n const tail = messages.slice(tailStart)\n const middleStart = firstUserIndex + 1\n const droppedCount = Math.max(0, tailStart - middleStart)\n\n if (droppedCount === 0) {\n return { messages: [...messages], strategy: 'drop-middle', dropped: 0 }\n }\n\n const marker: MessageParam = {\n role: 'user',\n content: [\n {\n type: 'text',\n text: `[compacted: ${droppedCount} earlier message${droppedCount === 1 ? '' : 's'} dropped to fit the context window. Key findings and decisions from those messages may be lost — re-derive if needed.]`,\n },\n ],\n }\n\n return {\n messages: [messages[firstUserIndex] as MessageParam, marker, ...tail],\n strategy: 'drop-middle',\n dropped: droppedCount,\n }\n}\n","/**\n * Microcompaction — time-based clearing of old tool results.\n *\n * Does NOT call the LLM. Simply replaces the content of tool_result\n * messages older than `microcompactAgeMs` with a placeholder string.\n * The message structure is preserved (role, tool_use_id, etc.) so the\n * API's tool_use ↔ tool_result pairing stays valid.\n *\n * Ported from La-Machina's microCompact.ts. The engine's version is\n * simpler because we don't have the API cache_edits mechanism —\n * we mutate messages in-place before passing them to the next turn.\n *\n * Compactable tools (safe to clear old results): Read, Grep, Glob,\n * WebFetch, WebSearch, Bash (stdout-only outputs). We do NOT clear\n * tool results from Write, Edit, Agent, TaskCreate, Memorize, etc.\n * because their results may contain confirmation IDs or state the\n * model needs to reference later.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { CompactionResult } from './types.js'\n\nconst CLEARED_MARKER = '[Old tool result content cleared to save context space]'\n\n/** Tools whose results are safe to clear after they age out. */\nexport const COMPACTABLE_TOOLS = new Set([\n 'Read',\n 'Grep',\n 'Glob',\n 'WebFetch',\n 'WebSearch',\n 'Bash',\n 'ToolSearch',\n])\n\nexport interface MicrocompactOptions {\n readonly messages: readonly MessageParam[]\n /** How many recent messages to never touch. */\n readonly keepRecent: number\n /** Tool names from the registry — only compact known tools. */\n readonly knownToolNames?: ReadonlySet<string>\n}\n\nexport function microcompact(options: MicrocompactOptions): CompactionResult {\n const { messages, keepRecent } = options\n if (messages.length <= keepRecent) {\n return { messages: [...messages], strategy: 'microcompact', dropped: 0 }\n }\n\n const cutoff = messages.length - keepRecent\n let cleared = 0\n const out: MessageParam[] = []\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!\n if (i >= cutoff || msg.role !== 'user') {\n out.push(msg)\n continue\n }\n\n // Tool results are user messages with content blocks that have\n // type: 'tool_result'. Check if any blocks are compactable.\n if (!Array.isArray(msg.content)) {\n out.push(msg)\n continue\n }\n\n // Tool results are user messages with content blocks. We check each\n // block for tool_result type and clear large content in old blocks.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const blocks = msg.content as any[]\n let modified = false\n const newBlocks = blocks.map((block: any) => {\n if (block.type !== 'tool_result') return block\n const content = block.content\n if (typeof content === 'string' && content !== CLEARED_MARKER && content.length > 100) {\n modified = true\n cleared++\n return { ...block, content: CLEARED_MARKER }\n }\n if (Array.isArray(content)) {\n const hasLargeText = content.some(\n (c: any) => c?.type === 'text' && typeof c.text === 'string' && c.text.length > 100,\n )\n if (hasLargeText) {\n modified = true\n cleared++\n return { ...block, content: CLEARED_MARKER }\n }\n }\n return block\n })\n\n out.push(modified ? { ...msg, content: newBlocks } : msg)\n }\n\n return { messages: out, strategy: 'microcompact', dropped: cleared }\n}\n","/**\n * LLM-driven summarization compaction.\n *\n * Sends the middle messages to the model with a summarization prompt.\n * Replaces the dropped messages with the LLM-generated summary as a\n * synthetic user message. The model retains semantic understanding\n * without the raw token cost.\n *\n * The summarizer uses the same API client as the main run — sharing\n * the connection and (when applicable) the prompt cache.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { CompactionResult, ResolvedCompactionConfig } from './types.js'\nimport { buildSummarizationPrompt } from './prompt.js'\n\nexport interface SummarizeOptions {\n readonly messages: readonly MessageParam[]\n readonly config: ResolvedCompactionConfig\n readonly client: ModelAdapter\n readonly system: string\n}\n\nexport async function summarizeCompact(options: SummarizeOptions): Promise<CompactionResult> {\n const { messages, config, client, system } = options\n\n const firstUserIndex = messages.findIndex((m) => m.role === 'user')\n if (firstUserIndex === -1) {\n return { messages: [...messages], strategy: 'summarize', dropped: 0 }\n }\n\n const tailStart = Math.max(messages.length - config.keepLast, firstUserIndex + 1)\n const tail = messages.slice(tailStart)\n const middle = messages.slice(firstUserIndex + 1, tailStart)\n const droppedCount = middle.length\n\n if (droppedCount === 0) {\n return { messages: [...messages], strategy: 'summarize', dropped: 0 }\n }\n\n // Build the summarization request: include the first user message +\n // the middle messages as conversation history, then ask for a summary.\n const summaryMessages: MessageParam[] = [\n messages[firstUserIndex] as MessageParam,\n ...middle,\n {\n role: 'user',\n content: buildSummarizationPrompt(droppedCount),\n },\n ]\n\n let summaryText: string\n try {\n summaryText = await generateSummary(client, system, summaryMessages, config.summaryMaxTokens)\n } catch {\n // If summarization fails (API error, timeout, etc.), fall back to\n // drop-middle so the run can continue. Log at warn level.\n const marker: MessageParam = {\n role: 'user',\n content: `[compacted: ${droppedCount} messages dropped — summarization failed, using drop-middle fallback]`,\n }\n return {\n messages: [messages[firstUserIndex] as MessageParam, marker, ...tail],\n strategy: 'summarize',\n dropped: droppedCount,\n }\n }\n\n const summaryMarker: MessageParam = {\n role: 'user',\n content: `[Context summary — ${droppedCount} earlier messages compacted into this summary]\\n\\n${summaryText}`,\n }\n\n return {\n messages: [messages[firstUserIndex] as MessageParam, summaryMarker, ...tail],\n strategy: 'summarize',\n dropped: droppedCount,\n summaryLength: summaryText.length,\n }\n}\n\nasync function generateSummary(\n client: ModelAdapter,\n system: string,\n messages: MessageParam[],\n maxTokens: number,\n): Promise<string> {\n const pieces: string[] = []\n\n for await (const event of client.streamMessage({\n messages,\n system,\n maxTokens,\n temperature: 0,\n })) {\n if (event.type === 'text') {\n pieces.push(event.text)\n }\n }\n\n const raw = pieces.join('')\n if (raw.length === 0) {\n throw new Error('Summarization returned empty response')\n }\n\n // Strip <analysis> blocks if present (La-Machina convention —\n // the model uses it as scratchpad before the real summary).\n const cleaned = raw\n .replace(/<analysis>[\\s\\S]*?<\\/analysis>/gi, '')\n .replace(/<\\/?summary>/gi, '')\n .trim()\n\n return cleaned.length > 0 ? cleaned : raw\n}\n","/**\n * Summarization prompt — ported from La-Machina's compact/prompt.ts.\n *\n * 100+ lines of structured instructions that guide the LLM to produce\n * high-quality conversation summaries that preserve:\n * - File paths, line numbers, code snippets\n * - Errors and how they were resolved\n * - Decision rationale and pending tasks\n * - User messages (non-tool results)\n *\n * The <analysis> block is a scratchpad the model uses to plan the\n * summary before writing it — stripped post-processing.\n */\n\nexport function buildSummarizationPrompt(droppedCount: number): string {\n return `CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.\n- Do NOT use Read, Bash, Grep, Glob, Edit, Write, or ANY other tool.\n- You already have all the context you need in the conversation above.\n- Tool calls will be REJECTED and will waste your only turn — you will fail the task.\n- Your entire response must be plain text: an <analysis> block followed by a <summary> block.\n\nYour task is to create a detailed summary of the conversation so far.\n${droppedCount} messages from the middle of the conversation are being compacted to fit the context window.\n\nYour summary should include the following sections:\n\n1. **Primary Request and Intent**\n What the user originally asked for and what they're trying to achieve.\n\n2. **Key Technical Concepts**\n Important architectural decisions, patterns, or constraints discovered.\n\n3. **Files and Code Sections**\n Every file that was read, modified, or created — with FULL file paths.\n Include key code snippets verbatim (not paraphrased) when they are\n central to understanding the changes made.\n\n4. **Errors and Fixes**\n Every error encountered, its root cause, and how it was resolved.\n Include the actual error messages.\n\n5. **Problem Solving**\n Approaches tried, why they failed or succeeded, and the reasoning\n behind the current approach.\n\n6. **All User Messages**\n Reproduce every user message (not tool results) from the conversation\n in chronological order, preserving the user's exact words or a close\n paraphrase. These are the primary requirements.\n\n7. **Pending Tasks**\n Anything that was planned but not yet completed. Include specific\n next steps.\n\n8. **Current Work**\n What was being worked on when this summary was generated. Include\n the last assistant action and its result.\n\n9. **Optional Next Step**\n If the conversation suggests a clear next action, state it with\n direct quotes from recent messages.\n\nWrite your response in this format:\n\n<analysis>\n[Your internal reasoning about what to include — this is your scratchpad.\nThink about what information is load-bearing vs what can be safely dropped.\nThis block will be stripped before the summary is used.]\n</analysis>\n\n<summary>\n[Your structured summary following the 9 sections above.\nBe thorough — anything not in this summary will be permanently lost.\nInclude specific file paths, variable names, error messages, and code\nsnippets. Prefer exact quotes over paraphrasing.]\n</summary>\n\nREMINDER: Do NOT call any tools. Respond with plain text only — an <analysis> block followed by a <summary> block.`\n}\n","/**\n * StreamingToolExecutor — stateful tool queue with ordered result yielding,\n * concurrency control, and sibling error cascading.\n *\n * Ported 1:1 from La-Machina's StreamingToolExecutor.ts. Key behaviors:\n *\n * - Tools are enqueued via `addTool()` and executed as they become eligible\n * - `canExecute()` enforces: concurrent-safe tools run in parallel; unsafe\n * tools run alone (exclusive access)\n * - Results are yielded in **original enqueue order** regardless of\n * completion order (preserves tool_result ordering for the API)\n * - On **Bash error**, `siblingAbortController.abort()` cancels all queued\n * siblings with synthetic error results. Only Bash cascades — Read/Grep/\n * WebFetch errors are independent.\n * - All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ToolResult } from '../tools/contract.js'\nimport type { ToolExecutor } from './toolRuntime.js'\n\nexport type ToolStatus = 'queued' | 'executing' | 'completed'\n\ninterface TrackedTool {\n readonly id: string\n readonly name: string\n readonly input: unknown\n readonly isConcurrencySafe: boolean\n status: ToolStatus\n result?: ToolResult\n promise?: Promise<void>\n resolve?: () => void\n}\n\nexport class StreamingToolExecutor {\n private readonly tools: TrackedTool[] = []\n private readonly executor: ToolExecutor\n private readonly siblingAbort = new AbortController()\n private bashErrorDesc: string | null = null\n\n constructor(executor: ToolExecutor) {\n this.executor = executor\n }\n\n /**\n * Enqueue a tool call. Eligible tools start executing immediately.\n */\n addTool(id: string, name: string, input: unknown, isConcurrencySafe: boolean): void {\n this.tools.push({ id, name, input, status: 'queued', isConcurrencySafe })\n this.processQueue()\n }\n\n /**\n * Yield results in original enqueue order. Waits for each tool to\n * complete before yielding — guarantees the API sees tool_result\n * blocks in the same order as the tool_use blocks.\n */\n async *results(): AsyncGenerator<{ id: string; result: ToolResult }> {\n for (const tool of this.tools) {\n // Wait for this tool to finish (may already be done)\n if (tool.promise) await tool.promise\n // Subagent pause — rethrow the stashed error so the parent\n // agentLoop's try/catch can surface it as a `paused` result.\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n const sp = (tool as TrackedTool & { subagentPausedError?: unknown }).subagentPausedError\n if (sp !== undefined) throw sp as Error\n yield { id: tool.id, result: tool.result! }\n }\n }\n\n // ---------- internal ----------\n\n /**\n * Can this tool start now? Mirrors La-Machina's canExecuteTool():\n * - If nothing is executing → yes\n * - If only concurrent-safe tools are executing AND this tool is safe → yes\n * - Otherwise → no (wait for exclusive access)\n */\n private canExecute(isConcurrencySafe: boolean): boolean {\n const executing = this.tools.filter((t) => t.status === 'executing')\n return (\n executing.length === 0 || (isConcurrencySafe && executing.every((t) => t.isConcurrencySafe))\n )\n }\n\n /**\n * Walk the queue and start any eligible tools. Called after enqueue\n * and after each tool completes (to unblock the next batch).\n */\n private processQueue(): void {\n for (const tool of this.tools) {\n if (tool.status !== 'queued') continue\n\n // Sibling already aborted → mark cancelled immediately\n if (this.siblingAbort.signal.aborted) {\n tool.status = 'completed'\n tool.result = {\n content: `Cancelled: parallel tool call \"${this.bashErrorDesc ?? 'bash'}\" errored`,\n isError: true,\n }\n // Create a resolved promise so results() doesn't block\n tool.promise = Promise.resolve()\n continue\n }\n\n if (this.canExecute(tool.isConcurrencySafe)) {\n this.startTool(tool)\n } else if (!tool.isConcurrencySafe) {\n // Don't skip past an exclusive tool — it must run before anything after it\n break\n }\n }\n }\n\n private startTool(tool: TrackedTool): void {\n tool.status = 'executing'\n\n // Create a promise that external code (results()) can await.\n // The resolve function is called when execution completes.\n let resolvePromise: () => void\n tool.promise = new Promise<void>((r) => {\n resolvePromise = r\n })\n\n // Fire and let processQueue() handle what comes next.\n // `void` — intentional fire-and-forget; completion is observed via\n // `tool.promise` which results() awaits.\n void this.executeTool(tool).then(() => {\n resolvePromise()\n })\n }\n\n private async executeTool(tool: TrackedTool): Promise<void> {\n try {\n tool.result = await this.executor.execute(tool.name, tool.input)\n } catch (err) {\n // Subagent pause propagation — surface the error through the\n // result channel so consumers see it as a throw when they iterate\n // `results()`. We attach a sentinel so consumer code can pick it\n // up and re-throw outside the executor boundary.\n if (isSubagentPausedError(err)) {\n tool.result = {\n content: '__SUBAGENT_PAUSED__',\n isError: true,\n }\n ;(tool as TrackedTool & { subagentPausedError?: unknown }).subagentPausedError = err\n } else {\n tool.result = {\n content: `Tool crashed: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n }\n\n tool.status = 'completed'\n\n // Bash error cascading — only Bash errors cancel siblings.\n // Bash commands often have implicit dependency chains (mkdir → write).\n // Read/WebFetch/etc. are independent — one failure shouldn't nuke the rest.\n if (tool.result.isError && tool.name === 'Bash') {\n const cmd = (tool.input as { command?: string } | undefined)?.command\n this.bashErrorDesc = cmd ? cmd.slice(0, 60) : 'bash'\n this.siblingAbort.abort('sibling_error')\n }\n\n // Unblock next queued tools\n this.processQueue()\n }\n}\n\nfunction isSubagentPausedError(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as { code?: unknown; childSnapshot?: unknown }\n return e.code === 'ERR_SUBAGENT_PAUSED' && e.childSnapshot !== undefined\n}\n","/**\n * RunContext — per-run state for the agent loop.\n *\n * Holds the conversation history (in Anthropic Messages API shape), the\n * turn counter, accumulated token usage, and a reference to the\n * `TranscriptWriter` that persists every state transition.\n *\n * Every method that mutates state ALSO writes a transcript entry, so\n * the writer is the single source of truth for \"what happened during\n * this run.\" The agent loop never touches the writer directly — it\n * only goes through `RunContext`.\n *\n * UUID chaining: each transcript entry's `parentUuid` points at the\n * previous entry's `uuid`, forming a linked list. The first entry has\n * `parentUuid: null`. This lets the reader reconstruct order even\n * when shards arrive out of band.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\nimport type {\n ContentBlockParam,\n MessageParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { TokenUsage } from '../api/streaming.js'\nimport type { EpisodicMemory } from '../memory/episodes.js'\nimport type { Entry } from '../transcript/entries.js'\nimport type { TranscriptWriter } from '../transcript/writer.js'\n\nexport interface RunContextOptions {\n readonly runId: string\n readonly nodeId: string\n readonly writer: TranscriptWriter\n readonly maxTurns: number\n readonly clock?: () => Date\n /**\n * Optional episodic memory. When set, every message mutation logs\n * a corresponding episode line. When omitted, episodic logging is\n * disabled (used by tests that don't care about the log).\n */\n readonly episodes?: EpisodicMemory\n}\n\nexport class RunContext {\n readonly runId: string\n readonly nodeId: string\n private readonly writer: TranscriptWriter\n private readonly maxTurns: number\n private readonly clock: () => Date\n private readonly episodes: EpisodicMemory | null\n\n private readonly messages: MessageParam[] = []\n private turnCount = 0\n private tokensUsed: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n } = { input: 0, output: 0 }\n\n private lastUuid: string | null = null\n\n /**\n * Plan 019 — names of tools whose capability-stub returned an\n * `isError` result during this run. Aggregated and surfaced on the\n * response's `meta.capabilitiesMissing` (deduped, insertion-ordered).\n */\n private readonly capabilitiesMissing = new Set<string>()\n\n constructor(options: RunContextOptions) {\n this.runId = options.runId\n this.nodeId = options.nodeId\n this.writer = options.writer\n this.maxTurns = options.maxTurns\n this.clock = options.clock ?? (() => new Date())\n this.episodes = options.episodes ?? null\n }\n\n // ---------- message mutators ----------\n\n async addUserMessage(text: string): Promise<void> {\n const content: ContentBlockParam[] = [{ type: 'text', text }]\n this.messages.push({ role: 'user', content })\n await this.writeEntry({\n type: 'user',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'user', content },\n })\n this.episodes?.logTurn(this.turnCount, 'user', text)\n }\n\n async addAssistantMessage(content: ContentBlockParam[]): Promise<void> {\n this.messages.push({ role: 'assistant', content })\n await this.writeEntry({\n type: 'assistant',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'assistant', content },\n })\n if (this.episodes) {\n // Episode payload is the assistant text + tool_use call signatures\n // joined into a single line. Tool inputs are stringified so the\n // search index can match against them later.\n const summary = content\n .map((block) => {\n const b = block as { type: string; text?: string; name?: string; input?: unknown }\n if (b.type === 'text') return b.text ?? ''\n if (b.type === 'tool_use') return `[${b.name ?? '?'}: ${JSON.stringify(b.input ?? {})}]`\n return ''\n })\n .filter((s) => s.length > 0)\n .join(' ')\n this.episodes.logTurn(this.turnCount, 'assistant', summary)\n }\n }\n\n /**\n * Inject a tool_result + a follow-up text block as a SINGLE user\n * message. Used by the resume() synthetic-release path when a\n * paused run is resumed without an explicit `gateAnswer`: we need\n * to both satisfy the tool_use↔tool_result pairing AND give the\n * model a retry instruction, in the same user turn.\n *\n * Splitting this into `addToolResult(...) + addUserMessage(...)`\n * produces two consecutive user messages, which the AI SDK's\n * openai-compatible adapter rejects with\n * `MissingToolResultsError`. Combining them into one user message\n * is the portable shape that works on every provider we support.\n *\n * Writes a single `user` transcript entry carrying the mixed\n * content, so `rebuildMessagesFromEntries` reconstructs the same\n * single-message shape on resume.\n */\n async addMixedUserMessage(blocks: ContentBlockParam[]): Promise<void> {\n this.messages.push({ role: 'user', content: blocks })\n await this.writeEntry({\n type: 'user',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'user', content: blocks },\n })\n // Episodic memory — log the tool_result content + any text blocks.\n const summary = blocks\n .map((b) => {\n const x = b as { type?: string; text?: string; content?: unknown }\n if (x.type === 'text') return x.text ?? ''\n if (x.type === 'tool_result') {\n return typeof x.content === 'string' ? x.content : JSON.stringify(x.content)\n }\n return ''\n })\n .filter((s) => s.length > 0)\n .join('\\n')\n this.episodes?.logTurn(this.turnCount, 'user', summary)\n }\n\n /**\n * Append a tool result to the conversation. The Anthropic Messages\n * API requires tool_result blocks to be wrapped in a user message,\n * so multiple results in the same turn collapse into one user message\n * by appending blocks to the previous tool_result message.\n */\n async addToolResult(toolUseId: string, content: string, isError: boolean): Promise<void> {\n const block: ToolResultBlockParam = {\n type: 'tool_result',\n tool_use_id: toolUseId,\n content,\n ...(isError ? { is_error: true } : {}),\n }\n\n // If the previous message is a user message containing only\n // tool_result blocks, append to it. Otherwise create a new one.\n const prev = this.messages[this.messages.length - 1]\n if (\n prev !== undefined &&\n prev.role === 'user' &&\n Array.isArray(prev.content) &&\n prev.content.every(\n (b) => typeof b === 'object' && (b as { type: string }).type === 'tool_result',\n )\n ) {\n prev.content.push(block)\n } else {\n this.messages.push({ role: 'user', content: [block] })\n }\n\n await this.writeEntry({\n type: 'tool_result',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n toolUseId,\n content,\n ...(isError ? { isError: true } : {}),\n })\n this.episodes?.logTurn(this.turnCount, 'tool_result', content, {\n toolUseId,\n isError,\n })\n }\n\n // ---------- accessors ----------\n\n getMessages(): readonly MessageParam[] {\n return this.messages\n }\n\n getTurnCount(): number {\n return this.turnCount\n }\n\n getTokensUsed(): Readonly<typeof this.tokensUsed> {\n return this.tokensUsed\n }\n\n /** Plan 019 — record that a capability-stubbed tool fired during this run. */\n recordCapabilityMissing(toolName: string): void {\n this.capabilitiesMissing.add(toolName)\n }\n\n /** Plan 019 — capability-stubbed tool names observed this run (deduped). */\n getCapabilitiesMissing(): readonly string[] {\n return [...this.capabilitiesMissing]\n }\n\n shouldContinue(): boolean {\n return this.turnCount < this.maxTurns\n }\n\n /** UUID of the most recently appended transcript entry, or null. */\n getLastUuid(): string | null {\n return this.lastUuid\n }\n\n /** Force-flush any buffered transcript entries through the writer. */\n async flushTranscript(): Promise<void> {\n await this.writer.flushLog()\n }\n\n /**\n * Re-seed a fresh RunContext with state from a paused snapshot. Used\n * by `engine.resume()` after the transcript has been replayed into\n * `addRehydratedMessage` calls. Sets the turn counter, token usage,\n * and last-uuid pointer back to where the run left off.\n */\n rehydrate(state: {\n messages: ReadonlyArray<MessageParam>\n turnCount: number\n tokensUsed: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n }\n lastUuid: string | null\n }): void {\n this.messages.length = 0\n this.messages.push(...state.messages)\n this.turnCount = state.turnCount\n this.tokensUsed = { ...state.tokensUsed }\n this.lastUuid = state.lastUuid\n }\n\n // ---------- mutators ----------\n\n incrementTurn(): void {\n this.turnCount++\n }\n\n /**\n * Mark the end of a turn: bumps the local counter AND flushes the\n * transcript writer's pending shards (under turn-end policy) plus\n * updates meta.json. The agent loop calls this once per turn.\n */\n async endTurn(): Promise<void> {\n this.turnCount++\n await this.writer.endTurn()\n }\n\n addTokenUsage(usage: TokenUsage): void {\n this.tokensUsed.input += usage.input\n this.tokensUsed.output += usage.output\n if (usage.cacheCreationInput !== undefined) {\n this.tokensUsed.cacheCreationInput =\n (this.tokensUsed.cacheCreationInput ?? 0) + usage.cacheCreationInput\n }\n if (usage.cacheReadInput !== undefined) {\n this.tokensUsed.cacheReadInput = (this.tokensUsed.cacheReadInput ?? 0) + usage.cacheReadInput\n }\n }\n\n // ---------- internal ----------\n\n private async writeEntry(entry: Entry): Promise<void> {\n await this.writer.append(entry)\n this.lastUuid = entry.uuid\n }\n\n private nextUuid(): string {\n return randomUUID()\n }\n\n private now(): string {\n return this.clock().toISOString()\n }\n}\n","/**\n * ToolExecutor — runs tools by name with input validation, timeouts,\n * cancellation, error isolation, and lifecycle hooks.\n *\n * Responsibilities:\n * 1. Resolve a tool by name from a `ToolRegistry`. Unknown name →\n * typed error result, never an exception.\n * 2. Validate the caller-supplied input against the tool's Zod schema.\n * Invalid input → typed error result.\n * 3. Build a `ToolContext` with an `AbortSignal` that fires on either\n * timeout or external cancellation.\n * 4. Race the tool's `execute()` against `timeoutMs` (when set). On\n * timeout, return an error result and abort the context signal.\n * 5. Catch any synchronous or asynchronous throw from the tool and\n * wrap it as `{ content, isError: true }`. **A misbehaving tool\n * must never crash the agent loop.**\n * 6. Fire `preToolCall` and `postToolCall` hooks. `postToolCall` runs\n * in a finally semantic — even on error, even on timeout. Hook\n * failures are isolated; they never propagate.\n *\n * The executor is stateless except for the registry reference; a\n * single instance per engine run is fine.\n */\n\nimport type { PermissionPolicy } from '../permissions/evaluator.js'\nimport type { Tool, ToolContext, ToolResult } from '../tools/contract.js'\nimport type { ToolRegistry } from '../tools/contract.js'\n\nexport interface PreToolCallEvent {\n readonly toolName: string\n readonly input: unknown\n}\n\nexport interface PostToolCallEvent {\n readonly toolName: string\n readonly input: unknown\n readonly result: ToolResult\n readonly durationMs: number\n}\n\nexport interface ToolExecutorHooks {\n readonly preToolCall?: (event: PreToolCallEvent) => void | Promise<void>\n readonly postToolCall?: (event: PostToolCallEvent) => void | Promise<void>\n}\n\nexport interface ToolExecutorOptions {\n readonly registry: ToolRegistry\n /** Per-call timeout in milliseconds. Omit or 0 to disable. */\n readonly timeoutMs?: number\n readonly hooks?: ToolExecutorHooks\n /** Permission policy. When set, every tool dispatch is checked before\n * execution. Denied tools get an isError result without running. */\n readonly permissions?: PermissionPolicy\n}\n\nexport interface ExecuteOptions {\n /** Optional external AbortSignal that can cancel the tool early. */\n readonly signal?: AbortSignal\n}\n\nconst DEFAULT_TIMEOUT_MS = 0 // 0 = no timeout\n\nexport class ToolExecutor {\n private readonly registry: ToolRegistry\n private readonly timeoutMs: number\n private readonly hooks: ToolExecutorHooks\n private readonly permissions: PermissionPolicy | undefined\n\n constructor(options: ToolExecutorOptions) {\n this.registry = options.registry\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.hooks = options.hooks ?? {}\n this.permissions = options.permissions\n }\n\n async execute(\n toolName: string,\n rawInput: unknown,\n options: ExecuteOptions = {},\n ): Promise<ToolResult> {\n const start = Date.now()\n let result: ToolResult\n\n await this.firePreHook(toolName, rawInput)\n try {\n result = await this.executeInner(toolName, rawInput, options)\n } catch (err) {\n // Subagent pause propagation — must escape the tool runtime so\n // the agentLoop can surface it as a parent pause. All other\n // errors are defensively wrapped as tool-level failures.\n if (isSubagentPausedError(err)) throw err\n result = errorResult(`Tool runtime crashed: ${describeError(err)}`)\n }\n await this.firePostHook(toolName, rawInput, result, Date.now() - start)\n return result\n }\n\n // ---------- internal ----------\n\n private async executeInner(\n toolName: string,\n rawInput: unknown,\n options: ExecuteOptions,\n ): Promise<ToolResult> {\n const tool = this.registry.get(toolName)\n if (!tool) {\n return errorResult(`Tool \"${toolName}\" not found in registry`)\n }\n\n // Permission check — before input validation so denied tools pay\n // zero parsing cost.\n if (this.permissions !== undefined) {\n const decision = this.permissions.check(toolName)\n if (!decision.allowed) {\n return errorResult(decision.reason)\n }\n }\n\n const parsed = tool.inputSchema.safeParse(rawInput)\n if (!parsed.success) {\n return errorResult(`Tool \"${toolName}\" validation failed: ${parsed.error.message}`)\n }\n\n return this.runWithTimeout(tool, parsed.data as never, options.signal)\n }\n\n private async runWithTimeout(\n tool: Tool,\n input: unknown,\n externalSignal: AbortSignal | undefined,\n ): Promise<ToolResult> {\n const controller = new AbortController()\n if (externalSignal) {\n if (externalSignal.aborted) controller.abort()\n else externalSignal.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n const ctx: ToolContext = { signal: controller.signal }\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null\n let timedOut = false\n\n const timeoutPromise =\n this.timeoutMs > 0\n ? new Promise<ToolResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true\n controller.abort()\n resolve(errorResult(`Tool \"${tool.name}\" timed out after ${this.timeoutMs}ms`))\n }, this.timeoutMs)\n })\n : null\n\n let toolPromise: Promise<ToolResult>\n try {\n // Wrap tool.execute() in a Promise.resolve so synchronous throws\n // become rejected promises and are caught uniformly.\n toolPromise = Promise.resolve().then(() => tool.execute(input as never, ctx))\n } catch (err) {\n // Truly synchronous throws before the await would be caught here,\n // but Promise.resolve().then() above already handles that path.\n return errorResult(`Tool \"${tool.name}\" threw synchronously: ${describeError(err)}`)\n }\n\n try {\n const result = timeoutPromise\n ? await Promise.race([toolPromise, timeoutPromise])\n : await toolPromise\n\n if (timedOut) {\n // The timeout already produced an error result; ignore the\n // stale tool result that may resolve later.\n return errorResult(`Tool \"${tool.name}\" timed out after ${this.timeoutMs}ms`)\n }\n return result\n } catch (err) {\n // Subagent pause propagation is NOT an error — the parent's\n // agentLoop must see the throw so it can produce its own paused\n // result with `pendingSubagent` set. Rethrow so it escapes the\n // tool-executor's \"wrap everything as isError\" semantics.\n if (isSubagentPausedError(err)) throw err\n return errorResult(`Tool \"${tool.name}\" threw: ${describeError(err)}`)\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle)\n }\n }\n\n private async firePreHook(toolName: string, input: unknown): Promise<void> {\n if (!this.hooks.preToolCall) return\n try {\n await this.hooks.preToolCall({ toolName, input })\n } catch {\n // Hook failures are isolated.\n }\n }\n\n private async firePostHook(\n toolName: string,\n input: unknown,\n result: ToolResult,\n durationMs: number,\n ): Promise<void> {\n if (!this.hooks.postToolCall) return\n try {\n await this.hooks.postToolCall({ toolName, input, result, durationMs })\n } catch {\n // Hook failures are isolated.\n }\n }\n}\n\nfunction errorResult(message: string): ToolResult {\n return { content: message, isError: true }\n}\n\n/**\n * Structural check for SubagentPausedError without importing engine/errors\n * (keeps the tool runtime dependency-light for tests that stub it).\n */\nfunction isSubagentPausedError(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as { code?: unknown; childSnapshot?: unknown }\n return e.code === 'ERR_SUBAGENT_PAUSED' && e.childSnapshot !== undefined\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","/**\n * TranscriptWriter — shard-per-flush NDJSON writer.\n *\n * Buffers `Entry` records in memory, serializes them to JSONL, and flushes\n * them as numbered shard files (`000000.jsonl`, `000001.jsonl`, ...) under\n * `{logPath}/`. Each flush also updates `meta.json`.\n *\n * ## Flush triggers\n *\n * A flush can be triggered by any of:\n * 1. **Explicit**: `flushLog()`\n * 2. **Turn boundary**: `endTurn()` + `flushPolicy === 'turn-end'`\n * 3. **Every entry**: `append()` + `flushPolicy === 'entry'`\n * 4. **Size ceiling**: buffer grows past `maxBufferBytes`\n * 5. **Idle timer**: `idleFlushMs` has elapsed since the last append\n * 6. **Close**: `close()` always flushes pending content\n *\n * The idle timer is reset on every append. If the process stays quiet\n * long enough, the buffered content lands on disk without caller action.\n *\n * ## Concurrency\n *\n * A **single-flight guard** ensures that `flushLog()` calls issued while\n * another flush is in progress coalesce — they all await the same promise.\n * This prevents double-writing a shard and race conditions on the counter.\n *\n * ## Error recovery\n *\n * On write failure, the buffer is restored and the counter is NOT bumped,\n * so the caller can retry `flushLog()` and land the same content in the\n * same shard slot. No data is lost unless the process dies between the\n * failure and the retry.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { serializeEntry, type Entry } from './entries.js'\nimport {\n createInitialMeta,\n readMeta,\n writeMeta,\n type TranscriptMeta,\n type TranscriptStatus,\n} from './meta.js'\n\nexport type FlushPolicy = 'turn-end' | 'entry' | 'manual'\n\nexport interface TranscriptWriterOptions {\n readonly storage: StorageAdapter\n readonly logPath: string\n readonly flushPolicy: FlushPolicy\n /** Buffer size ceiling in bytes; flush triggered when exceeded. */\n readonly maxBufferBytes?: number\n /** Idle duration in ms after which a flush is triggered. 0 disables. */\n readonly idleFlushMs?: number\n /** Injectable clock for deterministic timestamps in tests. */\n readonly clock?: () => Date\n /**\n * Initial shard counter — used by `engine.resume()` to continue\n * appending after a paused run without overwriting existing shards.\n * Defaults to 0 (fresh run).\n */\n readonly initialShardIndex?: number\n /**\n * Initial meta document — used by `engine.resume()` to preserve\n * counters and timestamps from the prior run. If omitted, the writer\n * starts with a fresh `pending` meta.\n */\n readonly initialMeta?: TranscriptMeta\n}\n\nconst DEFAULT_MAX_BUFFER_BYTES = 256 * 1024\nconst SHARD_DIGITS = 6\n\nexport class TranscriptWriter {\n private readonly storage: StorageAdapter\n private readonly logPath: string\n private readonly flushPolicy: FlushPolicy\n private readonly maxBufferBytes: number\n private readonly idleFlushMs: number\n private readonly clock: () => Date\n\n private buffer: string[] = []\n private bufferBytes = 0\n private nextShardIndex = 0\n private meta: TranscriptMeta\n private closed = false\n private flushInFlight: Promise<void> | null = null\n private idleTimer: ReturnType<typeof setTimeout> | null = null\n\n constructor(options: TranscriptWriterOptions) {\n this.storage = options.storage\n this.logPath = options.logPath\n this.flushPolicy = options.flushPolicy\n this.maxBufferBytes = options.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES\n this.idleFlushMs = options.idleFlushMs ?? 0\n this.clock = options.clock ?? (() => new Date())\n this.meta = options.initialMeta ?? createInitialMeta(this.clock)\n this.nextShardIndex = options.initialShardIndex ?? 0\n }\n\n // ---------- public API ----------\n\n async append(entry: Entry): Promise<void> {\n this.assertOpen()\n\n const line = serializeEntry(entry) + '\\n'\n this.buffer.push(line)\n this.bufferBytes += line.length\n this.meta = { ...this.meta, messageCount: this.meta.messageCount + 1 }\n\n // Policy: flush on every entry\n if (this.flushPolicy === 'entry') {\n await this.flushLog()\n return\n }\n\n // Safety: flush if buffer has exceeded the size ceiling\n if (this.bufferBytes >= this.maxBufferBytes) {\n await this.flushLog()\n return\n }\n\n // Schedule / reset the idle flush timer\n this.resetIdleTimer()\n }\n\n async endTurn(): Promise<void> {\n this.assertOpen()\n\n this.meta = {\n ...this.meta,\n turnCount: this.meta.turnCount + 1,\n updatedAt: this.clock().toISOString(),\n }\n\n if (this.flushPolicy === 'turn-end' && this.buffer.length > 0) {\n await this.flushLog()\n } else {\n // Even if we're not flushing a shard, persist the bumped turnCount.\n await writeMeta(this.storage, this.logPath, this.meta)\n }\n }\n\n flushLog(): Promise<void> {\n // Coalesce with any in-flight flush\n if (this.flushInFlight) return this.flushInFlight\n if (this.buffer.length === 0) return Promise.resolve()\n\n this.flushInFlight = this.doFlush().finally(() => {\n this.flushInFlight = null\n })\n return this.flushInFlight\n }\n\n async setStatus(status: TranscriptStatus): Promise<void> {\n this.meta = {\n ...this.meta,\n status,\n updatedAt: this.clock().toISOString(),\n }\n await writeMeta(this.storage, this.logPath, this.meta)\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.clearIdleTimer()\n if (this.buffer.length > 0) {\n await this.flushLog()\n }\n this.closed = true\n }\n\n // ---------- internals ----------\n\n private async doFlush(): Promise<void> {\n const shardIndex = this.nextShardIndex\n const shardName = formatShardName(shardIndex)\n const shardKey = `${this.logPath}/${shardName}`\n const content = this.buffer.join('')\n const contentBytes = this.bufferBytes\n\n // Clear buffer before write so new appends during the async write\n // don't double-land in this shard. On failure we restore.\n this.buffer = []\n this.bufferBytes = 0\n\n try {\n await this.storage.writeFile(shardKey, content)\n } catch (err) {\n // Restore buffer + keep counter — caller can retry.\n this.buffer.unshift(content)\n this.bufferBytes = contentBytes\n throw err\n }\n\n this.nextShardIndex = shardIndex + 1\n this.meta = {\n ...this.meta,\n status: this.meta.status === 'pending' ? 'running' : this.meta.status,\n lastShardIndex: shardIndex,\n shardCount: this.meta.shardCount + 1,\n updatedAt: this.clock().toISOString(),\n }\n await writeMeta(this.storage, this.logPath, this.meta)\n this.clearIdleTimer()\n }\n\n private resetIdleTimer(): void {\n if (this.idleFlushMs <= 0) return\n this.clearIdleTimer()\n this.idleTimer = setTimeout(() => {\n this.idleTimer = null\n void this.flushLog().catch(() => {\n // Swallow errors from background flush — caller's next operation\n // will observe the error via the restored buffer or directly.\n })\n }, this.idleFlushMs)\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n }\n\n private assertOpen(): void {\n if (this.closed) {\n throw new Error('TranscriptWriter is closed')\n }\n }\n}\n\nfunction formatShardName(index: number): string {\n return `${String(index).padStart(SHARD_DIGITS, '0')}.jsonl`\n}\n\n/**\n * Re-hydrate a writer's shard counter + meta from an existing transcript.\n * Used by pause/resume so the next shard lands at `lastShardIndex + 1`.\n * Returns null if there is no existing meta at `logPath`.\n */\nexport async function loadWriterState(\n storage: StorageAdapter,\n logPath: string,\n): Promise<{ nextShardIndex: number; meta: TranscriptMeta } | null> {\n const existing = await readMeta(storage, logPath)\n if (existing === null) return null\n const nextShardIndex = existing.lastShardIndex === null ? 0 : existing.lastShardIndex + 1\n return { nextShardIndex, meta: existing }\n}\n","/**\n * Transcript entry types and schemas.\n *\n * A transcript is a sequence of `Entry` records persisted as newline-\n * delimited JSON (NDJSON) sharded across numbered `.jsonl` files. This\n * module defines the entry type union, their Zod schemas, and the\n * serialize/parse helpers used by the writer and reader.\n *\n * The entry vocabulary is deliberately minimal — seven types. Everything\n * CLI-UX-specific in La-Machina's 19-type union has been dropped. Only\n * what a workflow engine needs to replay, audit, and learn from:\n *\n * user — user message (prompt, tool result from the client)\n * assistant — assistant message (text + tool_use blocks)\n * tool_result — result of a tool call dispatched by the engine\n * subagent_spawn — a child agent was created\n * subagent_done — a child agent returned its final output\n * meta — session-scoped metadata (title, tags, workflow ctx)\n * error — engine-level failure (tool crash, stream break, etc.)\n */\n\nimport { z } from 'zod'\n\n// ---------- shared base schema ----------\n\nconst UuidSchema = z.string().uuid()\nconst IsoTsSchema = z.string().datetime({ offset: true })\n\nconst TimelineBase = {\n uuid: UuidSchema,\n parentUuid: UuidSchema.nullable(),\n ts: IsoTsSchema,\n} as const\n\nconst SessionBase = {\n uuid: UuidSchema,\n ts: IsoTsSchema,\n} as const\n\n// ---------- message content blocks (permissive; tightened in Phase 4) ----------\n\nconst MessageSchema = z\n .object({\n role: z.enum(['user', 'assistant']),\n content: z.array(z.unknown()),\n })\n .strict()\n\n// ---------- individual entry schemas ----------\n\nconst UserEntrySchema = z\n .object({\n type: z.literal('user'),\n ...TimelineBase,\n message: MessageSchema,\n })\n .strict()\n\nconst AssistantEntrySchema = z\n .object({\n type: z.literal('assistant'),\n ...TimelineBase,\n message: MessageSchema,\n })\n .strict()\n\nconst ToolResultEntrySchema = z\n .object({\n type: z.literal('tool_result'),\n ...TimelineBase,\n toolUseId: z.string().min(1),\n content: z.unknown(),\n isError: z.boolean().optional(),\n })\n .strict()\n\nconst SubagentSpawnEntrySchema = z\n .object({\n type: z.literal('subagent_spawn'),\n ...TimelineBase,\n agentId: z.string().min(1),\n agentType: z.string().min(1),\n })\n .strict()\n\nconst SubagentDoneEntrySchema = z\n .object({\n type: z.literal('subagent_done'),\n ...TimelineBase,\n agentId: z.string().min(1),\n output: z.string(),\n })\n .strict()\n\nconst MetaEntrySchema = z\n .object({\n type: z.literal('meta'),\n ...SessionBase,\n key: z.string().min(1),\n value: z.unknown(),\n })\n .strict()\n\nconst ErrorEntrySchema = z\n .object({\n type: z.literal('error'),\n ...SessionBase,\n error: z\n .object({\n code: z.string().min(1),\n message: z.string(),\n stack: z.string().optional(),\n })\n .strict(),\n })\n .strict()\n\n// ---------- top-level union ----------\n\nexport const EntrySchema = z.discriminatedUnion('type', [\n UserEntrySchema,\n AssistantEntrySchema,\n ToolResultEntrySchema,\n SubagentSpawnEntrySchema,\n SubagentDoneEntrySchema,\n MetaEntrySchema,\n ErrorEntrySchema,\n])\n\nexport type Entry = z.infer<typeof EntrySchema>\nexport type UserEntry = z.infer<typeof UserEntrySchema>\nexport type AssistantEntry = z.infer<typeof AssistantEntrySchema>\nexport type ToolResultEntry = z.infer<typeof ToolResultEntrySchema>\nexport type SubagentSpawnEntry = z.infer<typeof SubagentSpawnEntrySchema>\nexport type SubagentDoneEntry = z.infer<typeof SubagentDoneEntrySchema>\nexport type MetaEntry = z.infer<typeof MetaEntrySchema>\nexport type ErrorEntry = z.infer<typeof ErrorEntrySchema>\n\n// ---------- serialization helpers ----------\n\n/**\n * Serialize an entry to a single JSON line (no trailing newline).\n * The writer is responsible for appending `\\n` between lines.\n * Throws if the entry fails schema validation — we never write\n * malformed entries to disk.\n */\nexport function serializeEntry(entry: Entry): string {\n const validated = EntrySchema.parse(entry)\n return JSON.stringify(validated)\n}\n\n/**\n * Parse a single NDJSON line into an entry. Throws if the line is\n * malformed JSON or if the parsed object does not match any entry variant.\n * The caller is responsible for providing context (shard index, line\n * number) in the thrown error message if wanted.\n */\nexport function parseEntryLine(line: string): Entry {\n if (line.length === 0) {\n throw new Error('parseEntryLine: empty line')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new Error(`parseEntryLine: invalid JSON: ${(err as Error).message}`)\n }\n const result = EntrySchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(`parseEntryLine: not a valid Entry — ${result.error.message}`)\n }\n return result.data\n}\n","/**\n * TranscriptMeta — the small sidecar at `{logPath}/meta.json` that the\n * writer updates on every flush.\n *\n * The meta document serves two purposes:\n * 1. **Fast session listing**: upstream callers (Nikaido, dashboard)\n * can stat this file to know turn count, status, and last update\n * without reading the transcript shards.\n * 2. **Resume anchor**: on pause/resume, the snapshot points to the\n * last shard index recorded here, letting the reader skip straight\n * to where it left off.\n *\n * The document is tiny (<1KB) and written frequently, so the cost of\n * overwriting on every flush is negligible. Writes go through the\n * storage adapter's atomic `writeFile`.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport type TranscriptStatus = 'pending' | 'running' | 'paused' | 'done' | 'failed'\n\nconst TranscriptMetaSchema = z\n .object({\n version: z.literal(1),\n status: z.enum(['pending', 'running', 'paused', 'done', 'failed']),\n startedAt: z.string().datetime({ offset: true }),\n updatedAt: z.string().datetime({ offset: true }),\n turnCount: z.number().int().nonnegative(),\n messageCount: z.number().int().nonnegative(),\n lastShardIndex: z.number().int().nonnegative().nullable(),\n shardCount: z.number().int().nonnegative(),\n })\n .strict()\n\nexport type TranscriptMeta = z.infer<typeof TranscriptMetaSchema>\n\nconst META_FILENAME = 'meta.json'\n\nfunction metaPath(logPath: string): string {\n return `${logPath}/${META_FILENAME}`\n}\n\n/**\n * Create a fresh meta document in `pending` state. Pass a `clock` for\n * deterministic timestamps in tests.\n */\nexport function createInitialMeta(clock: () => Date = () => new Date()): TranscriptMeta {\n const now = clock().toISOString()\n return {\n version: 1,\n status: 'pending',\n startedAt: now,\n updatedAt: now,\n turnCount: 0,\n messageCount: 0,\n lastShardIndex: null,\n shardCount: 0,\n }\n}\n\n/**\n * Read `meta.json` from `{logPath}/`. Returns `null` if the file does not\n * exist. Throws if the file is corrupted or fails schema validation — this\n * is a hard error, not a soft \"ignore the bad meta and continue\" case,\n * because a corrupted meta means we can't trust resume state.\n */\nexport async function readMeta(\n storage: StorageAdapter,\n logPath: string,\n): Promise<TranscriptMeta | null> {\n const raw = await storage.readFile(metaPath(logPath))\n if (raw === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (err) {\n throw new Error(`readMeta: invalid JSON at ${metaPath(logPath)}: ${(err as Error).message}`)\n }\n\n const result = TranscriptMetaSchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(`readMeta: schema violation at ${metaPath(logPath)}: ${result.error.message}`)\n }\n return result.data\n}\n\n/**\n * Validate + persist `meta.json`. Writes are atomic via the adapter's\n * temp+rename semantics, so a concurrent `readMeta` will either see the\n * previous version or the new one, never a partial.\n */\nexport async function writeMeta(\n storage: StorageAdapter,\n logPath: string,\n meta: TranscriptMeta,\n): Promise<void> {\n const validated = TranscriptMetaSchema.parse(meta)\n await storage.writeFile(metaPath(logPath), JSON.stringify(validated, null, 2))\n}\n","/**\n * Fork subagent — child inherits parent's full message context.\n *\n * Ported 1:1 from La-Machina's forkSubagent.ts. When `subagent_type`\n * is omitted, the Agent tool forks a child that sees the parent's\n * entire conversation history + a directive. This enables \"continue\n * this but focus on X\" delegation without starting from scratch.\n *\n * Key behaviors:\n * - Placeholder tool_results are byte-identical across all forks\n * (enables prompt cache sharing)\n * - Recursion guard via `<fork-boilerplate>` tag detection\n * - Fork children are instructed NOT to spawn sub-agents\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ContentBlockParam, MessageParam } from '@anthropic-ai/sdk/resources/messages'\n\nconst FORK_BOILERPLATE_TAG = 'fork-boilerplate'\nconst FORK_PLACEHOLDER = 'Fork started — processing in background'\n\n/**\n * Detect whether the current message history contains a fork boilerplate\n * tag — prevents recursive forking (child can't re-fork).\n */\nexport function isInForkChild(messages: readonly MessageParam[]): boolean {\n return messages.some((m) => {\n if (m.role !== 'user') return false\n const content = m.content\n if (!Array.isArray(content)) return false\n return content.some(\n (b) =>\n typeof b === 'object' &&\n b !== null &&\n 'type' in b &&\n b.type === 'text' &&\n 'text' in b &&\n typeof b.text === 'string' &&\n b.text.includes(`<${FORK_BOILERPLATE_TAG}>`),\n )\n })\n}\n\n/**\n * Build the messages a forked child sees. The child gets:\n * 1. All of the parent's existing messages (passed separately)\n * 2. A cloned assistant message with tool_use blocks\n * 3. Placeholder tool_results + fork directive\n *\n * The placeholder text is identical across all forks so the LLM\n * provider can cache-share the prefix.\n */\nexport function buildForkedMessages(\n directive: string,\n assistantContent: readonly ContentBlockParam[],\n): MessageParam[] {\n // Clone the parent's last assistant message\n const clonedAssistant: MessageParam = {\n role: 'assistant',\n content: [...assistantContent],\n }\n\n // Build placeholder tool_results for each tool_use block\n const toolUseBlocks = assistantContent.filter(\n (b): b is ContentBlockParam & { type: 'tool_use'; id: string } => b.type === 'tool_use',\n )\n\n if (toolUseBlocks.length === 0) {\n // No tool_use blocks — just the directive\n return [\n {\n role: 'user',\n content: [{ type: 'text', text: buildForkDirective(directive) }],\n },\n ]\n }\n\n // Placeholder results (byte-identical for cache sharing)\n const placeholders: ContentBlockParam[] = toolUseBlocks.map((b) => ({\n type: 'tool_result' as const,\n tool_use_id: b.id,\n content: FORK_PLACEHOLDER,\n }))\n\n const directiveMessage: MessageParam = {\n role: 'user',\n content: [...placeholders, { type: 'text', text: buildForkDirective(directive) }],\n }\n\n return [clonedAssistant, directiveMessage]\n}\n\n/**\n * Build the fork directive with rules and output format.\n * Ported from La-Machina's buildChildMessage().\n */\nfunction buildForkDirective(directive: string): string {\n return `<${FORK_BOILERPLATE_TAG}>\nSTOP. READ THIS FIRST.\n\nYou are a forked worker process. You are NOT the main agent.\n\nRULES (non-negotiable):\n1. Do NOT spawn sub-agents; execute directly.\n2. Do NOT converse, ask questions, or suggest next steps.\n3. USE your tools directly: Bash, Read, Write, etc.\n4. If you modify files, commit your changes before reporting.\n5. Do NOT emit text between tool calls. Use tools silently, then report once at the end.\n6. Stay strictly within your directive's scope.\n7. Keep your report under 500 words. Be factual and concise.\n8. Your response MUST begin with \"Scope:\".\n\nOutput format:\n Scope: <your assigned scope in one sentence>\n Result: <key findings>\n Key files: <relevant file paths>\n Files changed: <list if modified>\n Issues: <list if any>\n</${FORK_BOILERPLATE_TAG}>\n\nDirective: ${directive}`\n}\n","/**\n * Bash tool — runs a shell command via `child_process.spawn` and\n * returns its output.\n *\n * Design:\n * - The command runs through `/bin/sh -c` so callers can pipe, redirect,\n * and use shell features. (We're a server-side automation engine, not\n * a sandboxed REPL — the caller is responsible for trusting commands.)\n * - stdout and stderr are merged into the result `content` for the agent\n * to read. exit code goes into `metadata.exitCode`.\n * - On non-zero exit, the result is `isError: true` with stderr included.\n * - Output is hard-capped at 512KB to bound the memory footprint of a\n * misbehaving command. Truncation is flagged in `metadata.truncated`.\n * - Cancellation is fully signal-driven: if the tool's AbortSignal fires\n * (timeout or external), the child process gets SIGTERM, then SIGKILL\n * after a short grace period.\n *\n * The bash tool does NOT need a storage adapter — it operates against the\n * real filesystem via the OS. Use a sandbox at the engine layer if you\n * need isolation.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\n// Lazy import — `node:child_process` is not available in Cloudflare Workers.\n// The engine gates Bash registration behind `canSpawnProcesses()`, but the\n// import itself would crash Workers at module load time without this pattern.\nlet _spawn: typeof import('node:child_process').spawn | null = null\n\nasync function getSpawn(): Promise<typeof import('node:child_process').spawn> {\n if (_spawn === null) {\n const cp = await import('node:child_process')\n _spawn = cp.spawn\n }\n return _spawn\n}\n\nconst MAX_OUTPUT_BYTES = 512 * 1024\nconst SIGKILL_GRACE_MS = 500\n\n/**\n * Device paths that could hang the process or produce infinite output.\n * Ported from La-Machina's pathValidation.ts BLOCKED_DEVICE_PATHS.\n */\nconst BLOCKED_DEVICE_PATHS =\n /\\b(\\/dev\\/zero|\\/dev\\/random|\\/dev\\/urandom|\\/proc\\/kcore|\\/dev\\/sda|\\/dev\\/mem)\\b/\n\nconst inputSchema = z.object({\n command: z.string().min(1),\n cwd: z.string().min(1).optional(),\n})\n\nexport function createBashTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Bash',\n description:\n 'Execute a shell command via /bin/sh -c. Returns combined stdout+stderr and the exit code.',\n inputSchema,\n requiresNode: true,\n execute: async ({ command, cwd }, ctx) => {\n // Block commands that read from dangerous device paths\n if (BLOCKED_DEVICE_PATHS.test(command)) {\n return {\n content:\n 'Blocked: command references a dangerous device path (/dev/zero, /dev/random, /proc/kcore, etc.)',\n isError: true,\n }\n }\n\n const spawn = await getSpawn()\n return new Promise<ToolResult>((resolve) => {\n const buffers: Buffer[] = []\n let totalBytes = 0\n let truncated = false\n\n const child = spawn('/bin/sh', ['-c', command], {\n stdio: ['ignore', 'pipe', 'pipe'],\n ...(cwd !== undefined ? { cwd } : {}),\n })\n\n const append = (chunk: Buffer): void => {\n if (truncated) return\n if (totalBytes + chunk.length > MAX_OUTPUT_BYTES) {\n const remaining = MAX_OUTPUT_BYTES - totalBytes\n if (remaining > 0) buffers.push(chunk.subarray(0, remaining))\n truncated = true\n totalBytes = MAX_OUTPUT_BYTES\n return\n }\n buffers.push(chunk)\n totalBytes += chunk.length\n }\n\n child.stdout.on('data', append)\n child.stderr.on('data', append)\n\n let resolved = false\n const finish = (result: ToolResult): void => {\n if (resolved) return\n resolved = true\n cleanup()\n // Best-effort: destroy lingering pipes so the process is fully\n // released even if stdio buffers are still draining.\n child.stdout?.destroy()\n child.stderr?.destroy()\n resolve(result)\n }\n\n child.on('error', (err) => {\n finish({\n content: `Failed to spawn command: ${err.message}`,\n isError: true,\n })\n })\n\n // Listen on 'exit' rather than 'close' because 'close' waits for\n // all stdio pipes to drain; on SIGKILL the pipes can stay open\n // indefinitely while the kernel reaps the process. 'exit' fires\n // as soon as the process status changes.\n child.on('exit', (code, signal) => {\n const output = Buffer.concat(buffers).toString('utf8')\n const exitCode = typeof code === 'number' ? code : -1\n const metadata: Record<string, unknown> = { exitCode, truncated }\n if (signal) metadata.signal = signal\n\n if (exitCode === 0) {\n finish({ content: output, metadata })\n } else {\n const reason = signal ? `killed by ${signal}` : `exit ${exitCode}`\n finish({\n content: output.length > 0 ? output : `Command failed (${reason})`,\n isError: true,\n metadata,\n })\n }\n })\n\n const onAbort = (): void => {\n child.kill('SIGTERM')\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL')\n }, SIGKILL_GRACE_MS)\n }\n ctx.signal.addEventListener('abort', onAbort, { once: true })\n if (ctx.signal.aborted) onAbort()\n\n function cleanup(): void {\n ctx.signal.removeEventListener('abort', onAbort)\n }\n })\n },\n })\n}\n","/**\n * SendMessage tool — inter-agent communication within a single run.\n *\n * Routes messages to agents tracked in the SubagentRegistry:\n *\n * - **Running agent**: Message is queued via `registry.queueMessage()`.\n * The child's agentLoop drains queued messages at the start of\n * each turn (injected as a user message).\n *\n * - **Stopped agent**: Returns an error — auto-resume is deferred to v0.5.\n *\n * - **Completed agent**: Returns an error — can't send to finished agents.\n *\n * Ported from La-Machina's SendMessageTool.ts (918 lines). The engine\n * version omits mailbox/UDS/bridge routing (CLI-only) and structured\n * messages (shutdown_request, plan_approval) — headless mode doesn't\n * need them.\n */\n\nimport { z } from 'zod'\nimport type { SubagentRegistry } from '../subagent/registry.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n to: z.string().min(1).describe('Agent name (subagent_type) or agentId to send the message to.'),\n message: z.string().min(1).describe('Message content to deliver to the target agent.'),\n})\n\nexport interface SendMessageToolOptions {\n readonly registry: SubagentRegistry\n}\n\nexport function createSendMessageTool(options: SendMessageToolOptions): Tool<typeof inputSchema> {\n return defineTool({\n name: 'SendMessage',\n description:\n 'Send a text message to a running subagent by name or agentId. ' +\n \"The message is queued and delivered at the start of the agent's next turn. \" +\n 'Use this to redirect, provide additional context, or coordinate with agents you spawned.',\n inputSchema,\n execute: async ({ to, message }): Promise<ToolResult> => {\n const { registry } = options\n\n // Resolve target — try name first, then direct agentId\n let agentId = registry.findByName(to)\n if (agentId === undefined) {\n // Try as direct agentId\n try {\n registry.getDepth(to) // throws if not found\n agentId = to\n } catch {\n return {\n content: `Agent \"${to}\" not found. Available agents: check your spawned agent names.`,\n isError: true,\n }\n }\n }\n\n const status = registry.getStatus(agentId)\n\n switch (status) {\n case 'running':\n registry.queueMessage(agentId, message)\n return {\n content: `Message queued for agent \"${to}\" (${agentId}). It will be delivered at the start of the agent's next turn.`,\n metadata: { agentId, status: 'queued' },\n }\n\n case 'stopped':\n return {\n content: `Agent \"${to}\" (${agentId}) is stopped. Cannot deliver message. Consider spawning a new agent.`,\n isError: true,\n }\n\n case 'completed':\n return {\n content: `Agent \"${to}\" (${agentId}) has already completed. Cannot deliver message.`,\n isError: true,\n }\n\n default:\n return {\n content: `Agent \"${to}\" has unknown status \"${status}\".`,\n isError: true,\n }\n }\n },\n })\n}\n","/**\n * FileEdit tool — read-modify-write replacement of a substring in a file.\n *\n * Default semantics enforce uniqueness: `old_string` must occur exactly\n * once. This catches the most common LLM mistake — accidentally replacing\n * one occurrence in a file that has many. Set `replace_all: true` to\n * replace every occurrence (e.g. for renaming a variable).\n *\n * The replacement is computed in memory and written back atomically via\n * the storage adapter.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n old_string: z.string().min(1),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n})\n\nexport function createFileEditTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Edit',\n description:\n 'Replace old_string with new_string in a file. By default old_string must be unique; set replace_all to replace every occurrence.',\n inputSchema,\n execute: async ({ path, old_string, new_string, replace_all }): Promise<ToolResult> => {\n if (old_string === new_string) {\n return {\n content: 'old_string and new_string are identical — no change to make',\n isError: true,\n }\n }\n\n let original: string | null\n try {\n original = await storage.readFile(path)\n } catch (err) {\n return {\n content: `Failed to read \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n if (original === null) {\n return { content: `File not found: ${path}`, isError: true }\n }\n\n // Try exact match first, then normalized quotes (smart → ASCII).\n // Ported from La-Machina's findActualString / preserveQuoteStyle.\n let matchString = old_string\n let occurrences = countOccurrences(original, matchString)\n if (occurrences === 0) {\n const normalized = normalizeQuotes(old_string)\n if (normalized !== old_string) {\n const normOcc = countOccurrences(original, normalized)\n if (normOcc > 0) {\n matchString = normalized\n occurrences = normOcc\n }\n }\n }\n if (occurrences === 0) {\n return { content: `old_string not found in ${path}`, isError: true }\n }\n if (occurrences > 1 && !replace_all) {\n return {\n content: `old_string is not unique in ${path}: ${occurrences} occurrences found. Add more context to make it unique, or set replace_all: true.`,\n isError: true,\n }\n }\n\n const replacements = replace_all ? occurrences : 1\n // If we're using a normalized match, replace the normalized version.\n const newStringNormalized =\n matchString !== old_string ? normalizeQuotes(new_string) : new_string\n const updated = replace_all\n ? splitJoin(original, matchString, newStringNormalized)\n : original.replace(matchString, newStringNormalized)\n\n try {\n await storage.writeFile(path, updated)\n } catch (err) {\n return {\n content: `Failed to write \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n return {\n content: `Edited ${path} (${replacements} replacement${replacements === 1 ? '' : 's'})`,\n metadata: { path, replacements },\n }\n },\n })\n}\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0\n let count = 0\n let i = 0\n while ((i = haystack.indexOf(needle, i)) !== -1) {\n count++\n i += needle.length\n }\n return count\n}\n\nfunction splitJoin(haystack: string, needle: string, replacement: string): string {\n return haystack.split(needle).join(replacement)\n}\n\n/**\n * Normalize smart/curly quotes to ASCII equivalents.\n * Ported from La-Machina's preserveQuoteStyle.\n */\nfunction normalizeQuotes(s: string): string {\n return s\n .replace(/\\u201C/g, '\"') // \" → \"\n .replace(/\\u201D/g, '\"') // \" → \"\n .replace(/\\u2018/g, \"'\") // ' → '\n .replace(/\\u2019/g, \"'\") // ' → '\n}\n","/**\n * FileRead tool — read a file from the workspace storage adapter and\n * return its contents formatted with `cat -n` style line numbers.\n *\n * The line-numbered format is what Claude is trained to read in source\n * files: each line is prefixed with a 6-space-padded line number, a tab,\n * and the original line content. This format also makes line citations\n * (`file.ts:42`) trivial for the model to produce.\n *\n * Optional `offset` (1-based) and `limit` let the model paginate through\n * large files without exhausting context.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport type { FileTracker } from './fileTracker.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n offset: z.number().int().positive().optional(),\n limit: z.number().int().positive().optional(),\n /** PDF page range, e.g. \"1-5\", \"3\", \"10-20\". Max 20 pages per request. */\n pages: z.string().optional(),\n})\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'])\nconst PDF_EXTENSION = '.pdf'\n\n/** Extract file extension without requiring node:path (Workers-safe). */\nfunction extname(filePath: string): string {\n const dot = filePath.lastIndexOf('.')\n if (dot === -1 || dot === filePath.length - 1) return ''\n const slash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'))\n if (dot < slash) return ''\n return filePath.slice(dot).toLowerCase()\n}\nconst MAX_PDF_PAGES = 20\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024 // 10MB\n\nexport interface FileReadToolOptions {\n readonly storage: StorageAdapter\n readonly tracker?: FileTracker | undefined\n}\n\nexport function createFileReadTool(\n storageOrOptions: StorageAdapter | FileReadToolOptions,\n): Tool<typeof inputSchema> {\n const opts: FileReadToolOptions =\n 'readFile' in storageOrOptions ? { storage: storageOrOptions } : storageOrOptions\n const { storage, tracker } = opts\n return defineTool({\n name: 'Read',\n description:\n 'Read a file from the workspace. Text files return cat -n style line numbers. PDF files extract text per page (use pages param). Image files return base64 for visual analysis.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ path, offset, limit, pages }): Promise<ToolResult> => {\n const ext = extname(path)\n\n // PDF handling — extract text per page.\n if (ext === PDF_EXTENSION) {\n return readPdf(storage, path, pages)\n }\n\n // Image handling — return base64 for vision.\n if (IMAGE_EXTENSIONS.has(ext)) {\n return readImage(storage, path, ext)\n }\n\n // Normal text file.\n let content: string | null\n try {\n content = await storage.readFile(path)\n } catch (err) {\n return {\n content: `Failed to read \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n if (content === null) {\n return { content: `File not found: ${path}`, isError: true }\n }\n\n const lines = content.split('\\n')\n const totalLines = lines.length\n const startLine = offset ?? 1\n if (startLine > totalLines) {\n return {\n content: `Offset ${startLine} is out of range; file has ${totalLines} lines`,\n isError: true,\n }\n }\n const endLine = limit ? Math.min(startLine + limit - 1, totalLines) : totalLines\n const slice = lines.slice(startLine - 1, endLine)\n tracker?.trackRead(path)\n\n const formatted = slice\n .map((line, idx) => {\n const lineNo = String(startLine + idx).padStart(6, ' ')\n return `${lineNo}\\t${line}`\n })\n .join('\\n')\n return { content: formatted }\n },\n })\n}\n\n// ---------- PDF reading ----------\n\nasync function readPdf(\n storage: StorageAdapter,\n filePath: string,\n pagesParam?: string,\n): Promise<ToolResult> {\n let pdfParse: (data: Buffer) => Promise<{ numpages: number; text: string }>\n try {\n // Dynamic import — pdf-parse is an optional dep. If not installed,\n // the tool returns a helpful error instead of crashing.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = (await import('pdf-parse')) as any\n pdfParse = (mod.default ?? mod) as typeof pdfParse\n } catch {\n return {\n content: 'PDF reading requires the \"pdf-parse\" package. Install with: npm install pdf-parse',\n isError: true,\n }\n }\n\n let buffer: Buffer\n try {\n // Read through storage adapter (works on both local FS and R2/Workers)\n const content = await storage.readFile(filePath)\n if (content === null) {\n return { content: `PDF file not found: \"${filePath}\"`, isError: true }\n }\n buffer = Buffer.from(content, 'binary')\n } catch (err) {\n return {\n content: `Failed to read PDF \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n let parsed: { numpages: number; text: string }\n try {\n parsed = await pdfParse(buffer)\n } catch (err) {\n return {\n content: `Failed to parse PDF \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Page range filtering.\n const totalPages = parsed.numpages\n let startPage = 1\n let endPage = totalPages\n\n if (pagesParam) {\n const range = parsePageRange(pagesParam, totalPages)\n if (range.error) {\n return { content: range.error, isError: true }\n }\n startPage = range.start\n endPage = range.end\n }\n\n if (endPage - startPage + 1 > MAX_PDF_PAGES) {\n return {\n content: `Too many pages requested (${endPage - startPage + 1}). Maximum ${MAX_PDF_PAGES} pages per request. Use the \"pages\" parameter to specify a range.`,\n isError: true,\n }\n }\n\n // pdf-parse returns all text concatenated. For page-level output,\n // we note the total pages and return the full text (pdf-parse doesn't\n // expose per-page text without a custom renderer).\n const header = `PDF: ${filePath} (${totalPages} pages${pagesParam ? `, showing ${pagesParam}` : ''})\\n\\n`\n return {\n content: header + parsed.text,\n metadata: { pages: totalPages, format: 'pdf' },\n }\n}\n\nfunction parsePageRange(\n spec: string,\n total: number,\n):\n | { start: number; end: number; error?: undefined }\n | { start: number; end: number; error: string } {\n const parts = spec.split('-').map((s) => s.trim())\n if (parts.length === 1) {\n const page = parseInt(parts[0]!, 10)\n if (isNaN(page) || page < 1 || page > total) {\n return { start: 1, end: 1, error: `Invalid page \"${spec}\". File has ${total} pages.` }\n }\n return { start: page, end: page }\n }\n if (parts.length === 2) {\n const start = parseInt(parts[0]!, 10)\n const end = parseInt(parts[1]!, 10)\n if (isNaN(start) || isNaN(end) || start < 1 || end > total || start > end) {\n return { start: 1, end: 1, error: `Invalid page range \"${spec}\". File has ${total} pages.` }\n }\n return { start, end }\n }\n return { start: 1, end: 1, error: `Invalid page range format \"${spec}\". Use \"3\" or \"1-5\".` }\n}\n\n// ---------- Image reading ----------\n\nasync function readImage(\n storage: StorageAdapter,\n filePath: string,\n ext: string,\n): Promise<ToolResult> {\n let buffer: Buffer\n try {\n // Read through storage adapter (works on both local FS and R2/Workers)\n const content = await storage.readFile(filePath)\n if (content === null) {\n return { content: `Image file not found: \"${filePath}\"`, isError: true }\n }\n buffer = Buffer.from(content, 'binary')\n } catch (err) {\n return {\n content: `Failed to read image \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (buffer.length > MAX_IMAGE_BYTES) {\n return {\n content: `Image \"${filePath}\" is too large (${(buffer.length / 1024 / 1024).toFixed(1)}MB). Maximum ${MAX_IMAGE_BYTES / 1024 / 1024}MB.`,\n isError: true,\n }\n }\n\n const mimeMap: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.bmp': 'image/bmp',\n '.svg': 'image/svg+xml',\n }\n const mimeType = mimeMap[ext] ?? 'application/octet-stream'\n const base64 = buffer.toString('base64')\n\n return {\n content: `[Image: ${filePath} (${mimeType}, ${(buffer.length / 1024).toFixed(1)}KB)]\\n\\nBase64 data is included in the metadata for visual analysis.`,\n metadata: {\n format: 'image',\n mimeType,\n bytes: buffer.length,\n base64,\n },\n }\n}\n","/**\n * FileWrite tool — write a file via the storage adapter.\n *\n * Staleness check (ported from La-Machina): before writing, the tool\n * verifies the file was previously read OR is a new file. This prevents\n * blind overwrites of files the model hasn't seen, catching a common\n * class of bugs in multi-tool workflows.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport type { FileTracker } from './fileTracker.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n content: z.string(),\n})\n\nexport interface FileWriteToolOptions {\n readonly storage: StorageAdapter\n readonly tracker?: FileTracker | undefined\n}\n\nexport function createFileWriteTool(\n storageOrOptions: StorageAdapter | FileWriteToolOptions,\n): Tool<typeof inputSchema> {\n const opts: FileWriteToolOptions =\n 'readFile' in storageOrOptions ? { storage: storageOrOptions } : storageOrOptions\n const { storage, tracker } = opts\n\n return defineTool({\n name: 'Write',\n description: 'Write a file to the workspace. Creates parents and overwrites existing files.',\n inputSchema,\n execute: async ({ path, content }): Promise<ToolResult> => {\n // Staleness check: if the file exists and was never read, reject.\n if (tracker !== undefined) {\n const exists = await storage.exists(path)\n if (exists && !tracker.wasRead(path)) {\n return {\n content:\n `Cannot write \"${path}\": this file exists but you haven't read it yet. ` +\n `Use the Read tool first to see the current contents, then retry the write.`,\n isError: true,\n }\n }\n }\n\n try {\n await storage.writeFile(path, content)\n } catch (err) {\n return {\n content: `Failed to write \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Track the write as a \"read\" so subsequent writes to the same\n // file within the same run don't trigger the staleness check.\n tracker?.trackRead(path)\n\n return {\n content: `Wrote ${content.length} bytes to ${path}`,\n metadata: { path, bytes: Buffer.byteLength(content, 'utf8') },\n }\n },\n })\n}\n","/**\n * Glob tool — find files in the workspace by glob pattern.\n *\n * Walks the storage adapter starting at `path` (defaults to root) and\n * returns every relative path that matches `pattern`. Pattern matching\n * is delegated to picomatch, which understands the standard glob\n * vocabulary: `*`, `**`, `?`, `[abc]`, `{a,b}`, dotfiles via the dot\n * option, etc.\n *\n * Results are sorted by mtime descending — recently-modified files\n * surface first, which is what the model usually wants when searching\n * for \"where did I just edit this\".\n */\n\nimport picomatch from 'picomatch'\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport { walkAdapter } from './walkAdapter.js'\n\nconst inputSchema = z.object({\n pattern: z.string().min(1),\n path: z.string().optional(),\n})\n\nconst MAX_RESULTS = 1000\n\nexport function createGlobTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Glob',\n description:\n 'Find files by glob pattern. Supports *, **, ?, [abc], {a,b}. Returns paths sorted by mtime descending.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ pattern, path: searchPath }): Promise<ToolResult> => {\n const startPath = searchPath ?? ''\n const matcher = picomatch(pattern, { dot: true })\n\n const matches: Array<{ path: string; mtime: Date }> = []\n try {\n for await (const filePath of walkAdapter(storage, startPath, {\n maxFiles: MAX_RESULTS * 5,\n })) {\n // The matcher operates on the path RELATIVE to the search path,\n // so a pattern like `*.ts` matches `a.ts` even when the file\n // lives at `src/a.ts` (caller can scope via `path`).\n const relative =\n startPath && filePath.startsWith(`${startPath}/`)\n ? filePath.slice(startPath.length + 1)\n : filePath\n if (!matcher(relative)) continue\n\n let mtime = new Date(0)\n try {\n const stat = await storage.stat(filePath)\n if (stat) mtime = stat.mtime\n } catch {\n // ignore stat failures, sort by epoch\n }\n matches.push({ path: relative, mtime })\n if (matches.length >= MAX_RESULTS) break\n }\n } catch (err) {\n return {\n content: `Glob failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (matches.length === 0) {\n return {\n content: `No matches for pattern \"${pattern}\" in ${startPath || '.'}`,\n metadata: { count: 0 },\n }\n }\n\n matches.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n const lines = matches.map((m) => m.path).join('\\n')\n return {\n content: lines,\n metadata: { count: matches.length },\n }\n },\n })\n}\n","/**\n * walkAdapter — recursive walker over a `StorageAdapter` directory tree.\n *\n * Yields every file path (relative to the adapter root) reachable from\n * `startPath`. Used by the Glob and Grep tools, neither of which can\n * call `fs.readdir` directly because the adapter abstracts the backend.\n *\n * The walker uses `listDir` + `isDirectory` per entry. On R2 this is\n * cheap (everything is a single LIST/HEAD pair); on local fs this is\n * a few syscalls per directory. There are no symlink loops to worry\n * about because the adapter's path normalization rejects them.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface WalkOptions {\n /** Maximum directory depth to descend. Unbounded by default. */\n readonly maxDepth?: number\n /** Maximum number of files to yield. Unbounded by default. */\n readonly maxFiles?: number\n}\n\n/**\n * Walk a directory tree starting at `startPath` (relative to the\n * adapter root). Yields every file path encountered.\n */\nexport async function* walkAdapter(\n adapter: StorageAdapter,\n startPath: string,\n options: WalkOptions = {},\n): AsyncGenerator<string, void, void> {\n const maxDepth = options.maxDepth ?? Infinity\n const maxFiles = options.maxFiles ?? Infinity\n let yielded = 0\n\n // Stack-based DFS so we don't recurse — keeps the call stack flat\n // even on very deep trees.\n const stack: Array<{ path: string; depth: number }> = [{ path: startPath, depth: 0 }]\n\n while (stack.length > 0) {\n if (yielded >= maxFiles) return\n const current = stack.pop()\n if (!current) return\n\n let entries: string[]\n try {\n entries = await adapter.listDir(current.path)\n } catch {\n continue\n }\n\n // Sort for deterministic output across both backends.\n entries.sort()\n\n for (const name of entries) {\n const childPath = current.path === '' ? name : `${current.path}/${name}`\n const isDir = await adapter.isDirectory(childPath)\n if (isDir) {\n if (current.depth + 1 < maxDepth) {\n stack.push({ path: childPath, depth: current.depth + 1 })\n }\n } else {\n yield childPath\n yielded++\n if (yielded >= maxFiles) return\n }\n }\n }\n}\n","/**\n * Grep tool — regex search across files.\n *\n * Two implementations:\n * 1. **ripgrep (preferred):** Spawns `rg` binary on PATH for 10-100x\n * faster search. Supports context lines, multiline, type filters,\n * pagination. Ported from La-Machina's GrepTool.\n * 2. **JS fallback:** When `rg` is not on PATH, falls back to the\n * original in-process RegExp scanner. Slower but always works.\n *\n * The tool checks for `rg` availability once at construction time.\n */\n\nimport picomatch from 'picomatch'\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport { walkAdapter } from './walkAdapter.js'\n\nconst inputSchema = z.object({\n pattern: z.string().min(1),\n path: z.string().optional(),\n glob: z.string().optional(),\n type: z.string().optional(),\n output_mode: z.enum(['content', 'files_with_matches', 'count']).optional(),\n '-i': z.boolean().optional(),\n '-n': z.boolean().optional(),\n '-A': z.number().int().nonnegative().optional(),\n '-B': z.number().int().nonnegative().optional(),\n '-C': z.number().int().nonnegative().optional(),\n context: z.number().int().nonnegative().optional(),\n multiline: z.boolean().optional(),\n head_limit: z.number().int().nonnegative().optional(),\n offset: z.number().int().nonnegative().optional(),\n})\n\nconst MAX_FILES_SCANNED = 5_000\nconst MAX_MATCHES_PER_FILE = 100\nconst DEFAULT_HEAD_LIMIT = 250\n\n// Lazy child_process import — not available in Cloudflare Workers.\nlet _cpModule: typeof import('node:child_process') | null | false = null\nlet _cpPromise: Promise<typeof import('node:child_process') | null> | null = null\n\nasync function getChildProcessAsync(): Promise<typeof import('node:child_process') | null> {\n if (_cpModule === false) return null\n if (_cpModule !== null) return _cpModule\n if (_cpPromise !== null) return _cpPromise\n _cpPromise = import('node:child_process')\n .then((m) => {\n _cpModule = m\n return m\n })\n .catch(() => {\n _cpModule = false\n return null\n })\n return _cpPromise\n}\n\nfunction getChildProcessSync(): typeof import('node:child_process') | null {\n if (_cpModule === false) return null\n if (_cpModule !== null) return _cpModule\n // If async hasn't resolved yet, can't use it synchronously\n return null\n}\n\nfunction hasRipgrep(): boolean {\n // Pre-load child_process at tool creation time (async, best-effort)\n getChildProcessAsync().catch(() => {})\n // For the sync check, try require (works in CJS bundles)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n _cpModule = require('node:child_process') as typeof import('node:child_process')\n } catch {\n _cpModule = false\n return false\n }\n try {\n _cpModule.execSync('which rg', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nexport function createGrepTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n const rgAvailable = hasRipgrep()\n\n return defineTool({\n name: 'Grep',\n description:\n 'Search for a regex pattern across files. Supports ripgrep when available (context lines, multiline, type filters, pagination). Falls back to JS RegExp scanner.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async (input, ctx): Promise<ToolResult> => {\n if (rgAvailable && input.path !== undefined) {\n // Use ripgrep for filesystem searches with an explicit path.\n return runRipgrep(input, ctx)\n }\n // JS fallback for storage-adapter-based searches or when rg is missing.\n return runJsFallback(input, storage)\n },\n })\n}\n\n// ---------- ripgrep implementation ----------\n\nasync function runRipgrep(\n input: z.infer<typeof inputSchema>,\n ctx: { signal: AbortSignal },\n): Promise<ToolResult> {\n const args: string[] = []\n const outputMode = input.output_mode ?? 'files_with_matches'\n const headLimit = input.head_limit ?? DEFAULT_HEAD_LIMIT\n\n // Output mode flags\n if (outputMode === 'files_with_matches') args.push('-l')\n if (outputMode === 'count') args.push('-c')\n if (outputMode === 'content') {\n const showLineNumbers = input['-n'] !== false\n if (showLineNumbers) args.push('-n')\n }\n\n // Search options\n if (input['-i']) args.push('-i')\n if (input.multiline) args.push('-U', '--multiline-dotall')\n if (input.glob) args.push('--glob', input.glob)\n if (input.type) args.push('--type', input.type)\n\n // Context lines\n const contextLines = input['-C'] ?? input.context\n if (contextLines !== undefined) args.push('-C', String(contextLines))\n else {\n if (input['-A'] !== undefined) args.push('-A', String(input['-A']))\n if (input['-B'] !== undefined) args.push('-B', String(input['-B']))\n }\n\n // Cap per-file matches\n args.push('--max-count', String(MAX_MATCHES_PER_FILE))\n\n // Pattern and path\n args.push('--', input.pattern)\n if (input.path) args.push(input.path)\n\n const cp = getChildProcessSync() ?? (await getChildProcessAsync())\n if (cp === null) {\n return { content: 'ripgrep not available in this runtime', isError: true }\n }\n\n return new Promise<ToolResult>((resolve) => {\n const child = cp.spawn('rg', args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n timeout: 30_000,\n })\n\n let stdout = ''\n let stderr = ''\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString()\n // Early truncation if we've collected way more than we need.\n if (stdout.length > 1_000_000) {\n child.kill('SIGTERM')\n }\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n\n if (ctx.signal.aborted) {\n child.kill('SIGTERM')\n } else {\n ctx.signal.addEventListener('abort', () => child.kill('SIGTERM'), { once: true })\n }\n\n child.on('close', (code) => {\n if (code === 1 && stdout.length === 0) {\n // rg exit 1 = no matches (not an error).\n resolve({\n content: `No matches found`,\n metadata: { filesMatched: 0, engine: 'ripgrep' },\n })\n return\n }\n if (code !== 0 && code !== 1 && stderr.length > 0) {\n resolve({\n content: `Grep error: ${stderr.slice(0, 500)}`,\n isError: true,\n metadata: { engine: 'ripgrep', exitCode: code },\n })\n return\n }\n\n // Apply offset + head_limit pagination.\n let lines = stdout.split('\\n')\n if (input.offset) lines = lines.slice(input.offset)\n if (headLimit > 0) lines = lines.slice(0, headLimit)\n const output = lines.join('\\n').trim()\n\n resolve({\n content: output || 'No matches found',\n metadata: {\n engine: 'ripgrep',\n linesReturned: lines.length,\n },\n })\n })\n })\n}\n\n// ---------- JS fallback implementation ----------\n\nasync function runJsFallback(\n input: z.infer<typeof inputSchema>,\n storage: StorageAdapter,\n): Promise<ToolResult> {\n const flags = input['-i'] ? 'gi' : 'g'\n let regex: RegExp\n try {\n regex = new RegExp(input.pattern, flags + (input.multiline ? 's' : ''))\n } catch (err) {\n return {\n content: `Invalid regex: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const matcher = input.glob ? picomatch(input.glob, { dot: true }) : null\n const startPath = input.path ?? ''\n const outputMode = input.output_mode ?? 'content'\n const headLimit = input.head_limit ?? DEFAULT_HEAD_LIMIT\n\n const fileResults: Array<{ path: string; matches: Array<{ line: number; text: string }> }> = []\n let scanned = 0\n\n try {\n for await (const filePath of walkAdapter(storage, startPath, {\n maxFiles: MAX_FILES_SCANNED,\n })) {\n scanned++\n const relative =\n startPath && filePath.startsWith(`${startPath}/`)\n ? filePath.slice(startPath.length + 1)\n : filePath\n if (matcher && !matcher(relative)) continue\n\n let content: string | null\n try {\n content = await storage.readFile(filePath)\n } catch {\n continue\n }\n if (content === null) continue\n\n const lines = content.split('\\n')\n const matches: Array<{ line: number; text: string }> = []\n for (let i = 0; i < lines.length; i++) {\n if (matches.length >= MAX_MATCHES_PER_FILE) break\n const line = lines[i]!\n if (regex.test(line)) {\n matches.push({ line: i + 1, text: line })\n }\n // Reset lastIndex for global regex.\n regex.lastIndex = 0\n }\n if (matches.length > 0) {\n fileResults.push({ path: relative, matches })\n }\n }\n } catch (err) {\n return {\n content: `Grep failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (fileResults.length === 0) {\n return {\n content: `No matches for \"${input.pattern}\" (${scanned} files scanned)`,\n metadata: { filesScanned: scanned, filesMatched: 0, engine: 'js-fallback' },\n }\n }\n\n const formatted = formatJsResults(fileResults, outputMode, headLimit)\n return {\n content: formatted,\n metadata: {\n filesScanned: scanned,\n filesMatched: fileResults.length,\n totalMatches: fileResults.reduce((acc, f) => acc + f.matches.length, 0),\n engine: 'js-fallback',\n },\n }\n}\n\nfunction formatJsResults(\n results: ReadonlyArray<{ path: string; matches: ReadonlyArray<{ line: number; text: string }> }>,\n mode: 'content' | 'files_with_matches' | 'count',\n limit: number,\n): string {\n if (mode === 'files_with_matches') {\n return results\n .slice(0, limit)\n .map((r) => r.path)\n .join('\\n')\n }\n if (mode === 'count') {\n return results\n .slice(0, limit)\n .map((r) => `${r.path}:${r.matches.length}`)\n .join('\\n')\n }\n const lines: string[] = []\n for (const r of results) {\n for (const m of r.matches) {\n lines.push(`${r.path}:${m.line}:${m.text}`)\n if (lines.length >= limit) {\n lines.push(`... (truncated at ${limit} lines)`)\n return lines.join('\\n')\n }\n }\n }\n return lines.join('\\n')\n}\n","/**\n * WebFetch tool — fetch a URL and return its content as plain text.\n *\n * Design:\n * - Uses `fetch` (configurable for tests). Default is `globalThis.fetch`.\n * - Honors `ToolContext.signal` for cancellation; passes it straight\n * into `fetch({ signal })`.\n * - HTML responses get a basic tag-stripping pass: `<script>` and\n * `<style>` blocks are removed entirely, then all remaining tags are\n * stripped, then whitespace is collapsed. This is good enough for\n * feeding doc pages to the model. v0.2 may swap in a real Markdown\n * converter (turndown / html-to-md) if richer fidelity is needed.\n * - Output is hard-capped at 256 KB to bound memory.\n * - Non-2xx responses become `isError` results with the status code.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n url: z.string().url(),\n prompt: z.string().optional(),\n})\n\nconst MAX_OUTPUT_BYTES = 256 * 1024\n\nexport interface WebFetchToolOptions {\n /** Custom fetch implementation. Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. */\n readonly timeoutMs?: number\n}\n\nexport function createWebFetchTool(options: WebFetchToolOptions = {}): Tool<typeof inputSchema> {\n const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n return defineTool({\n name: 'WebFetch',\n description:\n 'Fetch a URL and return its content as plain text. HTML is stripped to its readable text.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ url }, ctx): Promise<ToolResult> => {\n let response: Response\n try {\n // Use redirect: 'manual' to detect cross-host redirects.\n // Ported from La-Machina's WebFetchTool.\n response = await fetchImpl(url, { signal: ctx.signal, redirect: 'manual' })\n } catch (err) {\n return {\n content: `Failed to fetch ${url}: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Detect redirects — if the redirect goes to a different host,\n // report it instead of silently following (might be a login page).\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location')\n if (location) {\n try {\n const originalHost = new URL(url).host\n const redirectHost = new URL(location, url).host\n if (originalHost !== redirectHost) {\n return {\n content:\n `URL redirected to a different host.\\n` +\n `Original: ${url}\\n` +\n `Redirect: ${location}\\n\\n` +\n `Make a new WebFetch request with the redirect URL if you want to follow it.`,\n metadata: { redirect: true, location, status: response.status },\n }\n }\n } catch {\n // URL parse failed — fall through to re-fetch with follow.\n }\n }\n // Same-host redirect or unparseable — re-fetch with follow.\n try {\n response = await fetchImpl(url, { signal: ctx.signal })\n } catch (err) {\n return {\n content: `Failed to fetch ${url} (after redirect): ${(err as Error).message}`,\n isError: true,\n }\n }\n }\n\n const contentType = response.headers.get('content-type') ?? 'application/octet-stream'\n\n if (!response.ok) {\n const body = await safeText(response)\n return {\n content: `HTTP ${response.status} from ${url}: ${body.slice(0, 500)}`,\n isError: true,\n metadata: { status: response.status, contentType },\n }\n }\n\n let raw: string\n try {\n raw = await response.text()\n } catch (err) {\n return {\n content: `Failed to read body from ${url}: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const text = isHtml(contentType) ? htmlToText(raw) : raw\n const { content, truncated } = truncate(text, MAX_OUTPUT_BYTES)\n\n return {\n content,\n metadata: {\n status: response.status,\n contentType,\n bytes: Buffer.byteLength(content, 'utf8'),\n truncated,\n },\n }\n },\n })\n}\n\nfunction isHtml(contentType: string): boolean {\n return contentType.toLowerCase().includes('html')\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n}\n\nfunction truncate(text: string, maxBytes: number): { content: string; truncated: boolean } {\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) {\n return { content: text, truncated: false }\n }\n // Truncate by character count as a rough proxy. UTF-8 may slightly\n // over- or under-shoot but never crosses a code point boundary.\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1\n if (Buffer.byteLength(text.slice(0, mid), 'utf8') <= maxBytes) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n return { content: text.slice(0, lo) + '\\n... (truncated)', truncated: true }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text()\n } catch {\n return ''\n }\n}\n","/**\n * FileTracker — tracks which files have been read during a run.\n *\n * Shared between Read and Write tools within a single run. The Write\n * tool checks this before writing: if a file exists but was never read,\n * the write is rejected with isError so the model reads first.\n *\n * Ported from La-Machina's read-before-write invariant.\n */\n\nexport class FileTracker {\n private readonly readPaths = new Set<string>()\n\n /** Mark a file as read. Called by the Read tool after a successful read. */\n trackRead(path: string): void {\n this.readPaths.add(normalizePath(path))\n }\n\n /** Check if a file was previously read. */\n wasRead(path: string): boolean {\n return this.readPaths.has(normalizePath(path))\n }\n}\n\nfunction normalizePath(p: string): string {\n // Normalize trailing slashes and consecutive slashes.\n return p.replace(/\\/+/g, '/').replace(/\\/$/, '')\n}\n","/**\n * WebSearch — search the web and return results.\n *\n * Strategy: uses WebFetch to query a search-engine-friendly URL and\n * extract results. When a proper search API is configured in the\n * future, this tool can be swapped without changing the tool contract.\n *\n * Current implementation: fetches a DuckDuckGo lite HTML page, strips\n * tags, and returns the text. The model interprets the search results\n * from the raw text content.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(2),\n max_results: z.number().int().positive().optional(),\n})\n\nexport function createWebSearchTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'WebSearch',\n description:\n 'Search the web for information. Returns search result snippets. Use when you need current information not available in local files.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query }): Promise<ToolResult> => {\n const encoded = encodeURIComponent(query)\n const url = `https://lite.duckduckgo.com/lite/?q=${encoded}`\n\n let response: Response\n try {\n response = await fetch(url, {\n headers: {\n 'User-Agent': 'la-machina-engine/0.2.0',\n Accept: 'text/html',\n },\n })\n } catch (err) {\n return {\n content: `Web search failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (!response.ok) {\n return {\n content: `Web search returned HTTP ${response.status}`,\n isError: true,\n }\n }\n\n let html: string\n try {\n html = await response.text()\n } catch (err) {\n return {\n content: `Failed to read search response: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const text = htmlToText(html)\n const trimmed = text.slice(0, 8000) // cap output\n\n return {\n content: `Search results for \"${query}\":\\n\\n${trimmed}`,\n metadata: { query, bytes: trimmed.length },\n }\n },\n })\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n}\n","/**\n * Sleep tool — pauses execution for a given number of milliseconds.\n * Honors the ToolContext's AbortSignal for early cancellation.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n durationMs: z.number().int().nonnegative().max(300_000),\n reason: z.string().optional(),\n})\n\nexport function createSleepTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Sleep',\n description:\n 'Pause execution for the given number of milliseconds (max 300000 = 5 minutes). Use when you need to wait for an external process or rate limit.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ durationMs, reason }, ctx): Promise<ToolResult> => {\n if (durationMs === 0) {\n return { content: 'Slept for 0ms (no-op).' }\n }\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, durationMs)\n if (typeof timer.unref === 'function') timer.unref()\n if (ctx.signal.aborted) {\n clearTimeout(timer)\n resolve()\n } else {\n ctx.signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer)\n resolve()\n },\n { once: true },\n )\n }\n })\n const cancelled = ctx.signal.aborted\n return {\n content: cancelled\n ? `Sleep cancelled after partial wait (requested ${durationMs}ms).`\n : `Slept for ${durationMs}ms.${reason ? ` Reason: ${reason}` : ''}`,\n metadata: { durationMs, cancelled },\n }\n },\n })\n}\n","/**\n * ToolSearch — search registered tools by keyword.\n * Ported from La-Machina's deferred-tool search logic.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolRegistry, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n max_results: z.number().int().positive().optional(),\n})\n\nexport function createToolSearchTool(registry: ToolRegistry): Tool<typeof inputSchema> {\n return defineTool({\n name: 'ToolSearch',\n description:\n 'Search the available tools by keyword. Returns matching tool names and descriptions. Use when you want to discover what tools are available for a task.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query, max_results }): Promise<ToolResult> => {\n const limit = max_results ?? 10\n const q = query.toLowerCase()\n const all = registry.list()\n\n const scored = all\n .map((tool) => {\n let score = 0\n const nameLower = tool.name.toLowerCase()\n const descLower = tool.description.toLowerCase()\n\n if (nameLower === q) score += 100\n if (nameLower.includes(q)) score += 50\n if (descLower.includes(q)) score += 20\n\n // Score individual query words.\n for (const word of q.split(/\\s+/)) {\n if (nameLower.includes(word)) score += 10\n if (descLower.includes(word)) score += 5\n }\n\n return { tool, score }\n })\n .filter(({ score }) => score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n\n if (scored.length === 0) {\n return {\n content: `No tools found matching \"${query}\". ${all.length} tools are registered.`,\n metadata: { totalTools: all.length, matches: 0 },\n }\n }\n\n const lines = scored.map(({ tool }) => `- **${tool.name}**: ${tool.description}`)\n return {\n content: `Found ${scored.length} tool(s) matching \"${query}\":\\n${lines.join('\\n')}`,\n metadata: { totalTools: all.length, matches: scored.length },\n }\n },\n })\n}\n","/**\n * Memorize tool — lets the model explicitly save facts to smart memory.\n * Wires to the existing SmartMemory façade (Hippocampus backend).\n */\n\nimport { z } from 'zod'\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n text: z.string().min(1),\n kind: z.enum(['rule', 'lesson']).default('lesson'),\n topic: z.string().optional(),\n})\n\nexport function createMemorizeTool(memory: SmartMemory): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Memorize',\n description:\n 'Save a fact, rule, or lesson to persistent memory. Memories survive across runs and are included in the system prompt of future runs. Use \"rule\" for behavioral constraints (always/never do X). Use \"lesson\" for learnings and observations.',\n inputSchema,\n execute: async ({ text, kind, topic }): Promise<ToolResult> => {\n if (memory.mode === 'off' || memory.mode === 'read-only') {\n return {\n content: `Cannot memorize: memory mode is \"${memory.mode}\". Set config.memory.mode to \"read-write\" to enable.`,\n isError: true,\n }\n }\n\n if (kind === 'rule') {\n await memory.encodeRule(text, 'always')\n return {\n content: `Memorized rule: \"${text.slice(0, 80)}${text.length > 80 ? '…' : ''}\"`,\n metadata: { kind: 'rule' },\n }\n }\n\n await memory.encodeLesson(text, topic)\n return {\n content: `Memorized lesson: \"${text.slice(0, 80)}${text.length > 80 ? '…' : ''}\"${topic ? ` (topic: ${topic})` : ''}`,\n metadata: { kind: 'lesson', topic },\n }\n },\n })\n}\n","/**\n * Recall tool — search persistent memory for previously saved facts.\n * Wires to SmartMemory (Hippocampus recall) + EpisodicMemory search.\n */\n\nimport { z } from 'zod'\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n scope: z.enum(['identity', 'rules', 'lessons', 'all']).default('all'),\n topic: z.string().optional(),\n})\n\nexport function createRecallTool(memory: SmartMemory): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Recall',\n description:\n 'Search persistent memory for previously saved facts, rules, and lessons. Use when you need to recall information from prior runs or check what rules/lessons are stored.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query, scope, topic }): Promise<ToolResult> => {\n if (memory.mode === 'off') {\n return {\n content: 'Cannot recall: memory mode is \"off\".',\n isError: true,\n }\n }\n\n const parts: string[] = []\n\n if (scope === 'identity' || scope === 'all') {\n const identity = await memory.recallIdentity()\n if (identity.length > 0) parts.push(`## Identity\\n${identity}`)\n }\n\n if (scope === 'rules' || scope === 'all') {\n const rules = await memory.recallRules()\n if (rules.length > 0) parts.push(`## Rules\\n${rules}`)\n }\n\n if (scope === 'lessons' || scope === 'all') {\n const lessons = await memory.recallLessons()\n if (lessons.length > 0) parts.push(`## Lessons\\n${lessons}`)\n }\n\n if (topic !== undefined) {\n const topicContent = await memory.recallTopic(topic)\n if (topicContent.length > 0) parts.push(`## Topic: ${topic}\\n${topicContent}`)\n }\n\n if (parts.length === 0) {\n return {\n content: `No memories found${scope !== 'all' ? ` in scope \"${scope}\"` : ''}.`,\n metadata: { found: false },\n }\n }\n\n // Simple relevance filter: if the query mentions specific words,\n // highlight lines that contain them.\n const content = parts.join('\\n\\n')\n return {\n content: `Memory recall for \"${query}\":\\n\\n${content}`,\n metadata: { found: true, scope, charCount: content.length },\n }\n },\n })\n}\n","/**\n * NotebookEdit — edit Jupyter .ipynb notebook cells.\n * Supports insert, replace, and delete operations on cells by index.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n notebook_path: z.string().min(1),\n edit_mode: z.enum(['replace', 'insert', 'delete']).default('replace'),\n cell_index: z.number().int().nonnegative(),\n new_source: z.string().optional(),\n cell_type: z.enum(['code', 'markdown']).optional(),\n})\n\ninterface NotebookCell {\n cell_type: string\n source: string[]\n metadata: Record<string, unknown>\n outputs?: unknown[]\n execution_count?: number | null\n}\n\ninterface Notebook {\n nbformat: number\n nbformat_minor: number\n metadata: Record<string, unknown>\n cells: NotebookCell[]\n}\n\nexport function createNotebookEditTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'NotebookEdit',\n description:\n 'Edit a Jupyter notebook (.ipynb) by inserting, replacing, or deleting cells. Specify the cell_index (0-based) and the operation.',\n inputSchema,\n execute: async ({\n notebook_path,\n edit_mode,\n cell_index,\n new_source,\n cell_type,\n }): Promise<ToolResult> => {\n const raw = await storage.readFile(notebook_path)\n if (raw === null) {\n return {\n content: `Notebook not found: ${notebook_path}`,\n isError: true,\n }\n }\n\n let notebook: Notebook\n try {\n notebook = JSON.parse(raw) as Notebook\n } catch {\n return {\n content: `Failed to parse notebook JSON: ${notebook_path}`,\n isError: true,\n }\n }\n\n if (!Array.isArray(notebook.cells)) {\n return {\n content: `Invalid notebook format: missing cells array`,\n isError: true,\n }\n }\n\n const cellCount = notebook.cells.length\n\n if (edit_mode === 'delete') {\n if (cell_index >= cellCount) {\n return {\n content: `Cell index ${cell_index} out of range (notebook has ${cellCount} cells).`,\n isError: true,\n }\n }\n notebook.cells.splice(cell_index, 1)\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Deleted cell at index ${cell_index}. Notebook now has ${notebook.cells.length} cells.`,\n metadata: { operation: 'delete', cell_index, cellCount: notebook.cells.length },\n }\n }\n\n if (new_source === undefined) {\n return {\n content: `new_source is required for ${edit_mode} operations.`,\n isError: true,\n }\n }\n\n const sourceLines = new_source\n .split('\\n')\n .map((line, i, arr) => (i < arr.length - 1 ? line + '\\n' : line))\n\n const newCell: NotebookCell = {\n cell_type: cell_type ?? 'code',\n source: sourceLines,\n metadata: {},\n ...(cell_type !== 'markdown' ? { outputs: [], execution_count: null } : {}),\n }\n\n if (edit_mode === 'insert') {\n const insertAt = Math.min(cell_index, cellCount)\n notebook.cells.splice(insertAt, 0, newCell)\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Inserted ${newCell.cell_type} cell at index ${insertAt}. Notebook now has ${notebook.cells.length} cells.`,\n metadata: { operation: 'insert', cell_index: insertAt, cellCount: notebook.cells.length },\n }\n }\n\n // replace\n if (cell_index >= cellCount) {\n return {\n content: `Cell index ${cell_index} out of range (notebook has ${cellCount} cells).`,\n isError: true,\n }\n }\n notebook.cells[cell_index] = newCell\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Replaced cell at index ${cell_index} with ${newCell.cell_type} cell.`,\n metadata: { operation: 'replace', cell_index, cellCount: notebook.cells.length },\n }\n },\n })\n}\n","/**\n * TaskStore — in-memory task collection scoped to a single engine run.\n *\n * Tasks are identified by auto-incrementing string IDs (\"1\", \"2\", ...).\n * The store is passed to the task tools at registry construction time\n * and shared across all tool invocations within the same `engine.run()`.\n *\n * Optionally persists to the workspace storage adapter as a JSON file\n * so tasks survive across pause/resume cycles.\n */\n\nimport type { StorageAdapter } from '../../storage/interface.js'\nimport type { Task, TaskStatus } from './types.js'\n\nconst TASKS_FILE = 'tasks.json'\n\nexport class TaskStore {\n private tasks: Map<string, Task> = new Map()\n private nextId = 1\n private readonly storage: StorageAdapter | undefined\n private readonly logPath: string\n\n constructor(options: { storage?: StorageAdapter; logPath: string }) {\n this.storage = options.storage\n this.logPath = options.logPath\n }\n\n create(subject: string, description: string, metadata?: Record<string, unknown>): Task {\n const id = String(this.nextId++)\n const now = new Date().toISOString()\n const task: Task = {\n id,\n subject,\n description,\n status: 'pending',\n createdAt: now,\n updatedAt: now,\n metadata: metadata ?? {},\n }\n this.tasks.set(id, task)\n void this.persist()\n return task\n }\n\n get(id: string): Task | undefined {\n return this.tasks.get(id)\n }\n\n list(filter?: { status?: TaskStatus }): Task[] {\n const out: Task[] = []\n for (const task of this.tasks.values()) {\n if (task.status === 'deleted') continue\n if (filter?.status !== undefined && task.status !== filter.status) continue\n out.push(task)\n }\n return out\n }\n\n update(\n id: string,\n fields: {\n subject?: string | undefined\n status?: TaskStatus | undefined\n description?: string | undefined\n metadata?: Record<string, unknown> | undefined\n },\n ): Task | undefined {\n const task = this.tasks.get(id)\n if (!task) return undefined\n\n if (fields.subject !== undefined) (task as { subject: string }).subject = fields.subject\n if (fields.status !== undefined) task.status = fields.status\n if (fields.description !== undefined)\n (task as { description: string }).description = fields.description\n if (fields.metadata !== undefined) {\n Object.assign(task.metadata, fields.metadata)\n }\n task.updatedAt = new Date().toISOString()\n void this.persist()\n return task\n }\n\n private async persist(): Promise<void> {\n if (!this.storage) return\n const data = JSON.stringify(Array.from(this.tasks.values()), null, 2)\n try {\n await this.storage.writeFile(`${this.logPath}/${TASKS_FILE}`, data)\n } catch {\n // Best-effort persistence — don't crash the run.\n }\n }\n}\n","/**\n * Task tools — TaskCreate, TaskGet, TaskList, TaskUpdate.\n * All four close over the same TaskStore instance.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from '../contract.js'\nimport type { TaskStore } from './store.js'\n\nconst TaskStatusEnum = z.enum(['pending', 'in_progress', 'completed', 'deleted'])\n\n// ---------- TaskCreate ----------\n\nconst createSchema = z.object({\n subject: z.string().min(1),\n description: z.string().default(''),\n metadata: z.record(z.unknown()).optional(),\n})\n\nexport function createTaskCreateTool(store: TaskStore): Tool<typeof createSchema> {\n return defineTool({\n name: 'TaskCreate',\n description:\n 'Create a new task. Use to break work into trackable steps. Returns the created task with its ID.',\n inputSchema: createSchema,\n execute: async ({ subject, description, metadata }) => {\n const task = store.create(subject, description, metadata)\n return {\n content: `Created task #${task.id}: \"${task.subject}\" (status: ${task.status})`,\n metadata: { task },\n }\n },\n })\n}\n\n// ---------- TaskGet ----------\n\nconst getSchema = z.object({\n taskId: z.string().min(1),\n})\n\nexport function createTaskGetTool(store: TaskStore): Tool<typeof getSchema> {\n return defineTool({\n name: 'TaskGet',\n description:\n 'Get a task by its ID. Returns the full task object including status and metadata.',\n inputSchema: getSchema,\n isConcurrencySafe: () => true,\n execute: async ({ taskId }) => {\n const task = store.get(taskId)\n if (!task) {\n return { content: `Task #${taskId} not found.`, isError: true }\n }\n return {\n content: `Task #${task.id}: \"${task.subject}\" — status: ${task.status}\\n${task.description}`,\n metadata: { task },\n }\n },\n })\n}\n\n// ---------- TaskList ----------\n\nconst listSchema = z.object({\n status: TaskStatusEnum.optional(),\n})\n\nexport function createTaskListTool(store: TaskStore): Tool<typeof listSchema> {\n return defineTool({\n name: 'TaskList',\n description:\n 'List all tasks. Optionally filter by status (pending, in_progress, completed). Deleted tasks are excluded.',\n inputSchema: listSchema,\n isConcurrencySafe: () => true,\n execute: async ({ status }) => {\n const tasks = store.list(status !== undefined ? { status } : undefined)\n if (tasks.length === 0) {\n return {\n content: status ? `No tasks with status \"${status}\".` : 'No tasks created yet.',\n metadata: { count: 0 },\n }\n }\n const lines = tasks.map((t) => `- #${t.id} [${t.status}] ${t.subject}`)\n return {\n content: `${tasks.length} task(s):\\n${lines.join('\\n')}`,\n metadata: { count: tasks.length, tasks },\n }\n },\n })\n}\n\n// ---------- TaskUpdate ----------\n\nconst updateSchema = z.object({\n taskId: z.string().min(1),\n subject: z.string().min(1).optional(),\n status: TaskStatusEnum.optional(),\n description: z.string().optional(),\n metadata: z.record(z.unknown()).optional(),\n})\n\nexport function createTaskUpdateTool(store: TaskStore): Tool<typeof updateSchema> {\n return defineTool({\n name: 'TaskUpdate',\n description:\n 'Update a task\\'s status, subject, description, or metadata. Set status to \"in_progress\" when starting, \"completed\" when done.',\n inputSchema: updateSchema,\n execute: async ({ taskId, subject, status, description, metadata }) => {\n const task = store.update(taskId, {\n subject,\n status,\n description,\n metadata: metadata,\n })\n if (!task) {\n return { content: `Task #${taskId} not found.`, isError: true }\n }\n return {\n content: `Updated task #${task.id}: \"${task.subject}\" — status: ${task.status}`,\n metadata: { task },\n }\n },\n })\n}\n","/**\n * Logger — structured log emission gated by `config.logging.level` and\n * routed to `config.logging.sink`.\n *\n * Levels (ascending verbosity):\n *\n * silent < error < warn < info < debug\n *\n * `silent` suppresses everything (no-op Logger). Any other level passes\n * records at that rank OR ANY RANK ABOVE IT through to the sink.\n *\n * Sinks:\n * - `'stderr'` — `console.error(JSON.stringify(entry))` per record.\n * Structured output that's cheap to grep/pipe through `jq`.\n * - `'none'` — true no-op. Use when embedding the engine inside a\n * host that has its own observability stack and doesn't want the\n * engine yelling into stderr.\n * - `(entry) => void` — callable sink. The engine hands the full\n * `LogEntry` to the caller on every emission. Use this to route into\n * OpenTelemetry, Pino, Winston, Sentry, a worker queue, etc.\n *\n * The returned logger is intentionally small: `{ error, warn, info, debug }`.\n * Each method takes a short message and an optional structured `meta`\n * object. The engine calls these at known checkpoints (run start/end,\n * turn boundaries, tool dispatch, pauses, failures) — see engine.ts for\n * the full emission schedule.\n */\n\nimport type { LogEntry, LogLevel, LogSink, ResolvedLoggingConfig } from '../config/types.js'\n\n/** Numeric rank for level comparisons. Higher = more verbose. */\nconst LEVEL_RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n}\n\nexport interface Logger {\n error(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n debug(msg: string, meta?: Record<string, unknown>): void\n}\n\nconst NOOP_LOGGER: Logger = {\n error: () => {},\n warn: () => {},\n info: () => {},\n debug: () => {},\n}\n\n/**\n * Build a Logger from a resolved logging config.\n *\n * Silent-level shortcuts to a true no-op so hot paths don't even\n * allocate the meta object. Non-silent loggers filter per-call against\n * the level rank before dispatching to the sink.\n */\nexport function createLogger(config: ResolvedLoggingConfig): Logger {\n if (config.level === 'silent') return NOOP_LOGGER\n\n const threshold = LEVEL_RANK[config.level]\n const dispatch = buildDispatcher(config.sink)\n\n const emit = (level: LogLevel, msg: string, meta?: Record<string, unknown>): void => {\n if (LEVEL_RANK[level] > threshold) return\n const entry: LogEntry = {\n level,\n msg,\n ts: new Date().toISOString(),\n ...(meta !== undefined ? { meta } : {}),\n }\n dispatch(entry)\n }\n\n return {\n error: (msg, meta) => emit('error', msg, meta),\n warn: (msg, meta) => emit('warn', msg, meta),\n info: (msg, meta) => emit('info', msg, meta),\n debug: (msg, meta) => emit('debug', msg, meta),\n }\n}\n\nfunction buildDispatcher(sink: LogSink): (entry: LogEntry) => void {\n if (sink === 'none') return () => {}\n if (sink === 'stderr') {\n return (entry) => {\n // Structured single-line JSON — easy to pipe through `jq`.\n console.error(JSON.stringify(entry))\n }\n }\n // Callable sink — user-supplied. Wrap in try so a throwing sink can't\n // tear down the engine mid-run.\n return (entry) => {\n try {\n sink(entry)\n } catch {\n // Swallow — logger failures must not abort the run.\n }\n }\n}\n","/**\n * Agents loader — discovers custom subagent definitions under a directory.\n *\n * Format (intentionally minimal, no YAML dependency):\n *\n * {customPath}/\n * ├── researcher.md\n * └── reviewer.md\n *\n * Each `.md` file defines one agent:\n *\n * # researcher\n *\n * One-line description. This is what the parent model sees in the Agent\n * tool's description catalogue.\n *\n * ---\n *\n * You are a research subagent. You have access to the web and filesystem...\n *\n * Parsing rules:\n *\n * - The **filename** (sans `.md`) is the agent's `name`. It must match\n * `^[a-zA-Z0-9_-]+$` or the file is skipped.\n * - The **first non-empty line** (after stripping leading `# `) is the\n * agent's `description`. One liner.\n * - The **rest of the file after the `---` separator** is the agent's\n * `systemPrompt`. If no `---` separator exists, the entire body after\n * the description is the system prompt. If there is no body at all,\n * `systemPrompt` is undefined and the agent inherits the parent's prompt.\n */\n\nimport type { AgentDefinition } from '../tools/agent.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\n/**\n * Walk `baseDir` under the given storage adapter and return one\n * `AgentDefinition` per valid `.md` file. Returns an empty array when\n * the directory is missing or empty.\n */\nexport async function loadAgents(\n storage: StorageAdapter,\n baseDir: string,\n): Promise<AgentDefinition[]> {\n const entries = await storage.listDir(baseDir)\n if (entries.length === 0) return []\n\n const out: AgentDefinition[] = []\n for (const entry of entries.slice().sort()) {\n if (!entry.endsWith('.md')) continue\n const name = entry.replace(/\\.md$/, '')\n if (!SAFE_NAME.test(name)) continue\n\n const content = await storage.readFile(`${baseDir}/${entry}`)\n if (content === null) continue\n\n const parsed = parseAgentFile(content, name)\n out.push(parsed)\n }\n\n return out\n}\n\nfunction parseAgentFile(content: string, name: string): AgentDefinition {\n const lines = content.split('\\n')\n let description = ''\n let bodyStart = 0\n let inHeading = false\n\n // Find the first non-empty line, strip `# ` if present, use as description.\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!.trim()\n if (line.length === 0) continue\n if (line.startsWith('#')) {\n inHeading = true\n // If there's text after `#`, keep looking — the heading itself is\n // usually the agent name (which we already have from the filename),\n // not the description.\n continue\n }\n description = line\n bodyStart = i + 1\n break\n }\n\n if (description === '' && inHeading) {\n // Only a heading, no body — use the agent name as the description.\n return { name, description: name }\n }\n\n // Look for a `---` separator between the description and the system prompt.\n // If not found, the remainder of the file is the system prompt.\n let promptStart = bodyStart\n for (let i = bodyStart; i < lines.length; i++) {\n if (lines[i]!.trim() === '---') {\n promptStart = i + 1\n break\n }\n }\n\n const systemPrompt = lines.slice(promptStart).join('\\n').trim()\n if (systemPrompt.length === 0) {\n return { name, description }\n }\n return { name, description, systemPrompt }\n}\n","/**\n * Coordinator mode — resolves config, builds the worker agent definition,\n * and determines the effective system prompt and tool restrictions.\n */\n\nimport type { ResolvedConfig } from '../config/types.js'\nimport type { AgentDefinition } from '../tools/agent.js'\nimport { getCoordinatorSystemPrompt } from './prompt.js'\nimport type { ResolvedCoordinatorConfig } from './types.js'\n\n/**\n * Check whether the engine is running in coordinator mode.\n */\nexport function isCoordinatorMode(config: ResolvedConfig): boolean {\n return config.coordinator.enabled\n}\n\n/**\n * Build the worker agent definition. Workers get a restricted tool set\n * and a simple system prompt. The coordinator dispatches to them via\n * `Agent({ subagent_type: 'worker', ... })`.\n */\nexport function buildWorkerAgent(config: ResolvedCoordinatorConfig): AgentDefinition {\n return {\n name: 'worker',\n description:\n 'A focused worker agent with restricted tool access. Executes research, implementation, or verification tasks as directed by the coordinator. Cannot spawn sub-agents.',\n systemPrompt: buildWorkerSystemPrompt(config),\n }\n}\n\nfunction buildWorkerSystemPrompt(config: ResolvedCoordinatorConfig): string {\n const tools = config.workerTools.join(', ')\n return `You are a worker agent inside la-machina-engine. You execute focused tasks as directed.\n\nYour available tools: ${tools}\n\nRules:\n- Execute the task given to you completely and accurately.\n- Report your findings, changes, and results clearly.\n- If you encounter an error, report it with the full error message, file path, and line number.\n- Do not ask questions — work with what you have. If information is missing, note what's missing in your report.\n- For implementation tasks: run tests and typecheck before reporting done. Commit your changes.\n- For research tasks: do not modify files. Report findings only.\n- For verification tasks: prove the code works — don't just confirm it exists. Try edge cases.\n- Be thorough but concise. Include file paths and line numbers in your reports.`\n}\n\n/**\n * Get the coordinator's system prompt override. Used by the engine's\n * prompt builder when coordinator mode is active.\n */\nexport function getCoordinatorBasePrompt(): string {\n return getCoordinatorSystemPrompt()\n}\n","/**\n * Coordinator system prompt — ported from La-Machina's coordinatorMode.ts.\n *\n * 370+ lines of behavioral instructions that transform the agent from\n * an implementer into an orchestrator. The prompt enforces:\n * - Research → Synthesis → Implementation → Verification phases\n * - Anti-lazy-delegation (must synthesize before directing workers)\n * - Parallel reads, serial writes\n * - Worker prompt quality standards\n *\n * Adapted for headless: no slash commands, no terminal UI, no interactive\n * approval dialogs. Tool names are parameterized.\n */\n\nexport function getCoordinatorSystemPrompt(): string {\n return `You are an AI assistant running inside la-machina-engine in **coordinator mode**. You orchestrate tasks across multiple workers.\n\n## 1. Your Role\n\nYou are a **coordinator**. Your job is to:\n- Help the caller achieve their goal\n- Direct workers to research, implement and verify code changes\n- Synthesize results and report back\n- Answer questions directly when possible — don't delegate work that you can handle without tools\n\nEvery message you produce goes to the caller. Worker results and system notifications are internal signals — never thank or acknowledge them. Summarize new information as it arrives.\n\n## 2. Your Tools\n\n- **Agent** — Spawn a new worker (use subagent_type: \"worker\")\n- **TaskCreate/TaskUpdate** — Track progress across phases\n\nWhen calling Agent:\n- Do not use one worker to check on another. Workers notify you when done.\n- Do not use workers to trivially report file contents. Give them higher-level tasks.\n- After launching agents, briefly state what you launched and end your response. Never fabricate or predict agent results — results arrive as separate messages.\n\n## 3. Workers\n\nWhen calling Agent, use subagent_type \"worker\". Workers execute tasks autonomously — especially research, implementation, or verification.\n\nWorkers have access to: Bash, Read, Write, Edit, Glob, Grep. They do NOT have the Agent tool (cannot sub-delegate). They do NOT have WebFetch or MCP tools unless explicitly configured.\n\n## 4. Task Workflow\n\nMost tasks can be broken down into the following phases:\n\n### Phases\n\n| Phase | Who | Purpose |\n|-------|-----|---------|\n| Research | Workers (parallel) | Investigate codebase, find files, understand problem |\n| Synthesis | **You** (coordinator) | Read findings, understand the problem, craft implementation specs |\n| Implementation | Workers | Make targeted changes per spec, commit |\n| Verification | Workers | Test changes work |\n\n### Concurrency\n\n**Parallelism is your superpower. Workers are async. Launch independent workers concurrently whenever possible — don't serialize work that can run simultaneously. When doing research, cover multiple angles. To launch workers in parallel, make multiple tool calls in a single message.**\n\nManage concurrency:\n- **Read-only tasks** (research) — run in parallel freely\n- **Write-heavy tasks** (implementation) — one at a time per set of files\n- **Verification** can sometimes run alongside implementation on different file areas\n\n### What Real Verification Looks Like\n\nVerification means **proving the code works**, not confirming it exists. A verifier that rubber-stamps weak work undermines everything.\n\n- Run tests **with the feature enabled** — not just \"tests pass\"\n- Run typechecks and **investigate errors** — don't dismiss as \"unrelated\"\n- Be skeptical — if something looks off, dig in\n- **Test independently** — prove the change works, don't rubber-stamp\n\n### Handling Worker Failures\n\nWhen a worker reports failure (tests failed, build errors, file not found):\n- Spawn a new worker with corrected instructions that incorporate the error context\n- If a correction attempt fails, try a different approach or report to the caller\n\n## 5. Writing Worker Prompts\n\n**Workers can't see your conversation.** Every prompt must be self-contained with everything the worker needs.\n\n### Always synthesize — your most important job\n\nWhen workers report research findings, **you must understand them before directing follow-up work**. Read the findings. Identify the approach. Then write a prompt that proves you understood by including specific file paths, line numbers, and exactly what to change.\n\nNever write \"based on your findings\" or \"based on the research.\" These phrases delegate understanding to the worker instead of doing it yourself. You never hand off understanding to another worker.\n\n\\`\\`\\`\n// Anti-pattern — lazy delegation\nAgent({ prompt: \"Based on your findings, fix the auth bug\", ... })\nAgent({ prompt: \"The worker found an issue in the auth module. Please fix it.\", ... })\n\n// Good — synthesized spec\nAgent({ prompt: \"Fix the null pointer in src/auth/validate.ts:42. The user field on Session (src/auth/types.ts:15) is undefined when sessions expire but the token remains cached. Add a null check before user.id access — if null, return 401 with 'Session expired'. Commit and report the hash.\", ... })\n\\`\\`\\`\n\nA well-synthesized spec gives the worker everything it needs in a few sentences.\n\n### Add a purpose statement\n\nInclude a brief purpose so workers can calibrate depth and emphasis:\n\n- \"This research will inform an implementation plan — report file paths, line numbers, and type signatures.\"\n- \"This is a quick check before we finish — just verify the happy path.\"\n\n### Prompt tips\n\n**Good examples:**\n\n1. Implementation: \"Fix the null pointer in src/auth/validate.ts:42. The user field can be undefined when the session expires. Add a null check and return early with an appropriate error. Commit and report the hash.\"\n\n2. Precise git operation: \"Create a new branch from main called 'fix/session-expiry'. Cherry-pick only commit abc123 onto it. Push and create a draft PR targeting main.\"\n\n3. Research: \"Find all files in src/ that import from the auth module. Report the import paths, which functions they use, and whether they handle session expiry. Do not modify files.\"\n\n**Bad examples:**\n\n1. \"Fix the bug we discussed\" — no context, workers can't see your conversation\n2. \"Based on your findings, implement the fix\" — lazy delegation\n3. \"Something went wrong with the tests, can you look?\" — no error message, no file path\n\nAdditional tips:\n- Include file paths, line numbers, error messages — workers start fresh and need complete context\n- State what \"done\" looks like\n- For implementation: \"Run relevant tests and typecheck, then commit and report the hash\"\n- For research: \"Report findings — do not modify files\"\n- For verification: \"Prove the code works, don't just confirm it exists\"\n- For verification: \"Try edge cases and error paths — don't just re-run what the implementation worker ran\"\n\n## 6. Example Session\n\nCaller: \"There's a null pointer in the auth module. Can you fix it?\"\n\nYou:\n Let me investigate first.\n\n Agent({ description: \"Investigate auth bug\", subagent_type: \"worker\", prompt: \"Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation. Report specific file paths, line numbers, and types involved. Do not modify files.\" })\n Agent({ description: \"Research auth tests\", subagent_type: \"worker\", prompt: \"Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry. Do not modify files.\" })\n\n Investigating from two angles — I'll report back with findings.\n\n[Worker A completes with findings about validate.ts:42]\n\nYou:\n Found the bug — null pointer in validate.ts:42. The user field on Session is undefined when the session expires but the token remains cached.\n\n Agent({ description: \"Fix auth null pointer\", subagent_type: \"worker\", prompt: \"Fix the null pointer in src/auth/validate.ts:42. Add a null check before accessing user.id — if null, return 401 with 'Session expired'. Run the test suite. Commit and report the hash.\" })\n\n Fix is in progress.\n\n[Worker completes with commit hash]\n\nYou:\n Fixed in commit abc123. Let me verify.\n\n Agent({ description: \"Verify auth fix\", subagent_type: \"worker\", prompt: \"Run the full test suite for src/auth/. Verify that the null pointer fix in validate.ts:42 handles session expiry correctly. Try edge cases: expired session with cached token, valid session, no session. Report pass/fail for each.\" })\n\n Running verification.`\n}\n","/**\n * McpManager — lifecycle, tool collection, and orphan prevention for a\n * set of MCP servers.\n *\n * Production hardening (v0.2.0):\n *\n * 1. **Orphan prevention.** Registers a `process.on('exit')` handler\n * that synchronously SIGKILLs every still-running child process.\n * The handler is removed after `shutdownAll()` completes.\n *\n * 2. **Dead-server reconnect.** Before skipping a server in\n * `getTools()`, checks `client.isConnected`. If the child process\n * died between runs, the server transitions back to `'failed'` and\n * is retried on the current call.\n *\n * 3. **Shutdown timeout.** `shutdownAll()` races a `Promise.all`\n * against a 5-second deadline. Survivors are SIGKILLed.\n */\n\nimport type { Logger } from '../logging/logger.js'\nimport { hasProcessLifecycle } from '../runtime/detect.js'\nimport type { Tool } from '../tools/contract.js'\nimport { McpClient } from './client.js'\nimport { McpConnectionError, McpProtocolError } from './errors.js'\nimport { adaptMcpTool } from './toolAdapter.js'\nimport type { McpServerState, ResolvedMcpConfig } from './types.js'\n\n// Removed hardcoded constant — now comes from config.mcp.shutdownTimeoutMs\n\ninterface ManagedServer {\n readonly name: string\n readonly client: McpClient\n state: McpServerState\n tools: ReadonlyArray<Tool> | null\n connectPromise: Promise<void> | null\n}\n\nexport interface McpInstructionDelta {\n readonly connected: string[]\n readonly disconnected: string[]\n}\n\nexport class McpManager {\n private readonly logger: Logger\n private readonly servers: ManagedServer[]\n private readonly shutdownTimeoutMs: number\n private exitHandler: (() => void) | null = null\n /** Tracks which servers connected/disconnected since last delta retrieval. */\n private pendingConnected: string[] = []\n private pendingDisconnected: string[] = []\n\n constructor(\n config: ResolvedMcpConfig,\n logger: Logger,\n options: {\n samplingHandler?: import('./sampling.js').SamplingHandler\n } = {},\n ) {\n this.shutdownTimeoutMs = config.shutdownTimeoutMs\n this.logger = logger\n this.servers = Object.entries(config.servers).map(([name, serverConfig]) => ({\n name,\n client: new McpClient({\n serverName: name,\n config: serverConfig,\n connectTimeoutMs: config.connectTimeoutMs,\n callTimeoutMs: config.callTimeoutMs,\n logger,\n ...(options.samplingHandler !== undefined\n ? { samplingHandler: options.samplingHandler }\n : {}),\n }),\n state: 'uninitialized',\n tools: null,\n connectPromise: null,\n }))\n\n // Install a synchronous exit handler that kills child processes.\n // Only when process lifecycle hooks are available (Node.js). In\n // Cloudflare Workers, process.on('exit') is a stub — skip it.\n if (this.servers.length > 0 && hasProcessLifecycle()) {\n this.exitHandler = () => this.killAllSync()\n process.on('exit', this.exitHandler)\n }\n }\n\n get connectedCount(): number {\n return this.servers.filter((s) => s.state === 'connected').length\n }\n\n /**\n * Lazily connect every configured server and return the full set of\n * tools. Detects dead connections and retries them. Per-server failures\n * are isolated.\n */\n async getTools(): Promise<ReadonlyArray<Tool>> {\n if (this.servers.length === 0) return []\n\n await Promise.all(\n this.servers.map(async (server) => {\n // Skip already-disconnected (post-shutdown) servers.\n if (server.state === 'disconnected') return\n\n // Detect dead connections: the child may have died between runs.\n // The transport.onclose handler in McpClient flips isConnected to\n // false, so we can catch it here and allow a reconnect attempt.\n if (server.state === 'connected' && !server.client.isConnected) {\n this.logger.warn('mcp.connect dead connection detected, retrying', {\n server: server.name,\n })\n server.state = 'failed'\n server.tools = null\n this.pendingDisconnected.push(server.name)\n }\n\n if (server.state === 'connected') return\n await this.connectServer(server)\n }),\n )\n\n const out: Tool[] = []\n for (const server of this.servers) {\n if (server.state !== 'connected' || server.tools === null) continue\n out.push(...server.tools)\n }\n return out\n }\n\n /**\n * Retrieve and clear pending instruction deltas (connected/disconnected\n * servers since last call). Used by agentLoop to announce MCP changes\n * to the model. Ported from La-Machina's mcpInstructionsDelta.ts.\n */\n getInstructionDeltas(): McpInstructionDelta {\n const delta: McpInstructionDelta = {\n connected: this.pendingConnected.splice(0),\n disconnected: this.pendingDisconnected.splice(0),\n }\n return delta\n }\n\n /**\n * Graceful shutdown with a timeout. Attempts `client.close()` for\n * every active server within `SHUTDOWN_TIMEOUT_MS`. Servers that don't\n * respond in time are force-killed (SIGKILL for stdio, no-op for HTTP/SSE).\n *\n * Removes the process.on('exit') handler after cleanup.\n */\n async shutdownAll(): Promise<void> {\n const active = this.servers.filter((s) => s.state === 'connected' || s.state === 'connecting')\n\n if (active.length > 0) {\n this.logger.info('mcp.shutdown start', { connectedCount: active.length })\n\n const graceful = Promise.all(\n active.map(async (server) => {\n try {\n await server.client.close()\n } catch (err) {\n this.logger.warn('mcp.shutdown close failed', {\n server: server.name,\n error: (err as Error).message,\n })\n }\n server.state = 'disconnected'\n server.tools = null\n server.connectPromise = null\n }),\n )\n\n // Race against the shutdown timeout. If servers don't respond in\n // time, force-kill everything.\n const timeout = new Promise<'timeout'>((resolve) => {\n const timer = setTimeout(() => resolve('timeout'), this.shutdownTimeoutMs)\n if (typeof timer.unref === 'function') timer.unref()\n })\n\n const result = await Promise.race([graceful.then(() => 'ok' as const), timeout])\n if (result === 'timeout') {\n this.logger.warn('mcp.shutdown timeout — force-killing remaining servers')\n this.killAllSync()\n // Mark everything as disconnected.\n for (const server of active) {\n server.state = 'disconnected'\n server.tools = null\n server.connectPromise = null\n }\n }\n\n this.logger.info('mcp.shutdown complete', {})\n }\n\n // Remove the exit handler — we've cleaned up, nothing to kill.\n this.removeExitHandler()\n }\n\n /**\n * Synchronously SIGKILL every known child PID. Used by the\n * process.on('exit') handler (where async is not possible) and by the\n * shutdown timeout fallback.\n */\n private killAllSync(): void {\n for (const server of this.servers) {\n server.client.killSync()\n }\n }\n\n private removeExitHandler(): void {\n if (this.exitHandler !== null) {\n process.removeListener('exit', this.exitHandler)\n this.exitHandler = null\n }\n }\n\n private async connectServer(server: ManagedServer): Promise<void> {\n if (server.state === 'connecting' && server.connectPromise !== null) {\n await server.connectPromise\n return\n }\n\n server.state = 'connecting'\n server.connectPromise = this.doConnect(server)\n try {\n await server.connectPromise\n } finally {\n server.connectPromise = null\n }\n }\n\n private async doConnect(server: ManagedServer): Promise<void> {\n this.logger.debug('mcp.connect start', { server: server.name })\n try {\n await server.client.connect()\n const defs = server.client.listTools()\n server.tools = defs.map((def) => adaptMcpTool(server.client, server.name, def))\n server.state = 'connected'\n this.pendingConnected.push(server.name)\n } catch (err) {\n server.state = 'failed'\n server.tools = null\n if (err instanceof McpConnectionError || err instanceof McpProtocolError) {\n this.logger.warn('mcp.connect failed', {\n server: server.name,\n error: err.message,\n })\n } else {\n this.logger.warn('mcp.connect failed (unexpected error)', {\n server: server.name,\n error: (err as Error).message,\n })\n }\n }\n }\n}\n","/**\n * McpClient — wraps `@modelcontextprotocol/sdk`'s Client for all three\n * transports (stdio, HTTP, SSE).\n *\n * Production hardening (v0.2.0):\n * - Tracks the child PID for stdio transports → McpManager can\n * synchronously kill orphans in a process.on('exit') handler.\n * - Detects dead connections: if `callTool()` fails with a transport\n * error, `isConnected` flips to false so McpManager can retry the\n * next time `getTools()` is called.\n * - Flattens MCP content blocks into a single string.\n * - Maps SDK errors into engine-typed errors.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport {\n CreateMessageRequestSchema,\n type CreateMessageRequest,\n type CreateMessageResult,\n} from '@modelcontextprotocol/sdk/types.js'\nimport type { Logger } from '../logging/logger.js'\nimport { BindingHttpTransport } from './bindingTransport.js'\nimport { McpConnectionError, McpProtocolError, McpTimeoutError } from './errors.js'\nimport type { McpCallResult, McpToolDef, ResolvedMcpServerConfig } from './types.js'\n\nconst CLIENT_IDENTITY = { name: 'la-machina-engine', version: '0.3.0' } as const\nconst CLIENT_CAPABILITIES = {} as const\n\nexport interface McpClientOptions {\n readonly serverName: string\n readonly config: ResolvedMcpServerConfig\n readonly connectTimeoutMs: number\n readonly callTimeoutMs: number\n readonly logger: Logger\n readonly transportOverride?: Transport\n /**\n * Handler invoked when this server issues a `sampling/createMessage`\n * request. Only called when `config.allowSampling === true`. When\n * absent, sampling requests are refused with a protocol error.\n */\n readonly samplingHandler?: import('./sampling.js').SamplingHandler\n}\n\nexport class McpClient {\n readonly serverName: string\n private readonly options: McpClientOptions\n private sdkClient: Client | null = null\n private toolCache: readonly McpToolDef[] | null = null\n private connected = false\n /** PID of the child process (stdio only). Used for synchronous orphan kill. */\n private childPid: number | null = null\n\n constructor(options: McpClientOptions) {\n this.serverName = options.serverName\n this.options = options\n }\n\n get isConnected(): boolean {\n return this.connected\n }\n\n /** PID of the spawned child process (stdio only). Null for HTTP/SSE. */\n get pid(): number | null {\n return this.childPid\n }\n\n async connect(): Promise<void> {\n if (this.connected) return\n\n const transport = this.options.transportOverride ?? this.buildTransport()\n\n // Advertise the `sampling` capability only when the server has it\n // allowed AND a handler was provided. Without both, the server\n // receives zero sampling capabilities during initialize and won't\n // attempt the reverse call.\n const capabilities: Record<string, unknown> = { ...CLIENT_CAPABILITIES }\n const allowSampling =\n (this.options.config as { allowSampling?: boolean }).allowSampling === true\n const samplingHandler = this.options.samplingHandler\n if (allowSampling && samplingHandler !== undefined) {\n capabilities.sampling = {}\n }\n\n const client = new Client(CLIENT_IDENTITY, { capabilities })\n\n // Install the sampling request handler BEFORE transport connects\n // so the SDK is ready for server-initiated requests that may land\n // during or immediately after initialize.\n if (allowSampling && samplingHandler !== undefined) {\n this.installSamplingHandler(client, samplingHandler)\n }\n // Note: when allowSampling is false (default), we DON'T register a\n // refusal handler. The SDK rejects setRequestHandler for any\n // method whose capability we haven't advertised. Since we omit\n // `sampling: {}` from capabilities, the SDK itself returns the\n // \"method not supported\" error to the server — which is exactly\n // what we want. See Plan 018 §2 safety design.\n\n // Detect transport death so isConnected flips proactively.\n transport.onclose = () => {\n this.connected = false\n }\n\n try {\n await withTimeout(\n client.connect(transport),\n this.options.connectTimeoutMs,\n () =>\n new McpConnectionError(\n this.serverName,\n `initialize did not complete within ${this.options.connectTimeoutMs}ms`,\n ),\n )\n } catch (err) {\n await safeClose(client)\n throw wrapConnectionError(this.serverName, err)\n }\n\n // Capture PID for orphan kill (stdio transport only).\n if (transport instanceof StdioClientTransport) {\n this.childPid = transport.pid ?? null\n }\n\n let tools: readonly McpToolDef[]\n try {\n const response = await client.listTools()\n tools = normalizeToolList(response, this.serverName)\n } catch (err) {\n await safeClose(client)\n throw wrapProtocolError(this.serverName, err, 'tools/list failed')\n }\n\n this.sdkClient = client\n this.toolCache = tools\n this.connected = true\n this.options.logger.info('mcp.connect ok', {\n server: this.serverName,\n type: this.options.config.type,\n toolCount: tools.length,\n ...(this.childPid !== null ? { pid: this.childPid } : {}),\n })\n }\n\n listTools(): readonly McpToolDef[] {\n if (this.toolCache === null) {\n throw new McpProtocolError(this.serverName, 'listTools() called before connect()')\n }\n return this.toolCache\n }\n\n async callTool(toolName: string, input: unknown): Promise<McpCallResult> {\n const client = this.sdkClient\n if (client === null || !this.connected) {\n throw new McpProtocolError(this.serverName, `callTool(${toolName}) — not connected`)\n }\n\n const params = {\n name: toolName,\n arguments: normalizeInput(input),\n }\n\n this.options.logger.debug('mcp.callTool', { server: this.serverName, tool: toolName })\n\n let response: unknown\n try {\n response = await withTimeout(\n client.callTool(params),\n this.options.callTimeoutMs,\n () => new McpTimeoutError(this.serverName, toolName, this.options.callTimeoutMs),\n )\n } catch (err) {\n // Mark as disconnected so McpManager retries on the next getTools().\n this.connected = false\n throw err instanceof McpTimeoutError || err instanceof McpProtocolError\n ? err\n : wrapProtocolError(this.serverName, err, `callTool(${toolName})`)\n }\n\n return flattenCallResult(response, this.serverName, toolName)\n }\n\n async close(): Promise<void> {\n const client = this.sdkClient\n this.sdkClient = null\n this.connected = false\n this.toolCache = null\n this.childPid = null\n if (client !== null) {\n await safeClose(client)\n }\n }\n\n /**\n * Synchronously kill the child process (stdio only). Used by\n * McpManager's process.on('exit') handler where async work is not\n * possible. No-op for HTTP/SSE transports.\n */\n killSync(): void {\n const pid = this.childPid\n if (pid !== null) {\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n // Already dead or not our child — swallow.\n }\n this.childPid = null\n this.connected = false\n }\n }\n\n /**\n * Register the engine-side handler for MCP `sampling/createMessage`.\n * Runs user-supplied SamplingHandler, converts result to the MCP\n * `CreateMessageResult` shape.\n */\n private installSamplingHandler(\n client: Client,\n handler: import('./sampling.js').SamplingHandler,\n ): void {\n client.setRequestHandler(\n CreateMessageRequestSchema,\n async (request: CreateMessageRequest): Promise<CreateMessageResult> => {\n const params = request.params\n const engineRequest: import('./sampling.js').SamplingRequest = {\n messages: params.messages.map((m) => ({\n role: m.role,\n content: m.content,\n })) as ReadonlyArray<import('./sampling.js').SamplingMessage>,\n ...(typeof params.systemPrompt === 'string' ? { systemPrompt: params.systemPrompt } : {}),\n maxTokens: params.maxTokens,\n ...(typeof params.temperature === 'number' ? { temperature: params.temperature } : {}),\n ...(Array.isArray(params.stopSequences) ? { stopSequences: params.stopSequences } : {}),\n ...(params.modelPreferences !== undefined\n ? {\n modelPreferences:\n params.modelPreferences as import('./sampling.js').SamplingModelPreferences,\n }\n : {}),\n ...(params.includeContext !== undefined ? { includeContext: params.includeContext } : {}),\n ...(params.metadata !== undefined\n ? { metadata: params.metadata as Readonly<Record<string, unknown>> }\n : {}),\n }\n\n const response = await handler(engineRequest, {\n serverName: this.serverName,\n depth: 0,\n })\n\n return {\n role: response.role,\n content: response.content,\n model: response.model,\n ...(response.stopReason !== undefined ? { stopReason: response.stopReason } : {}),\n }\n },\n )\n }\n\n private buildTransport(): Transport {\n const config = this.options.config\n\n switch (config.type) {\n case 'stdio': {\n const env = resolveEnv(config.env, config.isolateEnv)\n return new StdioClientTransport({\n command: config.command,\n args: [...config.args],\n ...(env !== undefined ? { env } : {}),\n ...(config.cwd !== undefined ? { cwd: config.cwd } : {}),\n stderr: 'pipe',\n })\n }\n\n case 'http': {\n // Workers-friendly path — plain POST JSON-RPC, no long-lived SSE.\n // Opt-in via config.preferBindingTransport so Node users keep\n // the full Streamable HTTP behavior (notifications, resumption).\n if (config.preferBindingTransport === true) {\n return new BindingHttpTransport({\n url: config.url,\n ...(config.headers !== undefined ? { headers: config.headers } : {}),\n ...(config.headersProvider !== undefined\n ? { resolveHeaders: config.headersProvider }\n : {}),\n })\n }\n const url = new URL(config.url)\n const opts: { requestInit?: RequestInit; fetch?: typeof globalThis.fetch } = {}\n if (config.headers !== undefined) {\n opts.requestInit = { headers: { ...config.headers } }\n }\n if (config.headersProvider !== undefined) {\n // Wrap global fetch so the SDK's transport picks up fresh\n // headers per request. On 401 we invoke the provider a\n // second time and retry once (one-shot refresh).\n opts.fetch = wrapFetchWithHeadersProvider(\n globalThis.fetch.bind(globalThis),\n config.headersProvider,\n config.headers,\n )\n }\n // Cast: StreamableHTTPClientTransport has `sessionId?: string`\n // which conflicts with Transport's `sessionId?: string` under\n // exactOptionalPropertyTypes. The runtime shape is identical.\n return new StreamableHTTPClientTransport(url, opts) as unknown as Transport\n }\n\n case 'sse': {\n const url = new URL(config.url)\n const opts: { requestInit?: RequestInit; fetch?: typeof globalThis.fetch } = {}\n if (config.headers !== undefined) {\n opts.requestInit = { headers: { ...config.headers } }\n }\n if (config.headersProvider !== undefined) {\n opts.fetch = wrapFetchWithHeadersProvider(\n globalThis.fetch.bind(globalThis),\n config.headersProvider,\n config.headers,\n )\n }\n return new SSEClientTransport(url, opts)\n }\n }\n }\n}\n\n// ---------- helpers ----------\n\nfunction resolveEnv(\n explicit: Readonly<Record<string, string>> | undefined,\n isolate: boolean,\n): Record<string, string> | undefined {\n if (isolate) return explicit ? { ...explicit } : {}\n if (explicit === undefined) return undefined\n const parent: Record<string, string> = {}\n for (const [k, v] of Object.entries(process.env)) {\n if (typeof v === 'string') parent[k] = v\n }\n return { ...parent, ...explicit }\n}\n\nfunction normalizeInput(input: unknown): Record<string, unknown> {\n if (input === null || input === undefined) return {}\n if (typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>\n }\n return { input }\n}\n\nfunction normalizeToolList(response: unknown, serverName: string): readonly McpToolDef[] {\n if (\n response === null ||\n typeof response !== 'object' ||\n !('tools' in response) ||\n !Array.isArray((response as { tools: unknown }).tools)\n ) {\n throw new McpProtocolError(serverName, 'tools/list response did not contain a tools array')\n }\n const rawTools = (response as { tools: unknown[] }).tools\n const out: McpToolDef[] = []\n for (const t of rawTools) {\n if (t === null || typeof t !== 'object') continue\n const obj = t as Record<string, unknown>\n const name = typeof obj.name === 'string' ? obj.name : null\n if (name === null) continue\n const description = typeof obj.description === 'string' ? obj.description : ''\n const inputSchema =\n obj.inputSchema !== null &&\n typeof obj.inputSchema === 'object' &&\n !Array.isArray(obj.inputSchema)\n ? (obj.inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} }\n out.push({ name, description, inputSchema })\n }\n return out\n}\n\ninterface McpContentBlock {\n readonly type: string\n readonly text?: string\n readonly mimeType?: string\n readonly uri?: string\n readonly name?: string\n}\n\nfunction flattenCallResult(response: unknown, serverName: string, toolName: string): McpCallResult {\n if (response === null || typeof response !== 'object') {\n throw new McpProtocolError(serverName, `callTool(${toolName}) returned a non-object response`)\n }\n\n const obj = response as { content?: unknown; isError?: unknown; toolResult?: unknown }\n const isError = obj.isError === true\n\n if (obj.content === undefined && 'toolResult' in obj) {\n return {\n content: safeStringify(obj.toolResult),\n ...(isError ? { isError: true } : {}),\n }\n }\n\n if (!Array.isArray(obj.content)) {\n throw new McpProtocolError(serverName, `callTool(${toolName}) returned no content array`)\n }\n\n const pieces: string[] = []\n for (const raw of obj.content as unknown[]) {\n if (raw === null || typeof raw !== 'object') continue\n const block = raw as McpContentBlock\n if (block.type === 'text' && typeof block.text === 'string') {\n pieces.push(block.text)\n } else if (block.type === 'image') {\n pieces.push(`[image block: ${block.mimeType ?? 'unknown mime'}]`)\n } else if (block.type === 'audio') {\n pieces.push(`[audio block: ${block.mimeType ?? 'unknown mime'}]`)\n } else if (block.type === 'resource') {\n pieces.push(`[resource block: ${block.uri ?? '(no uri)'}]`)\n } else if (block.type === 'resource_link') {\n pieces.push(`[resource_link: ${block.name ?? ''} ${block.uri ?? ''}]`)\n } else {\n pieces.push(`[${block.type ?? 'unknown'} block]`)\n }\n }\n\n return {\n content: pieces.join('\\n'),\n ...(isError ? { isError: true } : {}),\n }\n}\n\nfunction safeStringify(value: unknown): string {\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value)\n } catch {\n return String(value)\n }\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n makeError: () => Error,\n): Promise<T> {\n if (timeoutMs <= 0) return promise\n let timer: NodeJS.Timeout | undefined\n try {\n return await Promise.race<T>([\n promise,\n new Promise<T>((_, reject) => {\n timer = setTimeout(() => reject(makeError()), timeoutMs)\n if (typeof timer.unref === 'function') timer.unref()\n }),\n ])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n}\n\nasync function safeClose(client: Client): Promise<void> {\n try {\n await client.close()\n } catch {\n // Swallow.\n }\n}\n\nfunction wrapConnectionError(serverName: string, err: unknown): McpConnectionError {\n if (err instanceof McpConnectionError) return err\n if (err instanceof McpTimeoutError) {\n return new McpConnectionError(serverName, err.message)\n }\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('ENOENT')) {\n return new McpConnectionError(serverName, `command not found (ENOENT)`)\n }\n if (message.includes('EACCES')) {\n return new McpConnectionError(serverName, `permission denied (EACCES)`)\n }\n return new McpConnectionError(serverName, message)\n}\n\nfunction wrapProtocolError(serverName: string, err: unknown, context: string): McpProtocolError {\n if (err instanceof McpProtocolError) return err\n const message = err instanceof Error ? err.message : String(err)\n return new McpProtocolError(serverName, `${context}: ${message}`)\n}\n\n/**\n * Wrap `fetch` so that it resolves fresh headers via the caller's\n * `headersProvider` on every request, merging over the static headers\n * passed in. On HTTP 401, invokes the provider again and retries the\n * request once (one-shot refresh) — see Plan 018 §1.\n */\nfunction wrapFetchWithHeadersProvider(\n baseFetch: typeof globalThis.fetch,\n headersProvider: () => Promise<Readonly<Record<string, string>>>,\n staticHeaders: Readonly<Record<string, string>> | undefined,\n): typeof globalThis.fetch {\n const doOnce = async (\n input: Parameters<typeof globalThis.fetch>[0],\n init: Parameters<typeof globalThis.fetch>[1],\n ): Promise<Response> => {\n const dynamic = await headersProvider()\n const merged = new Headers(init?.headers ?? {})\n if (staticHeaders !== undefined) {\n for (const [k, v] of Object.entries(staticHeaders)) merged.set(k, v)\n }\n for (const [k, v] of Object.entries(dynamic)) merged.set(k, v)\n return baseFetch(input, { ...init, headers: merged })\n }\n\n return async (input, init) => {\n const first = await doOnce(input, init)\n if (first.status !== 401) return first\n // One-shot refresh on 401. The provider is expected to invalidate\n // any internal token cache so the second call returns a fresh value.\n return doOnce(input, init)\n }\n}\n","/**\n * BindingHttpTransport — plain-POST JSON-RPC MCP transport for Cloudflare\n * Workers.\n *\n * The upstream `StreamableHTTPClientTransport` opens a long-lived `fetch()`\n * with a streaming SSE response for server-push notifications. On the\n * Workers runtime that stream can hang unpredictably after `initialize`,\n * causing `tools/list` and `tools/call` to stall. This transport sidesteps\n * that entirely: every message is a short, stateless POST; the response\n * is parsed once and handed to `onmessage`. No persistent reader, no SSE.\n *\n * Trade-off: server-push notifications (logs, progress) don't work. That's\n * fine for the tool-calling use case — `tools/list` and `tools/call` are\n * request/response only.\n *\n * Implements just enough of the MCP transport contract for the engine's\n * `McpClient` to use. All pure JS — no `node:*` imports, Workers-safe.\n */\n\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js'\n\nconst SESSION_HEADER = 'Mcp-Session-Id'\n\nexport interface BindingHttpTransportOptions {\n /** Full URL of the MCP Streamable-HTTP endpoint (e.g. https://mcp.example.com/mcp). */\n readonly url: string\n /** Extra headers sent on every POST (auth tokens, API keys). */\n readonly headers?: Readonly<Record<string, string>>\n /**\n * Per-request dynamic header factory. When set, called before every\n * send; its result is merged OVER the static `headers`. On HTTP 401\n * the transport calls the factory again (invalidating any token\n * cache inside) and retries the request once.\n */\n readonly resolveHeaders?: () => Promise<Readonly<Record<string, string>>>\n /** Override fetch (tests only). Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. Default: 30_000. */\n readonly timeoutMs?: number\n}\n\n/**\n * MCP transport that speaks JSON-RPC 2.0 over bare POST. No persistent\n * connection. Not suitable for servers that rely on async notifications.\n */\nexport class BindingHttpTransport implements Transport {\n readonly url: string\n private readonly headers: Record<string, string>\n private readonly resolveHeaders: (() => Promise<Readonly<Record<string, string>>>) | undefined\n private readonly fetchImpl: typeof globalThis.fetch\n private readonly timeoutMs: number\n private started = false\n private closed = false\n sessionId?: string\n\n onclose?: () => void\n onerror?: (error: Error) => void\n onmessage?: (message: JSONRPCMessage) => void\n\n constructor(options: BindingHttpTransportOptions) {\n this.url = options.url\n this.headers = { ...(options.headers ?? {}) }\n this.resolveHeaders = options.resolveHeaders\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n this.timeoutMs = options.timeoutMs ?? 30_000\n }\n\n async start(): Promise<void> {\n // No persistent connection; `send()` does all the work.\n this.started = true\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n if (this.closed) {\n throw new Error('BindingHttpTransport: send after close')\n }\n if (!this.started) {\n // Protocol.connect calls start() first, but be defensive.\n this.started = true\n }\n\n const body = JSON.stringify(message)\n let response = await this.doFetch(body)\n\n // One-shot refresh on 401 when a headersProvider is configured.\n // We intentionally don't retry more than once — if the fresh\n // token also 401s, something is genuinely wrong.\n if (response.status === 401 && this.resolveHeaders !== undefined) {\n response = await this.doFetch(body)\n }\n\n // Capture session id from the initialize response (or any response\n // that carries one). Server sets it on initialize and expects it back\n // on every subsequent request.\n const newSession = response.headers.get(SESSION_HEADER)\n if (newSession !== null && newSession.length > 0) {\n this.sessionId = newSession\n }\n\n // Notifications/responses-only messages return 202 with no body.\n if (response.status === 202 || response.status === 204) return\n\n if (!response.ok) {\n const text = await safeText(response)\n const err = new Error(\n `BindingHttpTransport: HTTP ${String(response.status)} ${response.statusText}${text ? ` — ${text}` : ''}`,\n )\n this.onerror?.(err)\n throw err\n }\n\n // Parse JSON response. Server in enableJsonResponse mode returns a\n // single JSON-RPC response object (or array for batches).\n const contentType = response.headers.get('Content-Type') ?? ''\n if (!contentType.includes('application/json')) {\n // SSE response mode — read the first `data: …` line and parse it.\n // We don't support streaming notifications; we close after the\n // first message.\n const text = await response.text()\n const parsed = parseSseFrames(text)\n for (const msg of parsed) this.onmessage?.(msg as JSONRPCMessage)\n return\n }\n\n const responseBody = await response.text()\n if (responseBody.length === 0) return\n\n let parsed: unknown\n try {\n parsed = JSON.parse(responseBody)\n } catch (err) {\n const error = new Error(\n `BindingHttpTransport: invalid JSON response: ${err instanceof Error ? err.message : String(err)}`,\n )\n this.onerror?.(error)\n throw error\n }\n\n if (Array.isArray(parsed)) {\n for (const m of parsed) this.onmessage?.(m as JSONRPCMessage)\n } else {\n this.onmessage?.(parsed as JSONRPCMessage)\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.closed = true\n this.onclose?.()\n }\n\n /**\n * Perform a single POST, applying current headers (static + dynamic).\n * Does not retry — the 401-refresh loop lives in `send()`.\n */\n private async doFetch(body: string): Promise<Response> {\n const dynamic = this.resolveHeaders !== undefined ? await this.resolveHeaders() : {}\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...this.headers,\n ...dynamic,\n }\n if (this.sessionId !== undefined) {\n headers[SESSION_HEADER] = this.sessionId\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), this.timeoutMs)\n try {\n return await this.fetchImpl(this.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n this.onerror?.(error)\n throw error\n } finally {\n clearTimeout(timer)\n }\n }\n}\n\nasync function safeText(r: Response): Promise<string> {\n try {\n return await r.text()\n } catch {\n return ''\n }\n}\n\n/**\n * Parse a simple SSE stream body captured as text. Returns all `data:`\n * payloads as parsed JSON-RPC messages, skipping any we can't parse.\n * Only used for servers that refuse to switch to JSON response mode.\n */\nfunction parseSseFrames(text: string): unknown[] {\n const out: unknown[] = []\n for (const block of text.split(/\\r?\\n\\r?\\n/)) {\n const lines = block.split(/\\r?\\n/).filter((l) => l.startsWith('data:'))\n if (lines.length === 0) continue\n const raw = lines.map((l) => l.slice(5).trimStart()).join('\\n')\n if (raw.length === 0) continue\n try {\n out.push(JSON.parse(raw))\n } catch {\n /* skip unparseable frames */\n }\n }\n return out\n}\n","/**\n * MCP error taxonomy.\n *\n * Three error classes, all subclasses of `EngineError`:\n *\n * - `McpConnectionError` — a server failed to spawn, initialize, or list\n * tools. Swallowed by `McpManager`: logged as warn, server's tools are\n * absent from the registry, run proceeds.\n *\n * - `McpProtocolError` — a server returned a malformed JSON-RPC response\n * or an unexpected capability mismatch. Usually a server bug. Surfaces\n * in `tool_result` as `isError: true` when it happens during a call.\n *\n * - `McpTimeoutError` — a tool call exceeded `mcp.callTimeoutMs`.\n * Surfaces in `tool_result` as `isError: true` so the agent loop can\n * recover (retry, use a different tool, report back).\n *\n * The principle: MCP is best-effort. A run must never fail because one\n * of its MCP servers went wrong.\n */\n\nimport { EngineError } from '../engine/errors.js'\n\nexport class McpConnectionError extends EngineError {\n readonly serverName: string\n\n constructor(serverName: string, cause: string) {\n super('ERR_MCP_CONNECT', `mcp: ${serverName} — ${cause}`)\n this.serverName = serverName\n }\n}\n\nexport class McpProtocolError extends EngineError {\n readonly serverName: string\n\n constructor(serverName: string, cause: string) {\n super('ERR_MCP_PROTOCOL', `mcp: ${serverName} — ${cause}`)\n this.serverName = serverName\n }\n}\n\nexport class McpTimeoutError extends EngineError {\n readonly serverName: string\n readonly toolName: string\n readonly timeoutMs: number\n\n constructor(serverName: string, toolName: string, timeoutMs: number) {\n super('ERR_MCP_TIMEOUT', `mcp: ${serverName}/${toolName} exceeded ${timeoutMs}ms`)\n this.serverName = serverName\n this.toolName = toolName\n this.timeoutMs = timeoutMs\n }\n}\n","/**\n * adaptMcpTool — convert an `McpToolDef` into an engine `Tool`.\n *\n * The returned tool:\n *\n * - Has its name prefixed with `mcp__{serverName}__` so it cannot\n * collide with built-in or custom tools.\n * - Carries the server's description verbatim (the model sees this\n * as the tool's \"what does it do\" text).\n * - Uses `z.unknown()` as the engine-side input schema. MCP tools\n * author their validation in JSON Schema, not Zod, and the server\n * itself validates on receipt. Rather than run a lossy\n * JSON-Schema → Zod conversion at adapter time, we let the server\n * be the source of truth and pass input through unchanged.\n * - Sets `anthropicSchemaOverride` to the raw MCP JSON Schema — this\n * is what the engine ships to the Anthropic API so the model sees\n * a proper `input_schema` with typed parameters.\n * - Dispatches to `McpClient.callTool()`, turning `McpCallResult`\n * into the engine's `ToolResult` and catching any thrown MCP errors\n * into `{ isError: true }` results so the agent loop can recover.\n *\n * Why not use `z.any().passthrough()` instead of `z.unknown()`?\n * `z.unknown()` validates nothing (matches any value, including\n * `undefined`). `z.any()` is semantically equivalent but linters\n * frown on it. Either works; we pick `unknown` for stricter types.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from '../tools/contract.js'\nimport type { McpClient } from './client.js'\nimport { McpProtocolError, McpTimeoutError } from './errors.js'\nimport type { McpToolDef } from './types.js'\n\n/** Build the engine-side tool name for an MCP tool. */\nexport function mcpToolName(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`\n}\n\nexport function adaptMcpTool(\n client: McpClient,\n serverName: string,\n def: McpToolDef,\n): Tool<z.ZodUnknown> {\n const registeredName = mcpToolName(serverName, def.name)\n return defineTool({\n name: registeredName,\n description:\n def.description.length > 0 ? def.description : `MCP tool ${serverName}/${def.name}`,\n inputSchema: z.unknown(),\n // Pass the MCP server's JSON Schema through to Anthropic verbatim,\n // bypassing Zod-to-JSON-Schema conversion (which would produce `{}`\n // for our `z.unknown()` Zod schema).\n anthropicSchemaOverride: def.inputSchema,\n execute: async (input): Promise<ToolResult> => {\n try {\n const result = await client.callTool(def.name, input)\n return {\n content: result.content,\n ...(result.isError === true ? { isError: true } : {}),\n metadata: {\n mcpServer: serverName,\n mcpTool: def.name,\n },\n }\n } catch (err) {\n if (err instanceof McpTimeoutError || err instanceof McpProtocolError) {\n return {\n content: `${registeredName} failed: ${err.message}`,\n isError: true,\n metadata: { mcpServer: serverName, mcpTool: def.name, errorCode: err.code },\n }\n }\n return {\n content: `${registeredName} failed: ${(err as Error).message}`,\n isError: true,\n metadata: { mcpServer: serverName, mcpTool: def.name },\n }\n }\n },\n })\n}\n","/**\n * MCP sampling — Plan 018 §2.\n *\n * MCP servers can issue `sampling/createMessage` requests asking the\n * *client* to run an LLM completion on their behalf. The canonical use\n * case is a tool that needs to summarize / classify / structure some\n * text internally without carrying its own API key.\n *\n * This module provides:\n *\n * - `SamplingHandler` — the function callers can install via\n * `EngineInternals.samplingHandler` to customize routing.\n * - `defaultSamplingHandler(modelAdapter)` — a ready-to-use default\n * that routes every request to the engine's own model adapter.\n * Same model, same API key, same billing.\n * - Request/response shapes mirroring MCP's schema closely enough to\n * translate both directions without leaking SDK internals into the\n * rest of the engine.\n *\n * Safety: calling sampling is OFF by default per MCP server\n * (`allowSampling: false`). When a server attempts sampling and the\n * flag is off, the McpClient responds with a protocol error instead\n * of invoking the handler. The handler itself is only called after\n * the gate passes.\n */\n\nimport type { ModelAdapter } from '../model/adapter.js'\n\n/** Content block shape accepted from / sent to the MCP server. */\nexport interface SamplingTextBlock {\n readonly type: 'text'\n readonly text: string\n}\n\nexport interface SamplingMessage {\n readonly role: 'user' | 'assistant'\n readonly content: SamplingTextBlock | ReadonlyArray<SamplingTextBlock>\n}\n\nexport interface SamplingModelPreferences {\n readonly hints?: ReadonlyArray<{ readonly name?: string }>\n readonly costPriority?: number\n readonly speedPriority?: number\n readonly intelligencePriority?: number\n}\n\nexport interface SamplingRequest {\n readonly messages: ReadonlyArray<SamplingMessage>\n readonly systemPrompt?: string\n readonly maxTokens: number\n readonly temperature?: number\n readonly stopSequences?: ReadonlyArray<string>\n readonly modelPreferences?: SamplingModelPreferences\n readonly includeContext?: 'none' | 'thisServer' | 'allServers'\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\nexport interface SamplingResponse {\n readonly role: 'assistant'\n readonly model: string\n /** The assistant text. */\n readonly content: SamplingTextBlock\n readonly stopReason?: 'endTurn' | 'stopSequence' | 'maxTokens' | 'error'\n}\n\nexport interface SamplingContext {\n /** MCP server that issued the request. */\n readonly serverName: string\n /** Engine runId for the run this handler was invoked inside. */\n readonly runId?: string\n /** Engine nodeId for the run. */\n readonly nodeId?: string\n /**\n * Nesting depth — incremented when sampling itself triggers another\n * sampling request. Guards against loops: handlers MAY refuse when\n * `depth` exceeds a threshold (default implementation refuses at 3).\n */\n readonly depth: number\n}\n\nexport type SamplingHandler = (\n request: SamplingRequest,\n context: SamplingContext,\n) => Promise<SamplingResponse>\n\n/** Max depth the default handler will recurse through. */\nexport const DEFAULT_SAMPLING_MAX_DEPTH = 3\n\n/**\n * Build a default handler that routes every sampling request to the\n * provided `ModelAdapter`. Consumes the stream, concatenates the text\n * blocks, and maps the stop reason into the MCP vocabulary.\n *\n * If you want a different model per server, provide a custom\n * handler via `EngineInternals.samplingHandler`.\n */\nexport function defaultSamplingHandler(modelAdapter: ModelAdapter): SamplingHandler {\n return async (request, context) => {\n if (context.depth > DEFAULT_SAMPLING_MAX_DEPTH) {\n throw new Error(\n `Sampling depth ${String(context.depth)} exceeded max ${String(DEFAULT_SAMPLING_MAX_DEPTH)} — refusing to prevent loops`,\n )\n }\n\n const messages = request.messages.map((m) => ({\n role: m.role,\n content: extractText(m.content),\n }))\n\n const textChunks: string[] = []\n let mcpStopReason: NonNullable<SamplingResponse['stopReason']> = 'endTurn'\n\n for await (const event of modelAdapter.streamMessage({\n messages,\n ...(request.systemPrompt !== undefined ? { system: request.systemPrompt } : {}),\n maxTokens: request.maxTokens,\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n })) {\n if (event.type === 'text') textChunks.push(event.text)\n if (event.type === 'message_stop') {\n mcpStopReason = mapStopReason(event.stopReason)\n }\n }\n\n return {\n role: 'assistant',\n // We don't know the concrete model id at this layer — adapters\n // should fill it in if they care. Use a generic label.\n model: 'engine-default',\n content: { type: 'text', text: textChunks.join('') },\n stopReason: mcpStopReason,\n }\n }\n}\n\nfunction extractText(content: SamplingTextBlock | ReadonlyArray<SamplingTextBlock>): string {\n if (Array.isArray(content)) {\n return content.map((b) => b.text).join('')\n }\n return (content as SamplingTextBlock).text\n}\n\nfunction mapStopReason(sr: unknown): NonNullable<SamplingResponse['stopReason']> {\n switch (sr) {\n case 'end_turn':\n case 'tool_use':\n case 'pause_turn':\n return 'endTurn'\n case 'stop_sequence':\n return 'stopSequence'\n case 'max_tokens':\n return 'maxTokens'\n case 'refusal':\n return 'error'\n default:\n return 'endTurn'\n }\n}\n","/**\n * Permission evaluator — the decision pipeline.\n *\n * Pipeline (evaluated in order, first match wins):\n *\n * 1. Mode check:\n * - `'open'` → allow immediately (no further evaluation)\n * - `'locked'` → check allowlist only (skip rules entirely)\n * - `'rules'` → proceed to step 2\n *\n * 2. Safe-tool allowlist fast-path:\n * - If the tool is on the safe allowlist → allow (skip rules)\n *\n * 3. Rule evaluation (top-to-bottom):\n * - First matching rule wins\n * - `allow:X` → allow\n * - `deny:X` → deny with reason\n *\n * 4. Fall-closed:\n * - If no rule matched → deny (\"no matching rule, mode is rules\")\n *\n * The evaluator is a pure function: no side effects, no LLM calls.\n * The gate hook (`hooks.gateBeforeTool`) runs AFTER this evaluation in\n * the engine's tool dispatch — it can override a permission allow with\n * a pause, but it cannot override a permission deny.\n */\n\nimport { isSafeTool } from './allowlist.js'\nimport { matchesRule, parseRules } from './rules.js'\nimport type { PermissionDecision, PermissionRule, ResolvedPermissionsConfig } from './types.js'\n\n/**\n * Compiled permission policy — call `check(toolName)` to get a decision.\n * Built once at engine construction time from the resolved config.\n */\nexport interface PermissionPolicy {\n check(toolName: string): PermissionDecision\n}\n\nconst ALLOW: PermissionDecision = { allowed: true }\n\n/**\n * Build a `PermissionPolicy` from a resolved config. The returned\n * object is reusable across all runs on the same engine instance.\n */\nexport function buildPermissionPolicy(config: ResolvedPermissionsConfig): PermissionPolicy {\n if (config.mode === 'open') {\n return { check: () => ALLOW }\n }\n\n if (config.mode === 'locked') {\n return {\n check: (toolName: string): PermissionDecision => {\n if (isSafeTool(toolName)) return ALLOW\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" is not on the safe-tool allowlist (mode: locked)`,\n }\n },\n }\n }\n\n // mode === 'rules'\n const rules: readonly PermissionRule[] = parseRules(config.rules)\n\n return {\n check: (toolName: string): PermissionDecision => {\n // Fast path: safe tools bypass rules.\n if (isSafeTool(toolName)) return ALLOW\n\n // Evaluate rules top-to-bottom, first match wins.\n for (const rule of rules) {\n if (matchesRule(toolName, rule)) {\n if (rule.action === 'allow') return ALLOW\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" matched deny rule \"${rule.action}:${rule.pattern}\"`,\n }\n }\n }\n\n // No rule matched — fall closed.\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" — no matching rule (mode: rules, fall-closed)`,\n }\n },\n }\n}\n","/**\n * Safe tool allowlist — tools that are always safe to run without\n * human approval or rule evaluation.\n *\n * Ported from La-Machina's `SAFE_YOLO_ALLOWLISTED_TOOLS`. These tools\n * are read-only or purely informational — they cannot modify the\n * filesystem, send messages, or cause side effects beyond reading state.\n *\n * Used by `'locked'` mode: only these tools pass, everything else is\n * denied. Also used as a fast-path in `'rules'` mode: allowlisted tools\n * skip rule evaluation entirely.\n */\n\nexport const SAFE_TOOL_ALLOWLIST: ReadonlySet<string> = new Set([\n // Filesystem reads\n 'Read',\n 'Glob',\n 'Grep',\n\n // Task management (read/write internal state, no external side effects)\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n\n // Memory (read/write engine-internal memory, no external effects)\n 'Memorize',\n 'Recall',\n\n // Search + discovery (read-only)\n 'ToolSearch',\n 'SkillPage',\n 'WebSearch',\n\n // Plan/question (informational, triggers pause or produces output)\n 'AskUserQuestion',\n\n // Agent spawning (scoped to engine's own context)\n 'Agent',\n\n // Sleep (no side effects)\n 'Sleep',\n])\n\n/**\n * Check if a tool name is on the safe allowlist.\n */\nexport function isSafeTool(toolName: string): boolean {\n return SAFE_TOOL_ALLOWLIST.has(toolName)\n}\n","/**\n * Rule parser + matcher.\n *\n * Rule string format: `\"action:pattern\"`\n * - action: `allow` or `deny`\n * - pattern: exact tool name or glob with `*` wildcard\n *\n * Examples:\n * - `\"allow:Read\"` → allow the Read tool\n * - `\"deny:Bash\"` → deny the Bash tool\n * - `\"allow:mcp__fs__*\"` → allow all tools from the fs MCP server\n * - `\"deny:mcp__*\"` → deny all MCP tools\n * - `\"deny:*\"` → deny everything (catch-all)\n * - `\"allow:*\"` → allow everything (catch-all)\n *\n * Invalid rule strings are silently skipped (logged at warn level by\n * the evaluator).\n */\n\nimport picomatch from 'picomatch'\nimport type { PermissionAction, PermissionRule } from './types.js'\n\n/**\n * Parse a rule string into a structured `PermissionRule`. Returns null\n * if the string is malformed.\n */\nexport function parseRule(raw: string): PermissionRule | null {\n const colonIndex = raw.indexOf(':')\n if (colonIndex === -1) return null\n\n const action = raw.slice(0, colonIndex).trim().toLowerCase()\n const pattern = raw.slice(colonIndex + 1).trim()\n\n if (action !== 'allow' && action !== 'deny') return null\n if (pattern.length === 0) return null\n\n return { action: action as PermissionAction, pattern }\n}\n\n/**\n * Parse an array of rule strings into structured rules, skipping\n * malformed entries.\n */\nexport function parseRules(raw: readonly string[]): readonly PermissionRule[] {\n const out: PermissionRule[] = []\n for (const r of raw) {\n const parsed = parseRule(r)\n if (parsed !== null) out.push(parsed)\n }\n return out\n}\n\n/**\n * Check if a tool name matches a rule's pattern. Uses picomatch for\n * glob support (same library the engine uses for Glob/Grep tools).\n */\nexport function matchesRule(toolName: string, rule: PermissionRule): boolean {\n if (rule.pattern === '*') return true\n if (rule.pattern === toolName) return true\n return picomatch.isMatch(toolName, rule.pattern)\n}\n","/**\n * memoryConfig — applies the engine's `memory.mode` and `memory.scope`\n * gates to a wrapped Hippocampus + EpisodicMemory pair.\n *\n * Three modes from `ResolvedMemoryConfig`:\n *\n * - `'off'` — All reads return empty, all writes are no-ops.\n * The wrapped Hippocampus is built but never touched.\n * - `'read-only'` — Reads pass through to the wrapped Hippocampus,\n * writes are silent no-ops.\n * - `'read-write'` — Both reads and writes pass through.\n *\n * Scope (Plan 022): memory always reads/writes the workspace\n * adapter. The previous `'global'` scope was removed — the workspace\n * is the tenant root and nothing spans tenants.\n *\n * The factory returns a thin façade that exposes Hippocampus's read +\n * write surface plus the EpisodicMemory instance. The agent loop and\n * tools talk to this façade, never the raw Hippocampus.\n */\n\nimport type { MemoryMode, MemoryScope } from '../config/types.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { EpisodicMemory } from './episodes.js'\nimport { Hippocampus } from './hippocampus.js'\nimport type { EngramConfidence, EngramSource } from './types.js'\n\nexport interface SmartMemoryConfig {\n readonly mode: MemoryMode\n readonly scope: MemoryScope\n}\n\nexport interface SmartMemoryOptions {\n readonly storage: EngineStorage\n readonly config: SmartMemoryConfig\n}\n\nexport interface SmartMemory {\n readonly mode: MemoryMode\n readonly scope: MemoryScope\n readonly episodes: EpisodicMemory\n\n // ---------- recall ----------\n recallIdentity(): Promise<string>\n recallRules(): Promise<string>\n recallLessons(tokenBudget?: number): Promise<string>\n recallTopic(slug: string): Promise<string>\n\n // ---------- encode ----------\n encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence?: EngramConfidence,\n source?: EngramSource,\n ): Promise<void>\n encodeLesson(text: string, topic?: string, source?: EngramSource): Promise<void>\n rewriteIdentity(entries: ReadonlyArray<string>): Promise<void>\n}\n\nexport function createSmartMemory(options: SmartMemoryOptions): SmartMemory {\n const { storage, config } = options\n // Plan 022 — memory always lives in workspace scope.\n const adapter = storage.workspace\n const hippocampus = new Hippocampus(adapter, 'smart-memory')\n\n const writesEnabled = config.mode === 'read-write'\n const readsEnabled = config.mode !== 'off'\n\n // Episodic memory is write-only by nature; only enable when writes\n // are allowed AND mode isn't 'off'. Read-only mode keeps episodes off.\n const episodes = new EpisodicMemory(adapter, 'smart-memory/episodes', writesEnabled)\n\n return {\n mode: config.mode,\n scope: config.scope,\n episodes,\n\n async recallIdentity(): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallIdentity()\n },\n\n async recallRules(): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallRules()\n },\n\n async recallLessons(tokenBudget?: number): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallLessons(tokenBudget)\n },\n\n async recallTopic(slug: string): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallTopic(slug)\n },\n\n async encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence?: EngramConfidence,\n source?: EngramSource,\n ): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.encodeRule(text, kind, confidence, source)\n },\n\n async encodeLesson(text: string, topic?: string, source?: EngramSource): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.encodeLesson(text, topic, source)\n },\n\n async rewriteIdentity(entries: ReadonlyArray<string>): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.rewriteIdentity(entries)\n },\n }\n}\n","/**\n * EpisodicMemory — append-only JSONL log of every turn in a run.\n *\n * Ported from La-Machina with TS-strict cleanup. The episodic log\n * captures the raw timeline of conversation turns (user input,\n * assistant text, tool calls, tool results) for later inspection,\n * search, or training data extraction.\n *\n * Design rules:\n * - **Fire-and-forget**: `logTurn()` returns synchronously and never\n * throws. Storage errors are swallowed so logging cannot break the\n * agent loop.\n * - **Disabled = total no-op**: when `enabled` is false, no file is\n * created and `logTurn()` does nothing. Used to implement\n * `memory.mode === 'off'` at the engine config layer.\n * - **Per-session file**: each `startSession()` mints a fresh JSONL\n * under `{subdir}/{sessionId}.jsonl`. Format `YYYYMMDD_HHMMSS`.\n * - **Truncation**: tool_call and tool_result content is capped at\n * 2000 characters to keep individual entries small.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { Episode } from './types.js'\n\nconst MAX_TOOL_INPUT = 2000\nconst MAX_TOOL_RESULT = 2000\n\nexport class EpisodicMemory {\n private readonly storage: StorageAdapter\n private readonly subdir: string\n private _enabled: boolean\n private _sessionId: string | null = null\n private _filePath: string | null = null\n /**\n * Serialization chain — every log() chains its appendFile onto the\n * previous one so on-disk order matches call order. Without this,\n * two concurrent unawaited appendFile calls can land in arbitrary\n * order even though each individual O_APPEND is atomic.\n */\n private writeChain: Promise<void> = Promise.resolve()\n\n constructor(storage: StorageAdapter, subdir = 'smart-memory/episodes', enabled = true) {\n this.storage = storage\n this.subdir = subdir\n this._enabled = enabled\n }\n\n get enabled(): boolean {\n return this._enabled\n }\n\n set enabled(value: boolean) {\n this._enabled = value\n }\n\n get currentSessionId(): string | null {\n return this._sessionId\n }\n\n /**\n * Start a new session — mints a timestamp-based id and creates an\n * empty JSONL file under `{subdir}/`. Returns the session id, or\n * empty string if disabled.\n */\n async startSession(): Promise<string> {\n if (!this._enabled) return ''\n\n const now = new Date()\n const y = now.getUTCFullYear()\n const mo = String(now.getUTCMonth() + 1).padStart(2, '0')\n const d = String(now.getUTCDate()).padStart(2, '0')\n const h = String(now.getUTCHours()).padStart(2, '0')\n const mi = String(now.getUTCMinutes()).padStart(2, '0')\n const s = String(now.getUTCSeconds()).padStart(2, '0')\n this._sessionId = `${y}${mo}${d}_${h}${mi}${s}`\n this._filePath = `${this.subdir}/${this._sessionId}.jsonl`\n\n try {\n if (!(await this.storage.exists(this._filePath))) {\n await this.storage.writeFile(this._filePath, '')\n }\n } catch {\n // Fire-and-forget — failures here don't kill the run.\n }\n\n return this._sessionId\n }\n\n async resumeSession(sessionId: string): Promise<string> {\n this._sessionId = sessionId\n this._filePath = `${this.subdir}/${sessionId}.jsonl`\n try {\n if (!(await this.storage.exists(this._filePath))) {\n await this.storage.writeFile(this._filePath, '')\n }\n } catch {\n // Fire-and-forget\n }\n return this._sessionId\n }\n\n /**\n * Log a single episode entry. Fire-and-forget — never blocks, never\n * throws. Disabled mode and missing session both produce silent\n * no-ops so callers don't have to guard.\n */\n log(episode: Episode): void {\n if (!this._enabled || this._filePath === null) return\n const line = JSON.stringify(episode) + '\\n'\n const filePath = this._filePath\n // Chain onto the previous write so concurrent log() calls land\n // in the order they were issued. Errors are swallowed — episodic\n // logging must never block conversation.\n this.writeChain = this.writeChain.then(() =>\n this.storage.appendFile(filePath, line).catch(() => undefined),\n )\n }\n\n /** Convenience wrapper that builds an Episode and logs it. */\n logTurn(\n turn: number,\n role: Episode['role'],\n content: string,\n meta: Readonly<Record<string, unknown>> = {},\n ): void {\n if (!this._enabled || this._sessionId === null) return\n\n let truncated = content\n if (role === 'tool_call' && truncated.length > MAX_TOOL_INPUT) {\n truncated = truncated.slice(0, MAX_TOOL_INPUT)\n } else if (role === 'tool_result' && truncated.length > MAX_TOOL_RESULT) {\n truncated = truncated.slice(0, MAX_TOOL_RESULT)\n }\n\n this.log({\n ts: new Date().toISOString(),\n session: this._sessionId,\n turn,\n role,\n content: truncated,\n meta,\n })\n }\n}\n","/**\n * Hippocampus — memory encoding and retrieval engine.\n *\n * Ported from La-Machina. Named for the brain's hippocampus, which\n * encodes new traces (writing) and pattern-completes partial cues into\n * full memories (reading).\n *\n * Each Hippocampus instance manages one scope's files via a\n * StorageAdapter:\n * - profile.md → identity (full rewrite, not append)\n * - rules.md → behavioral gates (always / never / when sections)\n * - lessons.md → semantic facts (append + dedup, token-budgeted recall)\n * - topics/*.md → per-topic deep dives\n *\n * The storage backend is fully abstracted — the same instance works\n * against local fs or R2. Read-modify-write paths use the adapter's\n * atomic `writeFile` so concurrent writers see one or the other, never\n * a partial.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { EngramConfidence, EngramSource } from './types.js'\n\n// Metadata comment pattern: <!-- key:value key:value -->\nconst METADATA_RE = /\\s*<!--[\\s\\S]*?-->\\s*$/\n\nconst RULES_SKELETON = '# Rules\\n\\n## Always\\n\\n## Never\\n\\n## When\\n'\n\nexport class Hippocampus {\n private readonly storage: StorageAdapter\n private readonly subdir: string\n private readonly profilePath: string\n private readonly rulesPath: string\n private readonly lessonsPath: string\n private readonly topicsDir: string\n\n constructor(storage: StorageAdapter, subdir = 'smart-memory') {\n this.storage = storage\n this.subdir = subdir\n this.profilePath = `${subdir}/profile.md`\n this.rulesPath = `${subdir}/rules.md`\n this.lessonsPath = `${subdir}/lessons.md`\n this.topicsDir = `${subdir}/topics`\n }\n\n // ---------- recall (read) ----------\n\n async recallIdentity(): Promise<string> {\n const content = await this.storage.readFile(this.profilePath)\n return (content ?? '').trim()\n }\n\n async recallRules(): Promise<string> {\n const content = await this.storage.readFile(this.rulesPath)\n return (content ?? '').trim()\n }\n\n /**\n * Load semantic knowledge most recent first, within a token budget\n * (rough heuristic: 4 chars per token). The header lines (# Lessons,\n * blank lines) always survive; entry lines fill the remaining budget\n * starting from the most recent.\n */\n async recallLessons(tokenBudget = 1000): Promise<string> {\n const content = await this.storage.readFile(this.lessonsPath)\n if (content === null || content.trim().length === 0) return ''\n\n const lines = content\n .trim()\n .split('\\n')\n .filter((ln) => ln.trim().length > 0)\n const headerLines: string[] = []\n const entryLines: string[] = []\n\n for (const ln of lines) {\n if (ln.startsWith('- ') || ln.startsWith(' ')) {\n entryLines.push(ln)\n } else {\n headerLines.push(ln)\n }\n }\n\n // Reverse so most recent are first.\n entryLines.reverse()\n\n const charBudget = tokenBudget * 4\n const resultLines: string[] = [...headerLines]\n let used = resultLines.reduce((sum, ln) => sum + ln.length, 0)\n\n for (const ln of entryLines) {\n if (used + ln.length + 1 > charBudget) break\n resultLines.push(ln)\n used += ln.length + 1\n }\n\n return resultLines.join('\\n')\n }\n\n async recallTopic(slug: string): Promise<string> {\n const safeSlug = Hippocampus.sanitizeSlug(slug)\n const topicPath = `${this.topicsDir}/${safeSlug}.md`\n const content = await this.storage.readFile(topicPath)\n return (content ?? '').trim()\n }\n\n // ---------- encode (write) ----------\n\n async encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence: EngramConfidence = 'medium',\n source: EngramSource = 'llm',\n ): Promise<void> {\n const ts = new Date().toISOString().slice(0, 10)\n const metadata = `<!-- confidence:${confidence} source:${source} ts:${ts} -->`\n const entry = `- ${text} ${metadata}\\n`\n const sectionHeader = `## ${kind.charAt(0).toUpperCase()}${kind.slice(1)}`\n\n let content = await this.storage.readFile(this.rulesPath)\n if (content === null) content = RULES_SKELETON\n\n if (Hippocampus.extractEntryTexts(content).has(text)) return\n\n const lines = content.split(/(?<=\\n)/) // split keeping newlines\n const out: string[] = []\n let inserted = false\n let i = 0\n\n while (i < lines.length) {\n const current = lines[i] as string\n out.push(current)\n if (current.trim() === sectionHeader && !inserted) {\n i++\n const sectionEntries: string[] = []\n while (\n i < lines.length &&\n !(\n (lines[i] as string).trim().startsWith('## ') &&\n (lines[i] as string).trim() !== sectionHeader\n )\n ) {\n sectionEntries.push(lines[i] as string)\n i++\n }\n out.push(...sectionEntries)\n const lastEntry = sectionEntries[sectionEntries.length - 1]\n if (sectionEntries.length > 0 && lastEntry !== undefined && lastEntry.trim().length > 0) {\n out.push('\\n')\n }\n out.push(entry)\n inserted = true\n continue\n }\n i++\n }\n\n if (!inserted) {\n out.push(`\\n${sectionHeader}\\n${entry}`)\n }\n\n await this.storage.writeFile(this.rulesPath, out.join(''))\n }\n\n async encodeLesson(text: string, topic = '', source: EngramSource = 'llm'): Promise<void> {\n const ts = new Date().toISOString().slice(0, 10)\n const topicTag = topic ? ` topic:${topic}` : ''\n const sourceTag = source !== 'llm' ? ` source:${source}` : ''\n const entry = `- ${text} <!--${topicTag}${sourceTag} ts:${ts} -->\\n`\n\n const existing = await this.storage.readFile(this.lessonsPath)\n if (existing === null) {\n await this.storage.writeFile(this.lessonsPath, `# Lessons\\n${entry}`)\n } else if (!Hippocampus.extractEntryTexts(existing).has(text)) {\n await this.storage.appendFile(this.lessonsPath, entry)\n }\n\n if (topic) {\n const slug = Hippocampus.sanitizeSlug(topic)\n const topicPath = `${this.topicsDir}/${slug}.md`\n const topicContent = await this.storage.readFile(topicPath)\n if (topicContent === null) {\n await this.storage.writeFile(topicPath, `# ${topic}\\n${entry}`)\n } else if (!Hippocampus.extractEntryTexts(topicContent).has(text)) {\n await this.storage.appendFile(topicPath, entry)\n }\n }\n }\n\n /**\n * Replace the identity snapshot — full rewrite, not append. Identity\n * is a coherent snapshot, not an append log.\n */\n async rewriteIdentity(entries: ReadonlyArray<string>): Promise<void> {\n const content = `# Profile\\n${entries.map((e) => `- ${e}`).join('\\n')}\\n`\n await this.storage.writeFile(this.profilePath, content)\n }\n\n async entryCount(): Promise<number> {\n let count = 0\n for (const filePath of [this.rulesPath, this.lessonsPath]) {\n const content = await this.storage.readFile(filePath)\n if (content === null) continue\n count += content.split('\\n').filter((ln) => ln.trim().startsWith('- ')).length\n }\n return count\n }\n\n // ---------- accessors ----------\n\n getStorage(): StorageAdapter {\n return this.storage\n }\n\n get rulesPathRelative(): string {\n return this.rulesPath\n }\n\n get lessonsPathRelative(): string {\n return this.lessonsPath\n }\n\n get subdirPath(): string {\n return this.subdir\n }\n\n // ---------- static helpers ----------\n\n /**\n * Extract normalized entry texts from a markdown memory file.\n * Strips the \"- \" prefix and trailing `<!-- ... -->` metadata so\n * dedup works regardless of the comment payload.\n */\n static extractEntryTexts(content: string): Set<string> {\n const texts = new Set<string>()\n for (const line of content.split('\\n')) {\n const stripped = line.trim()\n if (!stripped.startsWith('- ')) continue\n let entry = stripped.slice(2)\n entry = entry.replace(METADATA_RE, '').trim()\n if (entry.length > 0) texts.add(entry)\n }\n return texts\n }\n\n /** Sanitize a topic name into a safe file slug. */\n static sanitizeSlug(name: string): string {\n let text = name.toLowerCase().trim()\n text = text.replace(/[^a-z0-9\\s_-]/g, '')\n text = text.replace(/\\s+/g, '-')\n text = text.replace(/-+/g, '-')\n text = text.replace(/^-|-$/g, '')\n return text.length > 0 ? text : 'general'\n }\n}\n","/**\n * buildSystemPrompt — assemble the full system prompt from static\n * sections, dynamic per-run sections, and optional memory/skill recall.\n *\n * Section order (matches La-Machina's cacheable/dynamic split):\n *\n * ── STATIC (cacheable prefix — identical across runs) ──\n * 1. Base identity + capabilities\n * 2. Doing tasks (behavioral rules)\n * 3. Executing actions with care (reversibility, blast radius)\n * 4. Using your tools (tool-specific instructions)\n * 5. Tone and style + output efficiency\n *\n * ── DYNAMIC (changes per-run) ──\n * 6. Environment (OS, CWD, model, date)\n * 7. MCP tools (when config.mcp.servers is populated)\n * 8. Identity (smart memory profile.md)\n * 9. Rules (smart memory rules.md)\n * 10. Lessons (smart memory lessons.md, token-budgeted)\n * 11. Skills (loadSkills() output as name/description list)\n * 12. Custom base (caller-supplied override, appended last)\n *\n * The function is async because memory recall and skill discovery both\n * involve storage adapter reads. It's pure-ish — no writes, no side\n * effects beyond the reads themselves.\n */\n\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport type { Tool } from '../tools/contract.js'\nimport { loadSkills } from '../skills/loader.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { getBaseSection } from './sections/base.js'\nimport { getDoingTasksSection } from './sections/doingTasks.js'\nimport { getActionsSection } from './sections/actions.js'\nimport { getUsingToolsSection } from './sections/usingTools.js'\nimport { getToneAndStyleSection } from './sections/toneAndStyle.js'\nimport { getEnvironmentSection } from './sections/environment.js'\nimport { getMcpSection } from './sections/mcp.js'\n\nexport interface BuildSystemPromptOptions {\n /** Custom base instruction appended to the system prompt. */\n readonly base?: string\n /** SmartMemory façade — reads are gated by memory mode. */\n readonly memory: SmartMemory\n /** Storage adapter pair — used to enumerate skills. */\n readonly storage: EngineStorage\n /** Whether to scan and inject the skill index. */\n readonly skillsAutoload: boolean\n /** Directory to scan for skills (relative to each scope's adapter root). */\n readonly skillsDir?: string\n /**\n * Pre-resolved skill catalogue. When set, takes precedence over the\n * disk scan (`skillsAutoload` + `skillsDir`). Used by the engine when\n * `RunOptions.skills` supplies an inline list via `InlineSkillSource`.\n */\n readonly skillList?: ReadonlyArray<{ name: string; description: string }>\n /** Token budget for the lessons section (default: 1000). */\n readonly lessonsTokenBudget?: number\n /** Model ID for the environment section. */\n readonly modelId?: string\n /** Provider name for the environment section. */\n readonly provider?: string\n /** Working directory override for the environment section. */\n readonly cwd?: string\n /** Registered tool names — drives tool-specific prompt instructions. */\n readonly registeredToolNames?: ReadonlySet<string>\n /** MCP-sourced tools — listed in a dedicated prompt section. */\n readonly mcpTools?: ReadonlyArray<Tool>\n /** When true, skip normal static sections (base/doingTasks/etc.) —\n * the coordinator prompt replaces them via `base`. */\n readonly coordinatorMode?: boolean\n}\n\nexport async function buildSystemPrompt(options: BuildSystemPromptOptions): Promise<string> {\n const sections: string[] = []\n\n // ── STATIC SECTIONS ──\n // In coordinator mode, the coordinator prompt (passed via options.base)\n // replaces the normal static sections. The dynamic sections below\n // (environment, MCP, memory, skills) are still appended.\n if (!options.coordinatorMode) {\n sections.push(getBaseSection())\n sections.push(getDoingTasksSection())\n sections.push(getActionsSection())\n\n if (options.registeredToolNames !== undefined && options.registeredToolNames.size > 0) {\n sections.push(getUsingToolsSection({ registeredToolNames: options.registeredToolNames }))\n }\n\n sections.push(getToneAndStyleSection())\n }\n\n // ── DYNAMIC SECTIONS ──\n\n sections.push(\n await getEnvironmentSection({\n modelId: options.modelId ?? 'unknown',\n provider: options.provider ?? 'unknown',\n cwd: options.cwd,\n }),\n )\n\n // MCP tools section — only when MCP tools are registered.\n if (options.mcpTools !== undefined && options.mcpTools.length > 0) {\n const mcpSection = getMcpSection({ mcpTools: options.mcpTools })\n if (mcpSection !== null) sections.push(mcpSection)\n }\n\n // Memory sections — each gated by SmartMemory.mode internally.\n const identity = await options.memory.recallIdentity()\n if (identity.length > 0) {\n sections.push(`# Identity\\n${identity}`)\n }\n\n const rules = await options.memory.recallRules()\n if (rules.length > 0) {\n sections.push(`# Rules\\n${rules}`)\n }\n\n const lessons = await options.memory.recallLessons(options.lessonsTokenBudget)\n if (lessons.length > 0) {\n sections.push(`# Lessons\\n${lessons}`)\n }\n\n // Skills section.\n //\n // Two sources of truth, in precedence order:\n // 1. Pre-resolved `options.skillList` — set by the caller when they\n // already know the catalogue (e.g., RunOptions.skills override).\n // 2. Fallback disk scan via `skillsAutoload` + `skillsDir`.\n //\n // Callers using `SkillSource` (Plan 017) pass `skillList` directly and\n // leave `skillsAutoload` false. The legacy path is kept for backwards\n // compatibility with callers still supplying only `skillsAutoload`.\n const effectiveSkillList: ReadonlyArray<{ name: string; description: string }> | undefined =\n options.skillList !== undefined\n ? options.skillList\n : options.skillsAutoload\n ? await collectSkills(options.storage, options.skillsDir ?? 'skills')\n : undefined\n\n if (effectiveSkillList !== undefined && effectiveSkillList.length > 0) {\n const lines: string[] = ['# Skills']\n for (const skill of effectiveSkillList) {\n lines.push(`- ${skill.name}: ${skill.description}`)\n }\n lines.push('', 'Use the SkillPage tool to load a specific page from a multi-page skill.')\n sections.push(lines.join('\\n'))\n }\n\n // Custom base — In coordinator mode, the coordinator prompt was\n // already prepended at the top (before dynamic sections). In normal\n // mode, it's appended at the end so callers can override.\n if (options.base !== undefined && options.base.length > 0) {\n if (options.coordinatorMode) {\n // Prepend — coordinator prompt is the identity section.\n sections.unshift(options.base)\n } else {\n sections.push(options.base)\n }\n }\n\n return sections.join('\\n\\n')\n}\n\nasync function collectSkills(\n storage: EngineStorage,\n skillsDir: string,\n): Promise<Array<{ name: string; description: string }>> {\n // Plan 022 — workspace-only. Previous workspace+global merge was\n // removed along with the global scope.\n const workspace = await loadSkills(storage.workspace, skillsDir)\n return workspace.map((s) => ({ name: s.name, description: s.description }))\n}\n","/**\n * Skills loader — discovers `SKILL.md` files under a base directory.\n *\n * The skill format is intentionally minimal:\n *\n * skills/\n * ├── alpha/\n * │ ├── SKILL.md ← required (name + description)\n * │ └── pages/ ← optional (multi-page skill)\n * │ ├── intro.md\n * │ └── advanced.md\n * └── beta/\n * └── SKILL.md\n *\n * The loader returns one `LoadedSkill` per discovered `SKILL.md`. The\n * description is extracted from the first non-empty body line (anything\n * after the title heading) — falling back to the heading text itself if\n * the file has no body.\n *\n * The result feeds into:\n * - the system prompt builder (Phase 12+) which injects skill names +\n * descriptions so the model knows what's available\n * - the SkillPage tool, which lets the model load specific pages on\n * demand for multi-page skills\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface LoadedSkill {\n /** Folder name (also used as the lookup key in SkillPage). */\n readonly name: string\n /** Human-readable description, extracted from SKILL.md. */\n readonly description: string\n /** Whether the skill has a pages/ subdirectory with content. */\n readonly hasPages: boolean\n /** Full relative path to the skill folder, e.g. \"skills/alpha\". */\n readonly path: string\n /** Full relative path to the SKILL.md file. */\n readonly skillFilePath: string\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\n/**\n * Walk the given base directory and return one entry per discovered\n * skill. Returns an empty array when the base directory does not exist\n * or contains no skills.\n */\nexport async function loadSkills(storage: StorageAdapter, baseDir: string): Promise<LoadedSkill[]> {\n const entries = await storage.listDir(baseDir)\n if (entries.length === 0) return []\n\n const out: LoadedSkill[] = []\n\n for (const entry of entries.slice().sort()) {\n if (!SAFE_NAME.test(entry)) continue\n const folder = `${baseDir}/${entry}`\n if (!(await storage.isDirectory(folder))) continue\n\n const skillFilePath = `${folder}/SKILL.md`\n const content = await storage.readFile(skillFilePath)\n if (content === null) continue\n\n const description = extractDescription(content)\n const pagesDir = `${folder}/pages`\n const hasPages =\n (await storage.isDirectory(pagesDir)) && (await storage.listDir(pagesDir)).length > 0\n\n out.push({\n name: entry,\n description,\n hasPages,\n path: folder,\n skillFilePath,\n })\n }\n\n return out\n}\n\n/**\n * Pull a one-line description out of a SKILL.md document.\n *\n * Strategy:\n * 1. If the body has a non-empty paragraph (after a `# Heading`), use\n * its first line.\n * 2. Otherwise, use the heading text itself (with `# ` stripped).\n * 3. Otherwise return an empty string.\n */\nfunction extractDescription(content: string): string {\n const lines = content.split('\\n')\n let headingText = ''\n let inBody = false\n\n for (const rawLine of lines) {\n const line = rawLine.trim()\n if (!inBody) {\n // Capture the first heading\n if (line.startsWith('#')) {\n headingText = line.replace(/^#+\\s*/, '').trim()\n inBody = true\n continue\n }\n // No heading at all — use the first non-empty line\n if (line.length > 0) return line\n } else {\n // Body — return the first non-empty line\n if (line.length > 0) return line\n }\n }\n\n return headingText\n}\n","/**\n * Base identity + capabilities — the engine's equivalent of La-Machina's\n * SimpleIntro + SimpleSystem sections.\n *\n * Adapted for headless: no slash commands, no interactive prompts, no\n * terminal rendering. The model is told it runs inside la-machina-engine,\n * returns structured results, and works through tools.\n */\n\nexport function getBaseSection(): string {\n return `# System\n\nYou are an AI assistant running inside la-machina-engine. You complete tasks by using the tools available to you. Your output goes to a programmatic caller (not a human terminal), so focus on correctness and completeness.\n\nIMPORTANT: Assist with authorized security testing, defensive security, CTF challenges, and educational contexts. Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes.\nIMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident they are correct. You may use URLs provided in the task or discovered via tools.`\n}\n","/**\n * Task execution guidance — ported from La-Machina's SimpleDoingTasks.\n *\n * This is the core behavioral instruction set. Covers: ambition,\n * read-before-modify, security, code quality, verification, and honest\n * reporting. Kept nearly verbatim from La-Machina; terminal-only lines\n * (slash commands, /issue, /share) removed.\n */\n\nexport function getDoingTasksSection(): string {\n return `# Doing tasks\n\n- The caller will request you to perform tasks — solving bugs, adding features, refactoring, analyzing data, research, and more.\n- You are highly capable and often allow callers to complete ambitious tasks that would otherwise be too complex or take too long. You should defer to the caller's judgement about whether a task is too large to attempt.\n- If you notice the request is based on a misconception, or spot a bug adjacent to what was asked about, say so. You're a collaborator, not just an executor — callers benefit from your judgment, not just your compliance.\n- In general, do not propose changes to code you haven't read. If asked about or to modify a file, read it first. Understand existing code before suggesting modifications.\n- Do not create files unless they're absolutely necessary for achieving your goal. Generally prefer editing an existing file to creating a new one, as this prevents file bloat and builds on existing work more effectively.\n- Avoid giving time estimates or predictions for how long tasks will take. Focus on what needs to be done, not how long it might take.\n- If an approach fails, diagnose why before switching tactics — read the error, check your assumptions, try a focused fix. Don't retry the identical action blindly, but don't abandon a viable approach after a single failure either. Escalate only when you're genuinely stuck after investigation, not as a first response to friction.\n- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities. If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code.\n- Don't add features, refactor code, or make \"improvements\" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability. Don't add docstrings, comments, or type annotations to code you didn't change. Only add comments where the logic isn't self-evident.\n- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs). Don't use feature flags or backwards-compatibility shims when you can just change the code.\n- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. The right amount of complexity is what the task actually requires — no speculative abstractions, but no half-finished implementations either. Three similar lines of code is better than a premature abstraction.\n- Default to writing no comments. Only add one when the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug, behavior that would surprise a reader. If removing the comment wouldn't confuse a future reader, don't write it.\n- Don't explain WHAT the code does, since well-named identifiers already do that. Don't reference the current task, fix, or callers (\"used by X\", \"added for the Y flow\", \"handles the case from issue #123\"), since those belong in the commit message and rot as the codebase evolves.\n- Don't remove existing comments unless you're removing the code they describe or you know they're wrong. A comment that looks pointless to you may encode a constraint or a lesson from a past bug that isn't visible in the current diff.\n- Before reporting a task complete, verify it actually works: run the test, execute the script, check the output. Minimum complexity means no gold-plating, not skipping the finish line. If you can't verify (no test exists, can't run the code), say so explicitly rather than claiming success.\n- Report outcomes faithfully: if tests fail, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded. Never claim \"all tests pass\" when output shows failures, never suppress or simplify failing checks to manufacture a green result, and never characterize incomplete or broken work as done. Equally, when a check did pass or a task is complete, state it plainly — do not hedge confirmed results with unnecessary disclaimers, downgrade finished work to \"partial,\" or re-verify things you already checked. The goal is an accurate report, not a defensive one.`\n}\n","/**\n * Action safety guidance — ported from La-Machina's ActionsSection.\n *\n * Covers reversibility, blast radius, and when to pause for confirmation.\n * Adapted for headless: \"check with the user\" becomes \"check via the gate\n * callback\" since there's no interactive terminal.\n */\n\nexport function getActionsSection(): string {\n return `# Executing actions with care\n\nCarefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests. But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the caller before proceeding. The cost of pausing to confirm is low, while the cost of an unwanted action (lost work, unintended messages sent, deleted branches) can be very high. For actions like these, consider the context, the action, and caller instructions, and by default transparently communicate the action and ask for confirmation before proceeding. This default can be changed by caller instructions — if explicitly asked to operate more autonomously, then you may proceed without confirmation, but still attend to the risks and consequences when taking actions.\n\nExamples of the kind of risky actions that warrant confirmation:\n- Destructive operations: deleting files/branches, dropping database tables, killing processes, rm -rf, overwriting uncommitted changes\n- Hard-to-reverse operations: force-pushing (can overwrite upstream), git reset --hard, amending published commits, removing or downgrading packages/dependencies, modifying CI/CD pipelines\n- Actions visible to others or that affect shared state: pushing code, creating/closing/commenting on PRs or issues, sending messages (Slack, email, GitHub), posting to external services, modifying shared infrastructure or permissions\n- Uploading content to third-party web tools (diagram renderers, pastebins, gists) publishes it — consider whether it could be sensitive before sending, since it may be cached or indexed even if later deleted.\n\nWhen you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent in-progress work. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions — measure twice, cut once.`\n}\n","/**\n * Tool-specific instructions — ported from La-Machina's UsingYourTools.\n *\n * Tells the model to prefer dedicated tools over Bash, parallelize\n * independent tool calls, and use task tools for progress tracking.\n * Tool names are passed in so the section adapts to whatever tools\n * are actually registered.\n */\n\nexport interface ToolInstructionsOptions {\n readonly registeredToolNames: ReadonlySet<string>\n}\n\nexport function getUsingToolsSection(options: ToolInstructionsOptions): string {\n const has = (name: string) => options.registeredToolNames.has(name)\n const items: string[] = []\n\n // Core tool preference guidance — always included.\n items.push(\n `Do NOT use Bash to run commands when a relevant dedicated tool is provided. Using dedicated tools produces clearer, more reviewable output. This is CRITICAL:`,\n )\n\n if (has('Read')) items.push(` - To read files use Read instead of cat, head, tail, or sed`)\n if (has('Edit')) items.push(` - To edit files use Edit instead of sed or awk`)\n if (has('Write'))\n items.push(` - To create files use Write instead of cat with heredoc or echo redirection`)\n if (has('Glob')) items.push(` - To search for files use Glob instead of find or ls`)\n if (has('Grep')) items.push(` - To search the content of files, use Grep instead of grep or rg`)\n items.push(\n ` - Reserve using Bash exclusively for system commands and terminal operations that require shell execution. If you are unsure and there is a relevant dedicated tool, default to using the dedicated tool and only fallback on Bash if it is absolutely necessary.`,\n )\n\n // Parallel tool calls.\n items.push(\n `You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially.`,\n )\n\n // Agent tool guidance.\n if (has('Agent')) {\n items.push(\n `Use the Agent tool with specialized agents when the task at hand matches the agent's description. Subagents are valuable for parallelizing independent queries or for protecting the main context window from excessive results, but should not be used excessively when not needed. Importantly, avoid duplicating work that subagents are already doing — if you delegate research to a subagent, do not also perform the same searches yourself.`,\n )\n\n if (has('Glob') || has('Grep')) {\n items.push(\n `For simple, directed codebase searches (e.g. for a specific file/class/function) use Glob or Grep directly.`,\n )\n }\n }\n\n // Skill tool guidance.\n if (has('SkillPage')) {\n items.push(\n `Skills are surfaced in the system prompt. Use the SkillPage tool to load specific pages from multi-page skills when you need detailed instructions.`,\n )\n }\n\n return `# Using your tools\\n\\n${items.map((i) => ` - ${i}`).join('\\n')}`\n}\n","/**\n * Tone, style, and output format guidance — ported from La-Machina's\n * ToneAndStyle + OutputEfficiency sections.\n *\n * For the engine (headless), output goes to a programmatic caller —\n * so we optimize for conciseness, accuracy, and structured reporting\n * over conversational flair.\n */\n\nexport function getToneAndStyleSection(): string {\n return `# Tone and style\n\n- Only use emojis if the caller explicitly requests it. Avoid using emojis in all output unless asked.\n- Your responses should be concise and direct. Lead with the answer or action, not the reasoning.\n- When referencing specific functions or pieces of code include the pattern file_path:line_number.\n- When referencing GitHub issues or pull requests, use the owner/repo#123 format.\n- Do not use a colon before tool calls. Your tool calls may not be shown directly in the output, so text like \"Let me read the file:\" followed by a read tool call should just be \"Let me read the file.\" with a period.\n\n# Output efficiency\n\nGo straight to the point. Try the simplest approach first without going in circles. Do not overdo it. Be extra concise.\n\nKeep your text output brief and direct. Lead with the answer or action, not the reasoning. Skip filler words, preamble, and unnecessary transitions. Do not restate the task — just do it. When explaining, include only what is necessary.\n\nFocus text output on:\n- Decisions that need input\n- High-level status updates at natural milestones\n- Errors or blockers that change the plan\n\nIf you can say it in one sentence, don't use three. Prefer short, direct sentences over long explanations.`\n}\n","/**\n * Environment info — dynamic section injected per-run.\n *\n * Tells the model what OS, shell, platform, working directory, model\n * name, current date, and git status. La-Machina's equivalent reads\n * from the real system; the engine does the same but as a library it\n * can't assume a terminal.\n *\n * Git injection: when running in Node.js (canSpawnProcesses), queries\n * git for branch, status, and recent commits. Skips silently on\n * Workers or non-git directories. Ported from La-Machina's context.ts.\n */\n\nimport { canSpawnProcesses } from '../../runtime/detect.js'\n\nexport interface EnvironmentOptions {\n readonly modelId: string\n readonly provider: string\n readonly cwd?: string | undefined\n}\n\nexport async function getEnvironmentSection(options: EnvironmentOptions): Promise<string> {\n let platform = 'unknown'\n let osRelease = ''\n try {\n const os = await import('node:os')\n platform = os.platform()\n osRelease = os.release()\n } catch {\n platform = typeof navigator !== 'undefined' ? 'worker' : 'unknown'\n }\n const shell =\n (typeof process !== 'undefined' ? process.env?.SHELL : undefined) ??\n (platform === 'win32' ? 'cmd.exe' : '/bin/sh')\n const osVersion = `${platform}${osRelease ? ' ' + osRelease : ''}`\n const cwd = options.cwd ?? (typeof process !== 'undefined' && process.cwd ? process.cwd() : '/')\n const date = new Date().toISOString().split('T')[0]\n\n const lines = [\n '# Environment',\n '',\n `- Platform: ${platform}`,\n `- Shell: ${shell}`,\n `- OS Version: ${osVersion}`,\n `- Working directory: ${cwd}`,\n `- Model: ${options.modelId} (provider: ${options.provider})`,\n `- Current date: ${date}`,\n ]\n\n // Git injection — ported from La-Machina's context.ts.\n // Only runs in Node.js (needs child_process). Skips silently on Workers.\n if (canSpawnProcesses()) {\n const git = await getGitContext(cwd)\n if (git) {\n lines.push('')\n lines.push('## Git')\n if (git.branch) lines.push(`- Branch: ${git.branch}`)\n if (git.isRepo) lines.push(`- Is git repo: true`)\n if (git.status) lines.push(`- Status:\\n${git.status}`)\n if (git.recentCommits) lines.push(`- Recent commits:\\n${git.recentCommits}`)\n }\n }\n\n return lines.join('\\n')\n}\n\n// ---------- git helpers ----------\n\ninterface GitContext {\n isRepo: boolean\n branch?: string\n status?: string\n recentCommits?: string\n}\n\nasync function getGitContext(cwd: string): Promise<GitContext | null> {\n try {\n const { execSync } = await import('node:child_process')\n const opts = {\n cwd,\n stdio: ['ignore', 'pipe', 'ignore'] as ['ignore', 'pipe', 'ignore'],\n timeout: 5000,\n }\n\n // Check if inside a git repo\n try {\n execSync('git rev-parse --is-inside-work-tree', opts)\n } catch {\n return null // not a git repo\n }\n\n const branch = tryExec(execSync, 'git branch --show-current', opts)\n const status = tryExec(execSync, 'git status --short', opts, 2000)\n const recentCommits = tryExec(execSync, 'git log --oneline -5', opts, 2000)\n\n const ctx: GitContext = { isRepo: true }\n if (branch) ctx.branch = branch\n if (status) ctx.status = status\n if (recentCommits) ctx.recentCommits = recentCommits\n return ctx\n } catch {\n return null\n }\n}\n\nfunction tryExec(\n execSync: (cmd: string, opts: object) => Buffer,\n cmd: string,\n opts: object,\n maxChars = 1000,\n): string {\n try {\n const out = execSync(cmd, opts).toString('utf-8').trim()\n return out.length > maxChars ? out.slice(0, maxChars) + '\\n...(truncated)' : out\n } catch {\n return ''\n }\n}\n","/**\n * MCP server/tool instructions — dynamic section injected when MCP\n * servers are configured. Lists the available prefixed tools so the\n * model knows what external capabilities it has.\n */\n\nimport type { Tool } from '../../tools/contract.js'\n\nexport interface McpInstructionsOptions {\n readonly mcpTools: ReadonlyArray<Tool>\n}\n\nexport function getMcpSection(options: McpInstructionsOptions): string | null {\n if (options.mcpTools.length === 0) return null\n\n // Group tools by server name (extract from mcp__{server}__{tool}).\n const byServer = new Map<string, string[]>()\n for (const tool of options.mcpTools) {\n const match = tool.name.match(/^mcp__([^_]+)__(.+)$/)\n if (!match) continue\n const server = match[1]!\n const toolName = match[2]!\n if (!byServer.has(server)) byServer.set(server, [])\n byServer.get(server)!.push(toolName)\n }\n\n if (byServer.size === 0) return null\n\n const lines: string[] = ['# MCP Tools', '']\n lines.push(\n 'The following tools come from external MCP servers. Call them by their',\n 'full prefixed name (e.g. `mcp__filesystem__read_file`).',\n '',\n )\n\n for (const [server, tools] of byServer) {\n lines.push(`**${server}** (${tools.length} tool${tools.length === 1 ? '' : 's'}):`)\n for (const t of tools) {\n // Find the original tool to get its description.\n const fullName = `mcp__${server}__${t}`\n const original = options.mcpTools.find((o) => o.name === fullName)\n const desc = original?.description ?? ''\n lines.push(` - \\`${fullName}\\`${desc ? ` — ${desc}` : ''}`)\n }\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n","/**\n * Structured JSON output — schema injection, parsing, validation.\n *\n * When `outputFormat: 'json'` is set on RunOptions:\n * 1. buildSchemaPrompt() injects output instructions into the system prompt\n * 2. tryParseJSON() extracts JSON from the model's response (handles fences, preamble)\n * 3. validateOutput() checks against the Zod schema\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { ZodTypeAny } from 'zod'\n\n// ---------- schema prompt injection ----------\n\n/**\n * Build the output format section to append to the system prompt.\n * Called when outputFormat is 'json'.\n */\nexport function buildSchemaPrompt(schema?: ZodTypeAny): string {\n const lines = [\n '# Output Format',\n '',\n 'CRITICAL: Your FINAL response (after all tool calls are complete) MUST be ONLY valid JSON.',\n 'No markdown fences. No explanation. No text before or after the JSON.',\n 'Do NOT wrap in ```json ... ```. Just raw JSON.',\n ]\n\n if (schema) {\n const jsonSchema = zodToJsonSchema(schema as Parameters<typeof zodToJsonSchema>[0], {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n })\n const { $schema: _, ...clean } = jsonSchema as Record<string, unknown>\n lines.push('', 'The JSON MUST conform to this schema:', JSON.stringify(clean, null, 2))\n } else {\n lines.push('', 'Return a JSON object with the relevant data.')\n }\n\n return lines.join('\\n')\n}\n\n// ---------- JSON extraction ----------\n\nexport interface ParseResult {\n readonly ok: boolean\n readonly value?: unknown\n readonly error?: string\n}\n\n/**\n * Extract JSON from model output. Tries multiple strategies:\n * 1. Raw parse (entire text is JSON)\n * 2. Strip markdown fences (```json ... ```)\n * 3. Find first { ... } or [ ... ] block\n */\nexport function tryParseJSON(text: string): ParseResult {\n const trimmed = text.trim()\n\n // Strategy 1: raw parse\n try {\n return { ok: true, value: JSON.parse(trimmed) }\n } catch {\n /* continue */\n }\n\n // Strategy 2: strip markdown fences\n const fenced = trimmed.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/)\n if (fenced?.[1]) {\n try {\n return { ok: true, value: JSON.parse(fenced[1].trim()) }\n } catch {\n /* continue */\n }\n }\n\n // Strategy 3: find first { ... } or [ ... ] block (greedy)\n const braceStart = trimmed.indexOf('{')\n const bracketStart = trimmed.indexOf('[')\n const start =\n braceStart === -1\n ? bracketStart\n : bracketStart === -1\n ? braceStart\n : Math.min(braceStart, bracketStart)\n\n if (start !== -1) {\n const closer = trimmed[start] === '{' ? '}' : ']'\n const end = trimmed.lastIndexOf(closer)\n if (end > start) {\n try {\n return { ok: true, value: JSON.parse(trimmed.slice(start, end + 1)) }\n } catch {\n /* continue */\n }\n }\n }\n\n return { ok: false, error: 'No valid JSON found in response' }\n}\n\n// ---------- schema validation ----------\n\n/**\n * Validate parsed JSON against a Zod schema.\n * Returns the validated data or an error message.\n */\nexport function validateOutput(\n value: unknown,\n schema: ZodTypeAny,\n): { ok: true; data: unknown } | { ok: false; error: string } {\n const result = schema.safeParse(value)\n if (result.success) {\n return { ok: true, data: result.data }\n }\n // Format Zod errors into a readable string\n const issues = result.error.issues.map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n return { ok: false, error: `Schema validation failed:\\n${issues.join('\\n')}` }\n}\n\n// ---------- retry prompt ----------\n\n/**\n * Build the retry prompt when JSON parsing or validation fails.\n */\nexport function buildRetryPrompt(error: string): string {\n return (\n `Your previous response was not valid JSON matching the required format.\\n` +\n `Error: ${error}\\n\\n` +\n `Respond with ONLY valid JSON. No markdown fences, no explanation, no text outside the JSON.`\n )\n}\n","/**\n * SkillPage tool — loads skill content on demand via a `SkillSource`.\n *\n * The tool is pluggable: the engine constructs it with either\n * `StorageSkillSource` (disk-backed, default) or `InlineSkillSource`\n * (per-run override). The tool itself only knows the interface.\n *\n * Input:\n * { skill: string, page?: string }\n *\n * - When `page` is omitted, the main `SKILL.md` body is returned.\n * - When `page` is set, the supplemental page body is returned.\n *\n * Errors surface as `{ isError: true, content }`:\n * - invalid skill / page name (path traversal shape)\n * - unknown skill (returned null from the source)\n * - unknown page\n * - upstream source throws (network error, SSRF block, etc.)\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from '../tools/contract.js'\nimport type { SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\nconst inputSchema = z.object({\n skill: z.string().min(1),\n page: z.string().min(1).optional(),\n})\n\nexport interface SkillPageToolOptions {\n /** The skill source the tool reads through. */\n readonly source: SkillSource\n}\n\nexport function createSkillPageTool(options: SkillPageToolOptions): Tool<typeof inputSchema> {\n return defineTool({\n name: 'SkillPage',\n description:\n 'Load a skill. Pass `skill` alone to read the main SKILL.md; pass both `skill` and `page` to read a supplemental page. Skill names appear in the system prompt skill index.',\n inputSchema,\n execute: async ({ skill, page }): Promise<ToolResult> => {\n if (!SAFE_NAME.test(skill)) {\n return {\n content: `Invalid skill name \"${skill}\". Skill names must be alphanumeric with hyphens or underscores only.`,\n isError: true,\n }\n }\n if (page !== undefined && !SAFE_NAME.test(page)) {\n return {\n content: `Invalid page name \"${page}\". Page names must be alphanumeric with hyphens or underscores only.`,\n isError: true,\n }\n }\n\n let content: string | null\n try {\n content =\n page === undefined\n ? await options.source.getSkillFile(skill)\n : await options.source.getPage(skill, page)\n } catch (err) {\n return {\n content: `SkillPage: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n\n if (content === null) {\n if (page === undefined) {\n return {\n content: `Skill \"${skill}\" not found. Check the skill index in the system prompt for available skills.`,\n isError: true,\n }\n }\n const available = await options.source.listPages(skill)\n const suggestion =\n available.length > 0\n ? `\\n\\nAvailable pages in \"${skill}\":\\n${available.map((p) => `- ${p}`).join('\\n')}`\n : `\\n\\nThe skill \"${skill}\" has no pages.`\n return {\n content: `Page \"${page}\" not found in skill \"${skill}\".${suggestion}`,\n isError: true,\n }\n }\n\n return {\n content,\n metadata: page !== undefined ? { skill, page } : { skill },\n }\n },\n })\n}\n","/**\n * ApiCall — built-in tool for calling tenant-configured external\n * HTTP APIs without the model ever seeing credentials (Plan 020).\n *\n * The caller describes a set of `ApiServiceV1`s, supplies an `env`\n * map of credential values (or a `resolveAuth` callback for dynamic\n * auth), and this factory returns a `Tool` ready to register. The\n * model picks a service from a closed-over enum + issues a request;\n * the tool resolves auth, enforces per-service allowlists, fetches,\n * and returns the response. Credentials live only in the closure —\n * never in input, output, or any engine-persisted surface.\n *\n * Safety rails (all enforced per-call, first failure wins):\n * 1. `service` must be in the closed enum.\n * 2. Method must pass `allowedMethods` if set.\n * 3. Path must match an `allowedPaths` entry if set.\n * 4. Request body cannot exceed `maxBodyBytes` (default 256 KB).\n * 5. Model-supplied headers cannot override auth headers (the\n * sanitizer strips case-insensitive collisions).\n *\n * Response body is size-capped at `maxResponseBytes` (default 100 KB)\n * with a trailing truncation marker.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from './contract.js'\nimport type {\n ApiAuthResolverV1,\n ApiAuthV1,\n ApiHttpMethodV1,\n ApiRequestEventV1,\n ApiResolverCtxV1,\n ApiResponseEventV1,\n ApiServiceV1,\n} from './apiCall.types.js'\n\nconst ALL_METHODS: readonly ApiHttpMethodV1[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']\nconst DEFAULT_MAX_BODY_BYTES = 256 * 1024\nconst DEFAULT_MAX_RESPONSE_BYTES = 100 * 1024\n\nexport interface CreateApiCallToolOptions {\n readonly services: readonly ApiServiceV1[]\n readonly env?: Readonly<Record<string, string>>\n readonly resolveAuth?: ApiAuthResolverV1\n readonly fetch?: typeof globalThis.fetch\n readonly maxResponseBytes?: number\n readonly onRequest?: (e: ApiRequestEventV1) => void | Promise<void>\n readonly onResponse?: (e: ApiResponseEventV1) => void | Promise<void>\n readonly toolName?: string\n readonly toolDescription?: string\n}\n\nexport function createApiCallTool(opts: CreateApiCallToolOptions): Tool {\n if (opts.services.length === 0) {\n throw new Error('createApiCallTool: services list must be non-empty')\n }\n const services = new Map<string, ApiServiceV1>()\n for (const svc of opts.services) {\n if (services.has(svc.name)) {\n throw new Error(`createApiCallTool: duplicate service name \"${svc.name}\"`)\n }\n services.set(svc.name, svc)\n }\n const serviceNames = [...services.keys()] as [string, ...string[]]\n\n // Validate that every service with a `custom` auth type has a\n // resolver available. Built-in types (bearer/header/basic/none)\n // can be resolved from `env`; `custom` cannot.\n for (const svc of opts.services) {\n if (svc.auth?.type === 'custom' && opts.resolveAuth === undefined) {\n throw new Error(\n `createApiCallTool: service \"${svc.name}\" uses custom auth ` +\n `(id: ${svc.auth.id}) but no resolveAuth was supplied`,\n )\n }\n }\n\n const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis)\n const maxResponseBytes = opts.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES\n\n const inputSchema = z.object({\n service: z.enum(serviceNames),\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),\n path: z.string().regex(/^\\//, 'path must start with /'),\n query: z.record(z.string(), z.string()).optional(),\n body: z.unknown().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n })\n\n const description =\n opts.toolDescription ??\n `Call a configured external API. Services: ${serviceNames.join(', ')}. ` +\n `Auth is injected automatically — do not pass credentials via headers.`\n\n return defineTool({\n name: opts.toolName ?? 'ApiCall',\n description,\n inputSchema,\n execute: async (input) => {\n const svc = services.get(input.service)\n if (!svc) {\n return errResult(`ERR_API_UNKNOWN_SERVICE: ${input.service}`)\n }\n\n const allowedMethods = svc.allowedMethods ?? ALL_METHODS\n if (!allowedMethods.includes(input.method)) {\n return errResult(\n `ERR_API_METHOD_NOT_ALLOWED: ${input.method} not permitted for service ${svc.name}`,\n )\n }\n\n if (!pathAllowed(input.path, svc.allowedPaths)) {\n return errResult(`ERR_API_PATH_NOT_ALLOWED: ${input.path} for service ${svc.name}`)\n }\n\n let bodyText: string | undefined\n if (input.body !== undefined) {\n bodyText = JSON.stringify(input.body)\n const cap = svc.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES\n if (byteLength(bodyText) > cap) {\n return errResult(`ERR_API_BODY_TOO_LARGE: exceeds ${cap} bytes`)\n }\n }\n\n let authHeaders: Readonly<Record<string, string>>\n try {\n authHeaders = await resolveAuth({\n auth: svc.auth ?? { type: 'none' },\n env: opts.env,\n resolver: opts.resolveAuth,\n ctx: { serviceName: svc.name, method: input.method, path: input.path },\n })\n } catch (err) {\n // Truncate the error message aggressively — we don't know\n // what the resolver put in there. 200 chars is enough to\n // diagnose, short enough to reduce accidental-leak surface.\n const raw = err instanceof Error ? err.message : String(err)\n const truncated = raw.length > 200 ? raw.slice(0, 200) + '…' : raw\n return errResult(`ERR_API_RESOLVER_FAILED: ${truncated}`)\n }\n\n const userHeaders = sanitizeHeaders(input.headers ?? {}, authHeaders)\n\n const url = buildUrl(svc.baseUrl, input.path, input.query)\n\n await invokeHook(opts.onRequest, {\n service: svc.name,\n method: input.method,\n path: input.path,\n })\n\n const started = Date.now()\n let res: Response\n try {\n res = await fetchFn(url, {\n method: input.method,\n headers: {\n 'Content-Type': 'application/json',\n ...(svc.defaultHeaders ?? {}),\n ...userHeaders,\n ...authHeaders, // wins last — model cannot override\n },\n ...(bodyText !== undefined ? { body: bodyText } : {}),\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return errResult(`network error: ${msg}`)\n }\n\n const raw = await res.text()\n const content =\n raw.length > maxResponseBytes ? raw.slice(0, maxResponseBytes) + '\\n…[TRUNCATED]' : raw\n\n await invokeHook(opts.onResponse, {\n service: svc.name,\n method: input.method,\n path: input.path,\n status: res.status,\n latencyMs: Date.now() - started,\n bytesIn: raw.length,\n })\n\n return {\n content,\n isError: !res.ok,\n metadata: { status: res.status, service: svc.name },\n }\n },\n })\n}\n\n// ---------- helpers ----------\n\nfunction errResult(msg: string) {\n return { content: msg, isError: true as const }\n}\n\nfunction pathAllowed(path: string, allowed?: ReadonlyArray<string | RegExp>): boolean {\n if (!allowed || allowed.length === 0) return true\n for (const a of allowed) {\n if (typeof a === 'string') {\n if (path.startsWith(a)) return true\n } else if (a.test(path)) {\n return true\n }\n }\n return false\n}\n\nfunction byteLength(s: string): number {\n // TextEncoder is the only reliable way to count bytes across runtimes\n // (Buffer is Node-only, .length on a string counts UTF-16 code units).\n return new TextEncoder().encode(s).byteLength\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: Readonly<Record<string, string>>): string {\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n const url = new URL(base + path)\n for (const [k, v] of Object.entries(query ?? {})) {\n url.searchParams.set(k, v)\n }\n return url.toString()\n}\n\n/**\n * Case-insensitive sanitizer: drops any model-supplied header whose\n * canonical name collides with a resolved auth header. The model\n * cannot spoof `Authorization`, `X-API-Key`, or any custom auth\n * header the caller declared.\n */\nfunction sanitizeHeaders(\n user: Readonly<Record<string, string>>,\n auth: Readonly<Record<string, string>>,\n): Record<string, string> {\n const banned = new Set(Object.keys(auth).map((k) => k.toLowerCase()))\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(user)) {\n if (banned.has(k.toLowerCase())) continue\n out[k] = v\n }\n return out\n}\n\nasync function resolveAuth(args: {\n auth: ApiAuthV1\n env: Readonly<Record<string, string>> | undefined\n resolver: ApiAuthResolverV1 | undefined\n ctx: ApiResolverCtxV1\n}): Promise<Readonly<Record<string, string>>> {\n const { auth, env, resolver, ctx } = args\n\n // Contract (Plan 020):\n // - Built-in auth types (bearer/header/basic/none) are always\n // resolved from `env` by the engine. Simple, predictable.\n // - `custom` is the extension point: the resolver handles it\n // and returns whatever headers are needed. If a user wants to\n // override bearer behavior (e.g., OAuth refresh), they declare\n // the auth as `custom` so the resolver owns it.\n //\n // This split keeps simple cases one-liners while leaving the\n // escape hatch fully general.\n switch (auth.type) {\n case 'none':\n return {}\n case 'bearer': {\n const token = envLookup(env, auth.tokenRef)\n return { Authorization: `Bearer ${token}` }\n }\n case 'header': {\n const value = envLookup(env, auth.valueRef)\n return { [auth.name]: value }\n }\n case 'basic': {\n const u = envLookup(env, auth.userRef)\n const p = envLookup(env, auth.passRef)\n return { Authorization: `Basic ${base64(`${u}:${p}`)}` }\n }\n case 'custom':\n if (resolver === undefined) {\n // Already validated at construction time; defensive fallback.\n throw new Error(`custom auth id \"${auth.id}\" requires resolveAuth`)\n }\n return resolver(auth, ctx)\n }\n}\n\nfunction envLookup(env: Readonly<Record<string, string>> | undefined, ref: string): string {\n if (env === undefined || env[ref] === undefined) {\n throw new Error(`ERR_API_ENV_MISSING: ${ref}`)\n }\n return env[ref]\n}\n\nfunction base64(input: string): string {\n // Prefer globalThis.btoa (browser/Workers); fall back to Buffer\n // (Node). Both exist in the runtimes we support.\n if (typeof globalThis.btoa === 'function') {\n return globalThis.btoa(input)\n }\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return Buffer.from(input, 'utf8').toString('base64')\n}\n\nasync function invokeHook<E>(\n hook: ((e: E) => void | Promise<void>) | undefined,\n event: E,\n): Promise<void> {\n if (hook === undefined) return\n try {\n await hook(event)\n } catch {\n // Hook failures are non-fatal — telemetry must never break a run.\n }\n}\n","/**\n * SearchKnowledge — built-in tool (Plan 023 §4).\n *\n * Loads the indexes for the run's selected knowledge folders and\n * scores their sections against the model's query by token\n * overlap. Also scores any per-run external link descriptions.\n * Returns the top-K matches as short snippets the model can then\n * follow up on with `ReadKnowledge`.\n *\n * Per-call behaviour:\n * 1. Resolve the effective folder list + external links\n * (per-run override on `RunOptions.knowledge` is the only\n * source — engine-level config carries thresholds, not paths).\n * 2. For each unique base in the folder list: load\n * `{base}/_index.json` from the knowledge adapter (cached on\n * a Map held by the tool factory's closure for this run).\n * 3. Filter sections by sub-path.\n * 4. Score sections + external descriptions, return top-K.\n *\n * Per-agent isolation: each agent gets its own factory instance\n * with its own cache + folder list. Subagents can't search past\n * their parent's scope (engine wires this up).\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\nimport { buildKnowledgeIndex } from '../knowledge/indexer.js'\nimport { parseFolderRef, relPathInScope, type ScopedFolder } from '../knowledge/scope.js'\nimport { scoreOverlap, tokenize } from '../knowledge/tokenize.js'\nimport type {\n KnowledgeExternalLinkV1,\n KnowledgeIndexV1,\n SectionEntryV1,\n} from '../knowledge/types.js'\n\nexport interface CreateSearchKnowledgeToolOptions {\n /** Knowledge-side storage adapter (rooted at the tenant's `knowledge/` folder). */\n readonly adapter: StorageAdapter\n /** Folder paths the model is allowed to search this run. */\n readonly folders: readonly string[]\n /** External links the model can search by description. */\n readonly external: readonly KnowledgeExternalLinkV1[]\n /** Default + max top-K; defaults to 5 when omitted. */\n readonly maxSearchResults?: number\n}\n\nconst DEFAULT_MAX_RESULTS = 5\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n maxResults: z.number().int().positive().optional(),\n})\n\nexport function createSearchKnowledgeTool(opts: CreateSearchKnowledgeToolOptions): Tool {\n const scoped = opts.folders.map(parseFolderRef)\n const indexCache = new Map<string, KnowledgeIndexV1>()\n const cap = opts.maxSearchResults ?? DEFAULT_MAX_RESULTS\n\n // Closed-over external link list — not read by the model\n const externals = opts.external\n\n return defineTool({\n name: 'SearchKnowledge',\n description:\n \"Search the agent's knowledge base. Returns up to K ranked snippets \" +\n 'matching the query (across all configured knowledge folders + any ' +\n 'attached external file links). Each result carries a `ref` you can ' +\n 'pass back to the `ReadKnowledge` tool to load the full content of ' +\n 'that section or file.',\n inputSchema,\n execute: async ({ query, maxResults }) => {\n const limit = Math.min(maxResults ?? cap, cap)\n const queryTokens = tokenize(query)\n if (queryTokens.length === 0) {\n return { content: 'no searchable tokens in query', isError: false }\n }\n\n // ── Index hits ──\n const sectionHits: Array<{ section: SectionEntryV1; base: string; score: number }> = []\n const seenBases = new Set<string>()\n for (const folder of scoped) {\n if (!seenBases.has(folder.base)) {\n seenBases.add(folder.base)\n }\n }\n for (const baseName of seenBases) {\n const idx = await loadIndex(opts.adapter, baseName, indexCache)\n if (idx === null) continue\n for (const section of idx.sections) {\n // Section qualifies if it falls under at least one of the\n // requested folders that share this base.\n const eligible = scoped.some(\n (f) => f.base === baseName && relPathInScope(f, section.relPath),\n )\n if (!eligible) continue\n const score = scoreOverlap(section.words, queryTokens)\n if (score > 0) sectionHits.push({ section, base: baseName, score })\n }\n }\n\n // ── External link hits ──\n const externalHits: Array<{ link: KnowledgeExternalLinkV1; score: number }> = []\n for (const link of externals) {\n const score = scoreOverlap(tokenize(link.description), queryTokens)\n if (score > 0) externalHits.push({ link, score })\n }\n\n const all = [\n ...sectionHits.map((h) => ({\n kind: 'knowledge' as const,\n score: h.score,\n render: () =>\n `[knowledge] ${h.base}/${h.section.relPath} §\"${h.section.heading || '(lead-in)'}\"\\n` +\n ` ${truncatePreview(h.section.preview)}\\n` +\n ` ref: ${h.base}/${h.section.slug}`,\n })),\n ...externalHits.map((h) => ({\n kind: 'external' as const,\n score: h.score,\n render: () =>\n `[external] ${h.link.name} (${h.link.format})\\n` +\n ` ${h.link.description}\\n` +\n ` ref: ext:${h.link.name}`,\n })),\n ]\n\n if (all.length === 0) {\n return { content: `no knowledge matches for \"${query}\"`, isError: false }\n }\n\n all.sort((a, b) => b.score - a.score)\n const top = all.slice(0, limit)\n const body = top.map((h, i) => `${i + 1}. ${h.render()}`).join('\\n\\n')\n return {\n content:\n `Found ${top.length} knowledge match${top.length === 1 ? '' : 'es'} ` +\n `(of ${all.length} ranked):\\n\\n${body}`,\n isError: false,\n metadata: { hits: all.length, returned: top.length },\n }\n },\n })\n}\n\nfunction truncatePreview(s: string): string {\n if (s.length <= 200) return s\n return s.slice(0, 200) + '…'\n}\n\n/**\n * Resolve a base's index. Order:\n * 1. Per-run cache hit\n * 2. `{base}/_index.json` on the adapter (fast path — pre-built)\n * 3. **Fallback**: build the index in memory by walking the base\n * and tokenising every file. Slower on first call but caches\n * for the rest of the run, so repeat queries cost nothing.\n *\n * Returns null only when the base genuinely has no readable files\n * (folder doesn't exist / empty) — i.e., even the build path would\n * find nothing. A corrupted `_index.json` falls through to the\n * build path; agents see real results instead of a misleading\n * \"no matches\".\n */\nasync function loadIndex(\n adapter: StorageAdapter,\n base: string,\n cache: Map<string, KnowledgeIndexV1>,\n): Promise<KnowledgeIndexV1 | null> {\n const cached = cache.get(base)\n if (cached !== undefined) return cached\n\n // Fast path — pre-built index file\n let raw: string | null = null\n try {\n raw = await adapter.readFile(`${base}/_index.json`)\n } catch {\n raw = null\n }\n if (raw !== null) {\n try {\n const parsed = JSON.parse(raw) as KnowledgeIndexV1\n cache.set(base, parsed)\n return parsed\n } catch {\n // Corrupted index — fall through to build path rather than\n // silently returning \"no matches\".\n }\n }\n\n // Fallback — build in-memory. Read-only: never writes _index.json.\n try {\n const built = await buildKnowledgeIndex({ adapter, base })\n cache.set(base, built)\n return built\n } catch {\n return null\n }\n}\n\n/** Re-export scope helper for direct use in folder validation tests. */\nexport type { ScopedFolder }\n","/**\n * Knowledge index builder (Plan 023 §3).\n *\n * Walks a single base folder under `{workspace}/knowledge/`, splits\n * every markdown file at heading boundaries, tokenizes each section,\n * and writes `{base}/_index.json`.\n *\n * Pure with respect to the storage adapter — works identically on\n * local filesystem, R2, or R2 binding. Designed to be called by\n * SaaS authors at upload time (when files change), not by the engine\n * at runtime.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { tokenize } from './tokenize.js'\nimport type { FileMetaV1, KnowledgeFormatV1, KnowledgeIndexV1, SectionEntryV1 } from './types.js'\n\nconst HEADING_RE = /^(#{1,6})[ \\t]+(.+?)\\s*$/\nconst WIKI_LINK_RE = /\\[\\[([^\\]|#]+)(?:[#|][^\\]]*)?\\]\\]/g\n\nconst FORMAT_BY_EXT: Record<string, KnowledgeFormatV1> = {\n md: 'md',\n markdown: 'md',\n txt: 'txt',\n json: 'json',\n csv: 'csv',\n html: 'html',\n htm: 'html',\n pdf: 'pdf',\n docx: 'docx',\n}\n\nconst PREVIEW_CHARS = 200\n\nexport interface BuildKnowledgeIndexOptions {\n /** Knowledge-side storage adapter (rooted at `workspaces/{wid}/knowledge/`). */\n readonly adapter: StorageAdapter\n /** Base folder name under the knowledge root, e.g. `'sales-playbook'`. */\n readonly base: string\n /** Override the timestamp written into the index (for deterministic tests). */\n readonly nowIso?: string\n}\n\nexport async function buildKnowledgeIndex(\n options: BuildKnowledgeIndexOptions,\n): Promise<KnowledgeIndexV1> {\n const { adapter, base } = options\n const safeBase = base.replace(/^\\/+|\\/+$/g, '')\n if (safeBase.length === 0 || safeBase.includes('..')) {\n throw new Error(`buildKnowledgeIndex: invalid base \"${base}\"`)\n }\n\n const files = await listFilesRecursive(adapter, safeBase)\n // relPath is relative to the base root\n const sections: SectionEntryV1[] = []\n const filesMeta: Record<string, FileMetaV1> = {}\n\n for (const fileRel of files) {\n if (fileRel === '_index.json') continue // skip our own output if present\n const fullPath = `${safeBase}/${fileRel}`\n const ext = (fileRel.split('.').pop() ?? '').toLowerCase()\n const format = FORMAT_BY_EXT[ext]\n if (format === undefined) continue // unknown format — skip silently\n\n const raw = await adapter.readFile(fullPath)\n if (raw === null) continue\n\n const sizeBytes = byteLength(raw)\n const meta: FileMetaV1 = { format, size: sizeBytes }\n\n if (format === 'md' || format === 'txt') {\n const fileSections = splitSections(raw, fileRel)\n sections.push(...fileSections)\n const wikiLinks = extractWikiLinks(raw)\n if (wikiLinks.length > 0) (meta as { wikiLinks?: readonly string[] }).wikiLinks = wikiLinks\n }\n\n filesMeta[fileRel] = meta\n }\n\n return {\n schema: 'v1' as const,\n base: safeBase,\n builtAt: options.nowIso ?? new Date().toISOString(),\n fileCount: Object.keys(filesMeta).length,\n sections,\n files: filesMeta,\n }\n}\n\n/**\n * Build the index AND write `_index.json` into the base folder.\n * Returns the index that was written.\n */\nexport async function writeKnowledgeIndex(\n options: BuildKnowledgeIndexOptions,\n): Promise<KnowledgeIndexV1> {\n const index = await buildKnowledgeIndex(options)\n await options.adapter.writeFile(`${index.base}/_index.json`, JSON.stringify(index, null, 2))\n return index\n}\n\n// ────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────\n\nasync function listFilesRecursive(adapter: StorageAdapter, dir: string): Promise<string[]> {\n // Returns paths relative to `dir`. Walks subfolders.\n const out: string[] = []\n const stack: string[] = ['']\n while (stack.length > 0) {\n const sub = stack.pop()!\n const fullDir = sub === '' ? dir : `${dir}/${sub}`\n let entries: string[] = []\n try {\n entries = await adapter.listDir(fullDir)\n } catch {\n continue\n }\n for (const name of entries) {\n const childRel = sub === '' ? name : `${sub}/${name}`\n const childFull = `${dir}/${childRel}`\n const isDir = await adapter.isDirectory(childFull).catch(() => false)\n if (isDir) {\n stack.push(childRel)\n } else {\n out.push(childRel)\n }\n }\n }\n return out.sort()\n}\n\nfunction splitSections(content: string, relPath: string): SectionEntryV1[] {\n const lines = content.split(/\\r?\\n/)\n const out: SectionEntryV1[] = []\n\n // First, find every heading line + its position\n type HeadingMark = { line: number; depth: number; heading: string }\n const heads: HeadingMark[] = []\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const m = HEADING_RE.exec(line)\n if (m) heads.push({ line: i + 1, depth: m[1]!.length, heading: m[2]!.trim() })\n }\n\n // Lead-in section before first heading, if any non-empty content there\n const leadInEndLine = heads.length > 0 ? heads[0]!.line - 1 : lines.length\n const leadInBody = lines.slice(0, leadInEndLine).join('\\n').trim()\n if (leadInBody.length > 0) {\n out.push({\n relPath,\n heading: '',\n slug: `${relPath}#`,\n depth: 0,\n words: tokenize(leadInBody),\n preview: makePreview(leadInBody),\n startLine: 1,\n endLine: leadInEndLine,\n })\n }\n\n // One entry per heading; section spans heading line through line\n // BEFORE the next heading (or end of file).\n for (let i = 0; i < heads.length; i++) {\n const h = heads[i]!\n const startLine = h.line\n const endLine = i + 1 < heads.length ? heads[i + 1]!.line - 1 : lines.length\n const body = lines.slice(startLine - 1, endLine).join('\\n')\n out.push({\n relPath,\n heading: h.heading,\n slug: `${relPath}#${slugify(h.heading)}`,\n depth: h.depth,\n words: tokenize(body),\n preview: makePreview(body),\n startLine,\n endLine,\n })\n }\n\n return out\n}\n\nfunction makePreview(body: string): string {\n // Strip the heading line if present (first line) for a cleaner preview\n const trimmed = body.replace(/^#{1,6}\\s+.+$\\r?\\n?/m, '').trim()\n if (trimmed.length <= PREVIEW_CHARS) return trimmed\n return trimmed.slice(0, PREVIEW_CHARS) + '…'\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction extractWikiLinks(text: string): string[] {\n const seen = new Set<string>()\n let m: RegExpExecArray | null\n WIKI_LINK_RE.lastIndex = 0\n while ((m = WIKI_LINK_RE.exec(text)) !== null) {\n const target = m[1]!.trim()\n if (target.length > 0) seen.add(target)\n }\n return [...seen].sort()\n}\n\nfunction byteLength(s: string): number {\n return new TextEncoder().encode(s).byteLength\n}\n","/**\n * Shared tokenizer for the knowledge subsystem (Plan 023).\n *\n * Both the indexer (`indexer.ts`) and SearchKnowledge use this\n * function so query tokens align with section tokens. ANY change\n * here must keep both ends consistent.\n */\n\nconst STOP_WORDS = new Set([\n 'the',\n 'and',\n 'of',\n 'to',\n 'a',\n 'in',\n 'is',\n 'it',\n 'you',\n 'that',\n 'was',\n 'for',\n 'on',\n 'are',\n 'with',\n 'as',\n 'this',\n 'by',\n 'from',\n 'or',\n 'but',\n 'not',\n 'all',\n 'an',\n 'has',\n 'have',\n 'had',\n 'will',\n 'can',\n 'do',\n 'did',\n 'be',\n 'been',\n 'being',\n 'your',\n 'our',\n 'their',\n 'his',\n 'her',\n 'my',\n 'we',\n 'they',\n 'them',\n 'than',\n 'so',\n 'if',\n 'at',\n 'no',\n 'yes',\n 'me',\n 'us',\n 'i',\n 'he',\n 'she',\n])\n\n/**\n * Lowercase, split on non-word characters, drop tokens shorter\n * than 2 chars, drop stop-words, dedupe (preserves first occurrence).\n *\n * Returns a deterministic, sorted list so two equivalent inputs\n * always yield the same array (helpful for snapshot tests).\n */\nexport function tokenize(text: string): string[] {\n if (typeof text !== 'string' || text.length === 0) return []\n const seen = new Set<string>()\n for (const raw of text.toLowerCase().split(/[\\W_]+/)) {\n if (raw.length < 2) continue\n if (STOP_WORDS.has(raw)) continue\n seen.add(raw)\n }\n return [...seen].sort()\n}\n\n/**\n * Score a section's word set against a query's token set.\n * Returns the count of query tokens that appear in the section.\n * Higher = better match. Used by SearchKnowledge.\n */\nexport function scoreOverlap(\n sectionWords: ReadonlyArray<string> | ReadonlySet<string>,\n queryTokens: ReadonlyArray<string>,\n): number {\n const set = sectionWords instanceof Set ? sectionWords : new Set(sectionWords)\n let n = 0\n for (const t of queryTokens) if (set.has(t)) n++\n return n\n}\n","/**\n * Path-safety + scope resolution helpers shared by SearchKnowledge\n * and ReadKnowledge.\n *\n * Centralised so all path validation runs through one place;\n * unit-tested separately so changes here can't silently weaken\n * the tenant boundary.\n */\n\nconst SAFE_PATH_RE = /^[a-zA-Z0-9_\\-./]+$/\n\nexport interface ScopedFolder {\n /** The folder path the user requested, normalized (no leading/trailing `/`). */\n readonly path: string\n /** The owning base — first path segment. */\n readonly base: string\n /** Sub-path within the base, or '' if the request IS the base root. */\n readonly subPath: string\n}\n\n/**\n * Validate a per-run folder request. Rejects:\n * - Empty / `..` / leading `/` / unsafe chars (whitespace, anything\n * outside `[a-zA-Z0-9_\\-./]`).\n *\n * Returns the normalized folder + its decomposed base + subPath.\n */\nexport function parseFolderRef(raw: string): ScopedFolder {\n if (typeof raw !== 'string' || raw.length === 0) {\n throw new Error(`invalid knowledge folder ref: empty`)\n }\n if (raw.startsWith('/')) {\n throw new Error(`invalid knowledge folder ref: absolute paths not allowed (\"${raw}\")`)\n }\n const trimmed = raw.replace(/\\/+$/g, '')\n if (trimmed.length === 0) {\n throw new Error(`invalid knowledge folder ref: \"${raw}\"`)\n }\n if (!SAFE_PATH_RE.test(trimmed)) {\n throw new Error(`invalid knowledge folder ref: unsafe characters in \"${raw}\"`)\n }\n if (trimmed.split('/').some((seg) => seg === '..' || seg === '.' || seg === '')) {\n throw new Error(`invalid knowledge folder ref: traversal in \"${raw}\"`)\n }\n const segs = trimmed.split('/')\n const base = segs[0]!\n const subPath = segs.slice(1).join('/')\n return { path: trimmed, base, subPath }\n}\n\n/**\n * Validate that a `relPath` from the index is allowed under the\n * requested folder. `relPath` is relative to the base root.\n */\nexport function relPathInScope(folder: ScopedFolder, relPath: string): boolean {\n if (folder.subPath === '') return true\n // relPath must start with subPath + '/' (or equal subPath for files\n // that ARE the sub-path itself, though sections always have a file\n // suffix so this is essentially the prefix-with-separator case).\n return relPath === folder.subPath || relPath.startsWith(`${folder.subPath}/`)\n}\n\n/**\n * Validate a ref the model passed to ReadKnowledge.\n *\n * - `ext:{name}` → external link (validated separately)\n * - `{base/path/to/file.ext}#{slug}` → section ref\n * - `{base/path/to/file.ext}` → whole-file ref\n *\n * Same character class + traversal rejection as parseFolderRef.\n */\nexport interface ParsedKnowledgeRef {\n readonly kind: 'ext' | 'section' | 'file'\n /** External: name; section/file: full file path under knowledge root. */\n readonly target: string\n /** Section anchor (slug after `#`) — present only for `kind === 'section'`. */\n readonly section?: string\n}\n\nexport function parseKnowledgeRef(raw: string): ParsedKnowledgeRef {\n if (typeof raw !== 'string' || raw.length === 0) {\n throw new Error('invalid knowledge ref: empty')\n }\n if (raw.startsWith('ext:')) {\n const name = raw.slice('ext:'.length)\n if (!/^[a-zA-Z0-9_-]+$/.test(name) || name.length === 0) {\n throw new Error(`invalid knowledge ref: external name \"${name}\" has unsafe characters`)\n }\n return { kind: 'ext', target: name }\n }\n if (raw.startsWith('/')) {\n throw new Error(`invalid knowledge ref: absolute paths not allowed (\"${raw}\")`)\n }\n // Split into [filePath]#[section]\n const hashAt = raw.indexOf('#')\n const filePath = hashAt === -1 ? raw : raw.slice(0, hashAt)\n const section = hashAt === -1 ? undefined : raw.slice(hashAt + 1)\n if (!SAFE_PATH_RE.test(filePath)) {\n throw new Error(`invalid knowledge ref: unsafe characters in \"${filePath}\"`)\n }\n if (filePath.split('/').some((seg) => seg === '..' || seg === '.' || seg === '')) {\n throw new Error(`invalid knowledge ref: traversal in \"${filePath}\"`)\n }\n if (section !== undefined) {\n if (section.length > 0 && !/^[a-zA-Z0-9_-]+$/.test(section)) {\n throw new Error(`invalid knowledge ref: unsafe characters in section \"${section}\"`)\n }\n return { kind: 'section', target: filePath, section }\n }\n return { kind: 'file', target: filePath }\n}\n\n/**\n * Check that a parsed file ref is within at least one of the\n * scoped folders. Used by ReadKnowledge.\n */\nexport function refInScope(folders: ReadonlyArray<ScopedFolder>, filePath: string): boolean {\n return folders.some((f) => {\n if (filePath === f.base || filePath.startsWith(`${f.base}/`)) {\n const relInBase = filePath === f.base ? '' : filePath.slice(f.base.length + 1)\n return relPathInScope(f, relInBase)\n }\n return false\n })\n}\n","/**\n * ReadKnowledge — built-in tool (Plan 023 §5).\n *\n * Resolves a `ref` to its content. Three cases:\n * - `ext:{name}` → fetch the registered external link's URL,\n * run format extraction, return text\n * - `{base}/{path}.ext#{slug}` → load the owning base's index,\n * find the section, slice the lines from the file\n * - `{base}/{path}.ext` → whole-file read + format extraction\n *\n * All paths run through `parseKnowledgeRef` + `refInScope` for\n * safety. Per-agent isolation: each agent's tool instance is bound\n * to its own folder list + index cache.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\nimport { getExtractor } from '../knowledge/extractors.js'\nimport { buildKnowledgeIndex } from '../knowledge/indexer.js'\nimport {\n parseFolderRef,\n parseKnowledgeRef,\n refInScope,\n type ScopedFolder,\n} from '../knowledge/scope.js'\nimport type {\n KnowledgeExternalLinkV1,\n KnowledgeFormatV1,\n KnowledgeIndexV1,\n} from '../knowledge/types.js'\n\nexport interface CreateReadKnowledgeToolOptions {\n /** Knowledge-side adapter rooted at `workspaces/{wid}/knowledge/`. */\n readonly adapter: StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxReadBytes?: number\n /** Override fetch (Workers / tests). Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch\n}\n\nconst DEFAULT_MAX_READ_BYTES = 10_000\n\nconst inputSchema = z.object({\n ref: z.string().min(1),\n})\n\nexport function createReadKnowledgeTool(opts: CreateReadKnowledgeToolOptions): Tool {\n const scoped = opts.folders.map(parseFolderRef)\n const indexCache = new Map<string, KnowledgeIndexV1>()\n const fileCache = new Map<string, string>()\n const cap = opts.maxReadBytes ?? DEFAULT_MAX_READ_BYTES\n const externalsByName = new Map(opts.external.map((e) => [e.name, e]))\n const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis)\n\n return defineTool({\n name: 'ReadKnowledge',\n description:\n 'Load the full content of a knowledge ref returned by SearchKnowledge. ' +\n 'Use the `ref` value verbatim from the search results — section refs ' +\n 'return one section, file refs return the whole file (with format-specific ' +\n 'extraction for non-markdown formats), and `ext:{name}` refs fetch a ' +\n 'pre-registered external file.',\n inputSchema,\n execute: async ({ ref }) => {\n let parsed\n try {\n parsed = parseKnowledgeRef(ref)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_REF_INVALID: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n\n if (parsed.kind === 'ext') {\n return readExternal(parsed.target, externalsByName, fetchFn, cap)\n }\n\n // file or section ref — must be in scope\n if (!refInScope(scoped, parsed.target)) {\n return {\n content: `ERR_KNOWLEDGE_FOLDER_NOT_ALLOWED: ref \"${parsed.target}\" is outside the run's allowed folders`,\n isError: true,\n }\n }\n\n // Identify the owning base\n const base = parsed.target.split('/')[0]!\n const relPath = parsed.target.slice(base.length + 1)\n\n // For section refs: load the index, look up the section.\n // `loadIndex` falls back to an in-memory build when no\n // `_index.json` exists, so a null here means the base is\n // genuinely empty / unreadable, not just unindexed.\n if (parsed.kind === 'section') {\n const idx = await loadIndex(opts.adapter, base, indexCache)\n if (idx === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: base \"${base}\" has no readable files`,\n isError: true,\n }\n }\n const sectionSlug = parsed.section ?? ''\n const section = idx.sections.find(\n (s) => s.relPath === relPath && extractAnchor(s.slug) === sectionSlug,\n )\n if (section === undefined) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: section ${parsed.target}#${sectionSlug} not in index for \"${base}\"`,\n isError: true,\n }\n }\n const fullContent = await readFile(opts.adapter, parsed.target, fileCache)\n if (fullContent === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: file ${parsed.target} not found in storage`,\n isError: true,\n }\n }\n const sliced = sliceLines(fullContent, section.startLine, section.endLine)\n return wrapResult(`[knowledge] ${parsed.target}#${sectionSlug}`, sliced, cap)\n }\n\n // file ref → whole file + format extraction\n const fmt = inferFormat(parsed.target)\n if (fmt === null) {\n return {\n content: `ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: cannot infer format for \"${parsed.target}\"`,\n isError: true,\n }\n }\n const raw = await readFile(opts.adapter, parsed.target, fileCache)\n if (raw === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: file ${parsed.target} not found in storage`,\n isError: true,\n }\n }\n let extracted: string\n try {\n extracted = await getExtractor(fmt).extract(raw)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_EXTRACTOR_FAILED: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n return wrapResult(`[knowledge] ${parsed.target} (${fmt})`, extracted, cap)\n },\n })\n}\n\n// ────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────\n\nasync function readExternal(\n name: string,\n registry: Map<string, KnowledgeExternalLinkV1>,\n fetchFn: typeof globalThis.fetch,\n cap: number,\n) {\n const link = registry.get(name)\n if (link === undefined) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: no external link named \"${name}\"`,\n isError: true as const,\n }\n }\n let res\n try {\n res = await fetchFn(link.url, {\n headers: (link.headers ?? {}) as Record<string, string>,\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return {\n content: `ERR_KNOWLEDGE_NETWORK: ${msg.slice(0, 200)}`,\n isError: true as const,\n }\n }\n if (!res.ok) {\n return {\n content: `ERR_KNOWLEDGE_NETWORK: HTTP ${res.status} fetching ext:${name}`,\n isError: true as const,\n }\n }\n const raw = await res.text()\n let extracted: string\n try {\n extracted = await getExtractor(link.format).extract(raw)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_EXTRACTOR_FAILED: ${err instanceof Error ? err.message : String(err)}`,\n isError: true as const,\n }\n }\n return wrapResult(`[external] ${name} (${link.format})`, extracted, cap)\n}\n\nfunction wrapResult(header: string, body: string, cap: number) {\n // Truncate at cap to keep tool_results bounded; offload (Plan 021)\n // takes over for the actual context-relief tier above this.\n let payload = body\n if (body.length > cap) {\n payload = body.slice(0, cap) + `\\n…[+${body.length - cap} more chars truncated]`\n }\n return {\n content: `${header}\\n\\n${payload}`,\n isError: false as const,\n metadata: { bytes: body.length },\n }\n}\n\n/**\n * Same fallback policy as SearchKnowledge.loadIndex — see that\n * helper's docstring. Pre-built `_index.json` is the fast path;\n * absent or corrupted index falls through to an in-memory build.\n * Section refs against unindexed bases now succeed instead of\n * returning ERR_KNOWLEDGE_INDEX_MISSING.\n */\nasync function loadIndex(\n adapter: StorageAdapter,\n base: string,\n cache: Map<string, KnowledgeIndexV1>,\n): Promise<KnowledgeIndexV1 | null> {\n const cached = cache.get(base)\n if (cached !== undefined) return cached\n\n let raw: string | null = null\n try {\n raw = await adapter.readFile(`${base}/_index.json`)\n } catch {\n raw = null\n }\n if (raw !== null) {\n try {\n const idx = JSON.parse(raw) as KnowledgeIndexV1\n cache.set(base, idx)\n return idx\n } catch {\n // Corrupted — fall through to build\n }\n }\n\n try {\n const built = await buildKnowledgeIndex({ adapter, base })\n cache.set(base, built)\n return built\n } catch {\n return null\n }\n}\n\nasync function readFile(\n adapter: StorageAdapter,\n path: string,\n cache: Map<string, string>,\n): Promise<string | null> {\n const cached = cache.get(path)\n if (cached !== undefined) return cached\n const content = await adapter.readFile(path).catch(() => null)\n if (content === null) return null\n cache.set(path, content)\n return content\n}\n\nfunction sliceLines(content: string, start: number, end: number): string {\n const lines = content.split(/\\r?\\n/)\n return lines.slice(start - 1, end).join('\\n')\n}\n\nfunction extractAnchor(slug: string): string {\n const i = slug.indexOf('#')\n return i === -1 ? '' : slug.slice(i + 1)\n}\n\nfunction inferFormat(filePath: string): KnowledgeFormatV1 | null {\n const ext = (filePath.split('.').pop() ?? '').toLowerCase()\n switch (ext) {\n case 'md':\n case 'markdown':\n return 'md'\n case 'txt':\n return 'txt'\n case 'json':\n return 'json'\n case 'csv':\n return 'csv'\n case 'html':\n case 'htm':\n return 'html'\n case 'pdf':\n return 'pdf'\n case 'docx':\n return 'docx'\n }\n return null\n}\n\nexport type { ScopedFolder }\n","/**\n * Format extractors for the knowledge subsystem (Plan 023 §5).\n *\n * Each extractor turns raw bytes (or a UTF-8 string) into the text\n * the model will see. Native formats are pure functions; pdf and\n * docx lazily import optional deps and are flagged `requiresNode`\n * (Plan 019's capability stub fires on Workers).\n */\n\nimport type { KnowledgeFormatV1 } from './types.js'\n\nexport interface KnowledgeExtractorV1 {\n readonly format: KnowledgeFormatV1\n /** True if this extractor uses `node:`-only deps (PDF, DOCX). */\n readonly requiresNode: boolean\n extract(raw: string): Promise<string>\n}\n\nconst CSV_MAX_ROWS = 100\nconst HTML_TAG_RE = /<[^>]+>/g\nconst HTML_ENTITIES: Record<string, string> = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n '&nbsp;': ' ',\n}\n\nfunction decodeHtmlEntities(s: string): string {\n return s.replace(/&(amp|lt|gt|quot|#39|nbsp);/g, (m) => HTML_ENTITIES[m] ?? m)\n}\n\nconst text: KnowledgeExtractorV1 = {\n format: 'txt',\n requiresNode: false,\n extract: async (raw) => raw,\n}\n\nconst md: KnowledgeExtractorV1 = {\n format: 'md',\n requiresNode: false,\n extract: async (raw) => raw,\n}\n\nconst json: KnowledgeExtractorV1 = {\n format: 'json',\n requiresNode: false,\n extract: async (raw) => {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2)\n } catch {\n return raw // fall back to raw text on parse failure\n }\n },\n}\n\nconst csv: KnowledgeExtractorV1 = {\n format: 'csv',\n requiresNode: false,\n extract: async (raw) => {\n const lines = raw.split(/\\r?\\n/).filter((l) => l.length > 0)\n if (lines.length === 0) return ''\n if (lines.length <= CSV_MAX_ROWS + 1) return lines.join('\\n')\n const head = lines.slice(0, CSV_MAX_ROWS + 1) // header + first N rows\n const remaining = lines.length - head.length\n return `${head.join('\\n')}\\n…[${remaining.toLocaleString()} more row${remaining === 1 ? '' : 's'} truncated]`\n },\n}\n\nconst html: KnowledgeExtractorV1 = {\n format: 'html',\n requiresNode: false,\n extract: async (raw) => {\n // Strip <script> and <style> bodies, then strip tags.\n const stripped = raw\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(HTML_TAG_RE, ' ')\n return decodeHtmlEntities(stripped).replace(/\\s+/g, ' ').trim()\n },\n}\n\nconst pdf: KnowledgeExtractorV1 = {\n format: 'pdf',\n requiresNode: true,\n extract: async (raw) => {\n let pdfParse: unknown\n try {\n // pdf-parse exposes either a CJS-style default export or a\n // namespace whose default IS the parser; access via `any` to\n // tolerate either shape (the package's d.ts shape varies by\n // version).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import('pdf-parse')\n pdfParse = (mod.default ?? mod) as unknown\n } catch {\n throw new Error(\n 'ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: pdf-parse is not installed. ' +\n 'Run `npm install pdf-parse` to enable PDF extraction.',\n )\n }\n const buf = Buffer.from(raw, 'binary')\n const result = await (pdfParse as (b: Buffer) => Promise<{ text: string }>)(buf)\n return result.text\n },\n}\n\nconst docx: KnowledgeExtractorV1 = {\n format: 'docx',\n requiresNode: true,\n extract: async (raw) => {\n let mammoth: unknown\n try {\n // mammoth has no @types package; access via dynamic any so the\n // optional dep can stay un-installed without tripping tsc.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mammoth = await import('mammoth' as any)\n } catch {\n throw new Error(\n 'ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: mammoth is not installed. ' +\n 'Run `npm install mammoth` to enable DOCX extraction.',\n )\n }\n const buf = Buffer.from(raw, 'binary')\n const result = await (\n mammoth as { extractRawText: (opts: { buffer: Buffer }) => Promise<{ value: string }> }\n ).extractRawText({ buffer: buf })\n return result.value\n },\n}\n\nconst EXTRACTORS: Record<KnowledgeFormatV1, KnowledgeExtractorV1> = {\n md,\n txt: text,\n json,\n csv,\n html,\n pdf,\n docx,\n}\n\nexport function getExtractor(format: KnowledgeFormatV1): KnowledgeExtractorV1 {\n const e = EXTRACTORS[format]\n if (e === undefined) throw new Error(`ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: ${format}`)\n return e\n}\n","/**\n * StorageSkillSource — the default `SkillSource`.\n *\n * Reads `SKILL.md` files (and optional `pages/*.md`) from the\n * workspace storage adapter. Empty/missing `baseDir` → `list()`\n * returns `[]` (equivalent to \"no skills configured\"). `autoload:\n * false` at the config layer is handled upstream — this source does\n * not read that flag.\n *\n * Plan 022: the previous workspace-then-global fallback lookup was\n * removed along with the global scope. The workspace IS the tenant\n * root; no cross-tenant merging.\n */\n\nimport { loadSkills } from './loader.js'\nimport type { EngineStorage, StorageAdapter } from '../storage/interface.js'\nimport type { ResolvedSkill, SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\nexport interface StorageSkillSourceOptions {\n readonly storage: EngineStorage\n /** Directory under the workspace adapter root. Default: `'skills'`. */\n readonly baseDir?: string\n}\n\nexport class StorageSkillSource implements SkillSource {\n private readonly storage: EngineStorage\n private readonly baseDir: string\n\n constructor(options: StorageSkillSourceOptions) {\n this.storage = options.storage\n this.baseDir = options.baseDir ?? 'skills'\n }\n\n async list(): Promise<ReadonlyArray<ResolvedSkill>> {\n const loaded = await loadSkills(this.storage.workspace, this.baseDir)\n return loaded.map((s) => ({\n name: s.name,\n description: s.description,\n hasPages: s.hasPages,\n }))\n }\n\n async getSkillFile(skill: string): Promise<string | null> {\n if (!SAFE_NAME.test(skill)) return null\n return this.findFile(skill, 'SKILL.md')\n }\n\n async getPage(skill: string, page: string): Promise<string | null> {\n if (!SAFE_NAME.test(skill)) return null\n if (!SAFE_NAME.test(page)) return null\n return this.findFile(skill, `pages/${page}.md`)\n }\n\n async listPages(skill: string): Promise<ReadonlyArray<string>> {\n if (!SAFE_NAME.test(skill)) return []\n return this.listPagesIn(this.storage.workspace, skill)\n }\n\n private async listPagesIn(\n adapter: StorageAdapter,\n skill: string,\n ): Promise<ReadonlyArray<string>> {\n const pagesDir = `${this.baseDir}/${skill}/pages`\n try {\n const entries = await adapter.listDir(pagesDir)\n return entries\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace(/\\.md$/, ''))\n .sort()\n } catch {\n return []\n }\n }\n\n private async findFile(skill: string, relative: string): Promise<string | null> {\n const path = `${this.baseDir}/${skill}/${relative}`\n return this.readIfExists(this.storage.workspace, path)\n }\n\n private async readIfExists(adapter: StorageAdapter, path: string): Promise<string | null> {\n try {\n return await adapter.readFile(path)\n } catch {\n return null\n }\n }\n}\n","/**\n * InlineSkillSource — the per-run override `SkillSource`.\n *\n * Takes a list of `SkillOverride` records and resolves bodies from\n * inline `body` (fast path, no network) or `url` (HTTPS fetch on\n * demand, cached per instance). Designed for Cloudflare Workers —\n * zero `node:*` imports, plain `fetch`.\n *\n * Security:\n * - Optional `allowedHosts` gate. When set, URL fetches outside the\n * allowlist throw before making the request. When unset (default),\n * any URL is allowed — fine for local dev, risky for production.\n * - `timeoutMs` aborts stuck fetches (default: 15s).\n *\n * Caching:\n * - Bodies (main + each page) are memoized within the instance, so\n * repeated `SkillPage` calls within one run never refetch.\n * - No cross-run cache. Each run constructs a fresh InlineSkillSource.\n */\n\nimport { ConfigError } from '../engine/errors.js'\nimport type { ResolvedSkill, SkillOverride, SkillPageOverride, SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\nconst DEFAULT_TIMEOUT_MS = 15_000\n\nexport interface InlineSkillSourceOptions {\n /** Fetch implementation. Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Host allowlist for URL fetches. When empty/undefined, any URL is\n * allowed. When set, each URL's host must exactly match an entry or\n * be a subdomain of one (`api.example.com` matches `example.com`).\n */\n readonly allowedHosts?: ReadonlyArray<string>\n /** Per-request fetch timeout. Default 15_000 ms. */\n readonly timeoutMs?: number\n}\n\nexport class InlineSkillSource implements SkillSource {\n private readonly byName = new Map<string, SkillOverride>()\n private readonly cache = new Map<string, string>()\n private readonly fetchImpl: typeof globalThis.fetch\n private readonly allowedHosts: ReadonlyArray<string> | undefined\n private readonly timeoutMs: number\n\n constructor(overrides: ReadonlyArray<SkillOverride>, options: InlineSkillSourceOptions = {}) {\n for (const override of overrides) {\n if (!SAFE_NAME.test(override.name)) {\n throw new ConfigError(\n `InlineSkillSource: invalid skill name \"${override.name}\". Must match [A-Za-z0-9_-]+`,\n )\n }\n if (override.pages !== undefined) {\n for (const pageName of Object.keys(override.pages)) {\n if (!SAFE_NAME.test(pageName)) {\n throw new ConfigError(\n `InlineSkillSource: invalid page name \"${pageName}\" in skill \"${override.name}\"`,\n )\n }\n }\n }\n if (this.byName.has(override.name)) {\n // Duplicate — last wins, matching disk behavior where a\n // later-loaded file would overwrite an earlier one.\n if (typeof console !== 'undefined') {\n console.warn(\n `[la-machina/engine] duplicate skill override \"${override.name}\" — later entry wins`,\n )\n }\n }\n this.byName.set(override.name, override)\n }\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n this.allowedHosts = options.allowedHosts\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n }\n\n async list(): Promise<ReadonlyArray<ResolvedSkill>> {\n return Array.from(this.byName.values()).map((s) => ({\n name: s.name,\n description: s.description,\n hasPages: s.pages !== undefined && Object.keys(s.pages).length > 0,\n }))\n }\n\n async getSkillFile(skill: string): Promise<string | null> {\n const entry = this.byName.get(skill)\n if (entry === undefined) return null\n return this.resolve(`skill:${skill}`, entry.body, entry.url, entry.headers)\n }\n\n async getPage(skill: string, page: string): Promise<string | null> {\n const entry = this.byName.get(skill)\n if (entry === undefined) return null\n const pageEntry: SkillPageOverride | undefined = entry.pages?.[page]\n if (pageEntry === undefined) return null\n return this.resolve(`page:${skill}/${page}`, pageEntry.body, pageEntry.url, entry.headers)\n }\n\n async listPages(skill: string): Promise<ReadonlyArray<string>> {\n const entry = this.byName.get(skill)\n if (entry === undefined || entry.pages === undefined) return []\n return Object.keys(entry.pages).sort()\n }\n\n private async resolve(\n cacheKey: string,\n inline: string | undefined,\n url: string | undefined,\n headers: Readonly<Record<string, string>> | undefined,\n ): Promise<string | null> {\n if (inline !== undefined) return inline\n if (url === undefined) return null\n\n const cached = this.cache.get(cacheKey)\n if (cached !== undefined) return cached\n\n this.assertUrlAllowed(url)\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), this.timeoutMs)\n let response: Response\n try {\n response = await this.fetchImpl(url, {\n method: 'GET',\n ...(headers !== undefined ? { headers } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timer)\n }\n\n if (!response.ok) {\n throw new Error(\n `InlineSkillSource: fetch ${url} → HTTP ${String(response.status)} ${response.statusText}`,\n )\n }\n const text = await response.text()\n this.cache.set(cacheKey, text)\n return text\n }\n\n private assertUrlAllowed(url: string): void {\n const hosts = this.allowedHosts\n if (hosts === undefined || hosts.length === 0) return\n let host: string\n try {\n host = new URL(url).host\n } catch {\n throw new Error(`InlineSkillSource: malformed URL \"${url}\"`)\n }\n const ok = hosts.some((h) => host === h || host.endsWith(`.${h}`))\n if (!ok) {\n throw new Error(`InlineSkillSource: host \"${host}\" not in allowedHosts [${hosts.join(', ')}]`)\n }\n }\n}\n","/**\n * Storage factory — turns a `ResolvedStorageConfig` into an\n * `EngineStorage` bundle with a single workspace-scoped adapter.\n *\n * Unlike La-Machina's original factory (which read `process.env`\n * directly), this version takes a fully-resolved config object as its\n * only input. Env resolution is the caller's responsibility (done\n * inside `initEngine()`). Keeping the factory pure makes it\n * trivially testable.\n *\n * Path layout (identical on local + r2 + r2-binding):\n *\n * {rootPath}/\n * └── workspaces/\n * └── {workspaceId}/\n * └── .claude/ ← tenant root\n * ├── memory/…\n * ├── projects/{runId}/nodes/{nodeId}/…\n * └── skills/…\n *\n * The `workspaces/` segment is a namespace guard (keeps engine data\n * separated from anything else in a shared bucket/filesystem); the\n * `.claude/` segment is a convention marker — \"engine-owned data,\n * don't touch.\" Both cost one directory level and pay off.\n *\n * Plan 022 removed the previous `global` scope (rooted at\n * `{rootPath}/.claude/`). Cross-tenant data sharing isn't a feature\n * real deployments want; the workspace IS the tenant boundary.\n */\n\nimport type { ResolvedStorageConfig } from '../config/types.js'\nimport type { EngineStorage } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { LocalStorageAdapter } from './localAdapter.js'\nimport { R2StorageAdapter } from './r2Adapter.js'\nimport { R2BindingStorageAdapter } from './r2BindingAdapter.js'\n\n/** The subfolder used for all engine data inside a workspace. */\nconst ENGINE_DATA_FOLDER = '.claude'\n\n/** The subfolder name that holds one folder per workspace (tenant). */\nconst WORKSPACES_FOLDER = 'workspaces'\n\n/**\n * The user-owned knowledge folder (Plan 023). Sibling to `.claude/`,\n * NOT inside it — clean separation between engine-managed state\n * and user-authored content.\n */\nconst KNOWLEDGE_FOLDER = 'knowledge'\n\nexport interface CreateEngineStorageOptions {\n /**\n * When true, builds a second `StorageAdapter` rooted at\n * `{rootPath}/workspaces/{workspaceId}/knowledge/` and exposes\n * it on `EngineStorage.knowledge`. Plan 023.\n */\n readonly withKnowledge?: boolean\n}\n\nexport async function createEngineStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions = {},\n): Promise<EngineStorage> {\n switch (config.provider) {\n case 'local':\n return createLocalStorage(config, options)\n case 'r2':\n return createR2Storage(config, options)\n case 'r2-binding':\n return createR2BindingStorage(config, options)\n }\n}\n\nasync function createLocalStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): Promise<EngineStorage> {\n // Lazy path import — only needed for local provider (Node.js only)\n const path = await import('node:path')\n const tenantRoot = path.join(config.rootPath, WORKSPACES_FOLDER, config.workspaceId)\n const workspaceRoot = path.join(tenantRoot, ENGINE_DATA_FOLDER)\n const out: EngineStorage = { workspace: new LocalStorageAdapter(workspaceRoot) }\n if (options.withKnowledge) {\n const knowledgeRoot = path.join(tenantRoot, KNOWLEDGE_FOLDER)\n return { ...out, knowledge: new LocalStorageAdapter(knowledgeRoot) }\n }\n return out\n}\n\nfunction createR2Storage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): EngineStorage {\n if (!config.r2) {\n throw new StorageError('storage.r2 is required when storage.provider === \"r2\"')\n }\n // Strip leading/trailing slashes so the prefix joins cleanly.\n const rootPrefix = config.rootPath.replace(/^\\/+|\\/+$/g, '')\n const tenantPrefix = `${rootPrefix}/${WORKSPACES_FOLDER}/${config.workspaceId}`\n const workspacePrefix = `${tenantPrefix}/${ENGINE_DATA_FOLDER}`\n const out: EngineStorage = { workspace: new R2StorageAdapter(config.r2, workspacePrefix) }\n if (options.withKnowledge) {\n const knowledgePrefix = `${tenantPrefix}/${KNOWLEDGE_FOLDER}`\n return { ...out, knowledge: new R2StorageAdapter(config.r2, knowledgePrefix) }\n }\n return out\n}\n\nfunction createR2BindingStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): EngineStorage {\n if (!config.r2Binding) {\n throw new StorageError('storage.r2Binding is required when storage.provider === \"r2-binding\"')\n }\n const rootPrefix = config.rootPath.replace(/^\\/+|\\/+$/g, '')\n const tenantPrefix = `${rootPrefix}/${WORKSPACES_FOLDER}/${config.workspaceId}`\n const workspacePrefix = `${tenantPrefix}/${ENGINE_DATA_FOLDER}`\n const out: EngineStorage = {\n workspace: new R2BindingStorageAdapter(config.r2Binding, workspacePrefix),\n }\n if (options.withKnowledge) {\n const knowledgePrefix = `${tenantPrefix}/${KNOWLEDGE_FOLDER}`\n return {\n ...out,\n knowledge: new R2BindingStorageAdapter(config.r2Binding, knowledgePrefix),\n }\n }\n return out\n}\n","/**\n * StorageAdapter — abstract filesystem interface for la-machina-engine.\n *\n * All paths are relative to the adapter's root. The adapter enforces\n * path safety (no traversal, no absolute paths, no null bytes) and\n * provides a filesystem-shaped API that subsystems can use without\n * knowing whether the backend is local disk, R2, or any other\n * S3-compatible object store.\n *\n * Implementations ship in this package:\n * - `LocalStorageAdapter` (src/storage/localAdapter.ts) — fs-backed\n * - `R2StorageAdapter` (src/storage/r2Adapter.ts) — S3-compatible\n *\n * Users may supply custom adapters implementing this interface.\n */\n\nexport interface FileStat {\n readonly size: number\n readonly mtime: Date\n}\n\nexport interface StorageAdapter {\n /** Read a file as UTF-8 text. Returns null if file doesn't exist. */\n readFile(relativePath: string): Promise<string | null>\n\n /** Write a file atomically. Creates parent directories if needed. */\n writeFile(relativePath: string, content: string): Promise<void>\n\n /** Append to a file. Creates it if it doesn't exist. */\n appendFile(relativePath: string, content: string): Promise<void>\n\n /** Delete a file. No-op if it doesn't exist. */\n deleteFile(relativePath: string): Promise<void>\n\n /** Check if a file or directory exists. */\n exists(relativePath: string): Promise<boolean>\n\n /**\n * List entries in a directory. Returns just the names (not full paths).\n * Returns an empty array if the directory doesn't exist.\n */\n listDir(relativePath: string): Promise<string[]>\n\n /** Create a directory (recursive). No-op on S3-like backends. */\n mkdir(relativePath: string): Promise<void>\n\n /** Check if a path is a directory. */\n isDirectory(relativePath: string): Promise<boolean>\n\n /** Get file metadata. Returns null if file doesn't exist. */\n stat(relativePath: string): Promise<FileStat | null>\n}\n\n/**\n * Single-root storage model (Plan 022).\n *\n * - `workspace`: rooted at `{rootPath}/workspaces/{workspaceId}/.claude/`.\n * The workspace IS the tenant root — every memory, skill, run,\n * transcript, snapshot, and offloaded tool result for a tenant\n * lives under this path.\n *\n * The previous `global` scope (rooted at `{rootPath}/.claude/`) was\n * removed: cross-tenant data sharing isn't a feature real\n * deployments want — it's a security problem.\n */\nexport interface EngineStorage {\n readonly workspace: StorageAdapter\n /**\n * Optional knowledge-base adapter (Plan 023). Built by the\n * factory only when `config.knowledge?.enabled === true`.\n * Rooted at `{rootPath}/workspaces/{workspaceId}/knowledge/` —\n * a sibling of the workspace adapter's `.claude/` root.\n */\n readonly knowledge?: StorageAdapter\n}\n\n/**\n * Error thrown by all storage operations. `cause` is preserved as-is\n * (usually an `ErrnoException` or AWS SDK error) so callers can inspect\n * the underlying failure.\n */\nexport class StorageError extends Error {\n override readonly cause?: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'StorageError'\n if (cause !== undefined) this.cause = cause\n }\n}\n","/**\n * LocalStorageAdapter — filesystem-backed `StorageAdapter`.\n *\n * Ported from La-Machina's production implementation. Wraps Node\n * `fs/promises` with:\n *\n * - **Atomic writes** (temp file + rename pattern)\n * - **Path safety** via `validateRelativePath` — blocks traversal, absolute\n * paths, null bytes at every entrypoint\n * - **Null-on-missing semantics** — `readFile`/`stat` return `null` instead\n * of throwing `ENOENT`; `listDir` returns `[]` for missing directories\n * - **Recursive directory creation** on all write operations\n *\n * Errors from the underlying `fs` module are wrapped in `StorageError` with\n * the original error preserved as `.cause`.\n */\n\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\n// Lazy imports — `node:fs` and `node:path` are not available in\n// Cloudflare Workers. LocalStorageAdapter is only instantiated when\n// `storage.provider === 'local'` (Node.js only), but the top-level\n// import would crash Workers at module load time.\nlet _fs: typeof import('node:fs/promises') | null = null\nlet _path: typeof import('node:path') | null = null\nlet _existsSync: typeof import('node:fs').existsSync | null = null\n\nasync function getFs(): Promise<typeof import('node:fs/promises')> {\n if (_fs === null) _fs = await import('node:fs/promises')\n return _fs\n}\n\nasync function getPath(): Promise<typeof import('node:path')> {\n if (_path === null) _path = await import('node:path')\n return _path\n}\n\nasync function getExistsSync(): Promise<typeof import('node:fs').existsSync> {\n if (_existsSync === null) {\n const fsModule = await import('node:fs')\n _existsSync = fsModule.existsSync\n }\n return _existsSync\n}\n\nfunction errnoCode(err: unknown): string | undefined {\n return (err as { code?: string } | null)?.code\n}\n\nexport class LocalStorageAdapter implements StorageAdapter {\n private readonly root: string\n\n constructor(root: string) {\n if (typeof root !== 'string' || root.length === 0) {\n throw new StorageError('LocalStorageAdapter: root must be a non-empty string')\n }\n this.root = root\n }\n\n private async resolve(rel: string): Promise<string> {\n validateRelativePath(rel)\n const p = await getPath()\n return p.join(this.root, rel)\n }\n\n async readFile(rel: string): Promise<string | null> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n return await fs.readFile(full, 'utf-8')\n } catch (err) {\n const code = errnoCode(err)\n if (code === 'ENOENT' || code === 'EISDIR') return null\n throw new StorageError(`Failed to read file: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const [fs, p, full] = await Promise.all([getFs(), getPath(), this.resolve(rel)])\n try {\n await fs.mkdir(p.dirname(full), { recursive: true })\n const tmp = `${full}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`\n await fs.writeFile(tmp, content, 'utf-8')\n await fs.rename(tmp, full)\n } catch (err) {\n throw new StorageError(`Failed to write file: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n const [fs, p, full] = await Promise.all([getFs(), getPath(), this.resolve(rel)])\n try {\n await fs.mkdir(p.dirname(full), { recursive: true })\n await fs.appendFile(full, content, 'utf-8')\n } catch (err) {\n throw new StorageError(`Failed to append to file: ${rel}`, err)\n }\n }\n\n async deleteFile(rel: string): Promise<void> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.unlink(full)\n } catch (err) {\n if (errnoCode(err) === 'ENOENT') return\n throw new StorageError(`Failed to delete file: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.access(full)\n return true\n } catch {\n return false\n }\n }\n\n async listDir(rel: string): Promise<string[]> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n return await fs.readdir(full)\n } catch (err) {\n const code = errnoCode(err)\n if (code === 'ENOENT' || code === 'ENOTDIR') return []\n throw new StorageError(`Failed to list directory: ${rel}`, err)\n }\n }\n\n async mkdir(rel: string): Promise<void> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.mkdir(full, { recursive: true })\n } catch (err) {\n throw new StorageError(`Failed to create directory: ${rel}`, err)\n }\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n const s = await fs.stat(full)\n return s.isDirectory()\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n const s = await fs.stat(full)\n return { size: s.size, mtime: s.mtime }\n } catch (err) {\n if (errnoCode(err) === 'ENOENT') return null\n throw new StorageError(`Failed to stat file: ${rel}`, err)\n }\n }\n\n getRoot(): string {\n return this.root\n }\n\n async rootExists(): Promise<boolean> {\n const existsSync = await getExistsSync()\n return existsSync(this.root)\n }\n}\n","/**\n * Path-safety validation for all StorageAdapter entrypoints.\n *\n * Every adapter method (read, write, delete, list, stat, exists, mkdir,\n * isDirectory, appendFile) calls `validateRelativePath(path)` as its first\n * step. This is the single gate that enforces:\n *\n * - paths are non-empty strings\n * - paths are relative (no leading `/` or `\\`)\n * - paths contain no `..` segments (no parent traversal)\n * - paths contain no null bytes (defensive against C-string injection)\n *\n * The adapter trusts nothing from the caller — config files, tool inputs,\n * subagent outputs, and caller-supplied paths all funnel through this.\n */\n\nimport { StorageError } from './interface.js'\n\nexport function validateRelativePath(path: unknown): asserts path is string {\n if (typeof path !== 'string') {\n throw new StorageError('Invalid path: must be a string')\n }\n // Empty string is allowed and means \"the adapter root\" — used by\n // recursive walkers and glob tools that need to start at the top.\n // For non-list operations the underlying fs will reject root reads\n // with a clear error (EISDIR for readFile, etc.).\n if (path.startsWith('/') || path.startsWith('\\\\')) {\n throw new StorageError(`Invalid path: absolute paths not allowed: ${path}`)\n }\n if (path.includes('..')) {\n throw new StorageError(`Invalid path: parent traversal (..) not allowed: ${path}`)\n }\n if (path.includes('\\0')) {\n throw new StorageError('Invalid path: null bytes not allowed')\n }\n}\n","/**\n * R2StorageAdapter — Cloudflare R2 (S3-compatible) implementation.\n *\n * Ported from La-Machina. Uses `@aws-sdk/client-s3` since R2 speaks the S3\n * protocol. Path semantics:\n *\n * - Files become objects keyed at `${rootPrefix}/${relativePath}`\n * - Directories are synthetic — S3 has no real directory concept. `mkdir`\n * is a no-op; `listDir` uses `Delimiter: '/'` to separate files from\n * \"subdirectories\" (common prefixes).\n * - `appendFile` is read-modify-write (S3 has no native append primitive).\n * OK for small files (JSONL episode logs); prohibitively expensive for\n * large files.\n * - `writeFile` is a single atomic PutObject — no temp+rename dance.\n *\n * The backing S3Client is constructed from config. Tests use\n * `aws-sdk-client-mock` to intercept `.send()` without needing DI.\n */\n\nimport {\n DeleteObjectCommand,\n GetObjectCommand,\n HeadObjectCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3'\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\nexport interface R2ClientConfig {\n readonly bucket: string\n readonly region: string\n readonly accessKeyId: string\n readonly secretAccessKey: string\n readonly endpoint?: string | undefined\n}\n\nexport class R2StorageAdapter implements StorageAdapter {\n private readonly client: S3Client\n private readonly bucket: string\n private readonly rootPrefix: string\n\n constructor(config: R2ClientConfig, rootPrefix: string) {\n if (!config.bucket || !config.accessKeyId || !config.secretAccessKey) {\n throw new StorageError(\n 'R2StorageAdapter: bucket, accessKeyId, and secretAccessKey are all required',\n )\n }\n\n const clientConfig: ConstructorParameters<typeof S3Client>[0] = {\n region: config.region,\n credentials: {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n },\n forcePathStyle: true, // R2/MinIO compatibility\n }\n if (config.endpoint !== undefined) {\n clientConfig.endpoint = config.endpoint\n }\n\n this.client = new S3Client(clientConfig)\n this.bucket = config.bucket\n // Normalize prefix: no leading or trailing slashes\n this.rootPrefix = rootPrefix.replace(/^\\/+|\\/+$/g, '')\n }\n\n private key(rel: string): string {\n validateRelativePath(rel)\n const normalized = rel.replace(/^\\/+/, '')\n return this.rootPrefix ? `${this.rootPrefix}/${normalized}` : normalized\n }\n\n async readFile(rel: string): Promise<string | null> {\n const Key = this.key(rel)\n try {\n const resp = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key }))\n if (!resp.Body) return null\n return await resp.Body.transformToString('utf-8')\n } catch (err) {\n if (isNotFound(err)) return null\n throw new StorageError(`Failed to read R2 object: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const Key = this.key(rel)\n try {\n await this.client.send(\n new PutObjectCommand({\n Bucket: this.bucket,\n Key,\n Body: content,\n ContentType: 'text/plain; charset=utf-8',\n }),\n )\n } catch (err) {\n throw new StorageError(`Failed to write R2 object: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n // S3/R2 has no native append — read-modify-write.\n const existing = await this.readFile(rel)\n const next = (existing ?? '') + content\n await this.writeFile(rel, next)\n }\n\n async deleteFile(rel: string): Promise<void> {\n const Key = this.key(rel)\n try {\n await this.client.send(new DeleteObjectCommand({ Bucket: this.bucket, Key }))\n } catch (err) {\n if (isNotFound(err)) return\n throw new StorageError(`Failed to delete R2 object: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const Key = this.key(rel)\n try {\n await this.client.send(new HeadObjectCommand({ Bucket: this.bucket, Key }))\n return true\n } catch (err) {\n if (isNotFound(err)) {\n // Could still be a synthetic directory — check by prefix\n return this.isDirectory(rel)\n }\n throw new StorageError(`Failed to check R2 object: ${rel}`, err)\n }\n }\n\n async listDir(rel: string): Promise<string[]> {\n const prefix = this.key(rel) + '/'\n const results: string[] = []\n let continuationToken: string | undefined\n\n try {\n do {\n const resp = await this.client.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n Delimiter: '/',\n ContinuationToken: continuationToken,\n }),\n )\n\n // Files directly under this prefix\n for (const obj of resp.Contents ?? []) {\n if (!obj.Key) continue\n const name = obj.Key.slice(prefix.length)\n if (name && !name.includes('/')) {\n results.push(name)\n }\n }\n\n // \"Subdirectories\" (common prefixes)\n for (const cp of resp.CommonPrefixes ?? []) {\n if (!cp.Prefix) continue\n const name = cp.Prefix.slice(prefix.length).replace(/\\/$/, '')\n if (name) results.push(name)\n }\n\n continuationToken = resp.IsTruncated ? resp.NextContinuationToken : undefined\n } while (continuationToken)\n\n return results\n } catch (err) {\n if (isNotFound(err)) return []\n throw new StorageError(`Failed to list R2 directory: ${rel}`, err)\n }\n }\n\n mkdir(rel: string): Promise<void> {\n // S3/R2 has no real directories — no-op. Directories are created\n // implicitly when files are written beneath them. But we still\n // validate the path so the contract with LocalStorageAdapter holds:\n // every method rejects traversal at its entrypoint. The validation\n // must be wrapped in a promise so sync throws become rejections.\n return Promise.resolve().then(() => validateRelativePath(rel))\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const prefix = this.key(rel) + '/'\n try {\n const resp = await this.client.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n MaxKeys: 1,\n }),\n )\n return (resp.KeyCount ?? 0) > 0\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const Key = this.key(rel)\n try {\n const resp = await this.client.send(new HeadObjectCommand({ Bucket: this.bucket, Key }))\n return {\n size: resp.ContentLength ?? 0,\n mtime: resp.LastModified ?? new Date(),\n }\n } catch (err) {\n if (isNotFound(err)) return null\n throw new StorageError(`Failed to stat R2 object: ${rel}`, err)\n }\n }\n}\n\n/**\n * S3 \"not found\" errors come in several shapes depending on the client\n * version and whether HEAD or GET was used.\n */\nfunction isNotFound(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as {\n name?: unknown\n Code?: unknown\n $metadata?: { httpStatusCode?: unknown }\n }\n if (e.name === 'NoSuchKey' || e.name === 'NotFound') return true\n if (e.Code === 'NoSuchKey' || e.Code === 'NotFound') return true\n if (e.$metadata?.httpStatusCode === 404) return true\n return false\n}\n","/**\n * R2BindingStorageAdapter — Cloudflare Workers R2 binding (NOT S3 SDK).\n *\n * Unlike `R2StorageAdapter` which talks to R2 over the S3 REST protocol,\n * this adapter uses the native R2 binding exposed to Workers runtime:\n *\n * [[r2_buckets]]\n * binding = \"BUCKET\"\n * bucket_name = \"my-bucket\"\n *\n * // In code:\n * new R2BindingStorageAdapter(env.BUCKET, 'tenant/acme')\n *\n * Why use this over `R2StorageAdapter` on Workers?\n * - `@aws-sdk/client-s3` is heavy (~500 KB) and the Workers-compatibility\n * story for ListObjectsV2 XML parsing is brittle; CommonPrefixes come\n * back empty in some runtimes, silently breaking `listDir`.\n * - The R2 binding API (`bucket.list`, `bucket.get`, `bucket.put`,\n * `bucket.delete`) is native, typed, and uses native JSON responses.\n * - No AWS credentials, no endpoint URL — the binding handles auth.\n *\n * Use `R2StorageAdapter` on Node or anywhere you don't have a Workers\n * binding (local dev with Miniflare's S3 endpoint, backfills, etc).\n * Use this adapter inside Workers for reliability and bundle size.\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\n// ---------- Minimal R2 binding types ----------\n// We don't depend on `@cloudflare/workers-types` here to keep this adapter\n// usable outside Workers (e.g., for testing with a mock). These match the\n// shape of the native R2Bucket interface.\n\ninterface R2Object {\n key: string\n size: number\n uploaded: Date\n httpMetadata?: R2HTTPMetadata\n customMetadata?: Record<string, string>\n}\n\ninterface R2ObjectBody extends R2Object {\n text(): Promise<string>\n arrayBuffer(): Promise<ArrayBuffer>\n blob?(): Promise<Blob>\n}\n\ninterface R2Objects {\n objects: R2Object[]\n truncated: boolean\n cursor?: string\n delimitedPrefixes?: string[]\n}\n\ninterface R2HTTPMetadata {\n contentType?: string\n contentLanguage?: string\n contentDisposition?: string\n contentEncoding?: string\n cacheControl?: string\n cacheExpiry?: Date\n}\n\ninterface R2ListOptions {\n prefix?: string\n delimiter?: string\n cursor?: string\n limit?: number\n include?: Array<'httpMetadata' | 'customMetadata'>\n}\n\ninterface R2PutOptions {\n httpMetadata?: R2HTTPMetadata\n customMetadata?: Record<string, string>\n}\n\n/**\n * Structural type for `env.BUCKET` — intentionally not imported from\n * `@cloudflare/workers-types` so this adapter has no extra peer deps.\n */\nexport interface R2BucketBinding {\n head(key: string): Promise<R2Object | null>\n get(key: string): Promise<R2ObjectBody | null>\n put(\n key: string,\n value: string | ArrayBuffer | ArrayBufferView | ReadableStream | Blob | null,\n options?: R2PutOptions,\n ): Promise<R2Object>\n delete(keys: string | string[]): Promise<void>\n list(options?: R2ListOptions): Promise<R2Objects>\n}\n\n// ---------- Adapter ----------\n\nexport class R2BindingStorageAdapter implements StorageAdapter {\n private readonly bucket: R2BucketBinding\n private readonly rootPrefix: string\n\n constructor(bucket: R2BucketBinding, rootPrefix: string) {\n if (bucket === undefined || bucket === null) {\n throw new StorageError(\n 'R2BindingStorageAdapter: bucket binding is required (pass env.BUCKET)',\n )\n }\n this.bucket = bucket\n // Normalize: no leading or trailing slashes\n this.rootPrefix = rootPrefix.replace(/^\\/+|\\/+$/g, '')\n }\n\n private key(rel: string): string {\n validateRelativePath(rel)\n const normalized = rel.replace(/^\\/+/, '')\n return this.rootPrefix ? `${this.rootPrefix}/${normalized}` : normalized\n }\n\n async readFile(rel: string): Promise<string | null> {\n const key = this.key(rel)\n try {\n const obj = await this.bucket.get(key)\n if (obj === null) return null\n return await obj.text()\n } catch (err) {\n throw new StorageError(`Failed to read R2 object: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const key = this.key(rel)\n try {\n await this.bucket.put(key, content, {\n httpMetadata: { contentType: 'text/plain; charset=utf-8' },\n })\n } catch (err) {\n throw new StorageError(`Failed to write R2 object: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n // R2 has no native append — read-modify-write. This is O(size+len)\n // per append; fine for small JSONL files, expensive for big blobs.\n const existing = await this.readFile(rel)\n const next = (existing ?? '') + content\n await this.writeFile(rel, next)\n }\n\n async deleteFile(rel: string): Promise<void> {\n const key = this.key(rel)\n try {\n await this.bucket.delete(key)\n } catch (err) {\n throw new StorageError(`Failed to delete R2 object: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const key = this.key(rel)\n try {\n const head = await this.bucket.head(key)\n if (head !== null) return true\n } catch {\n /* fall through to directory check */\n }\n // Not a file — check if it's a \"directory\" (any object with this prefix)\n try {\n const listing = await this.bucket.list({ prefix: `${key}/`, limit: 1 })\n return listing.objects.length > 0 || (listing.delimitedPrefixes?.length ?? 0) > 0\n } catch {\n return false\n }\n }\n\n /**\n * List direct children of `rel` (files + subdirectory names). Returns\n * just the names (not full keys). Empty array if path doesn't exist.\n *\n * Uses the native R2 list API with `delimiter: '/'` which returns\n * `delimitedPrefixes` for \"subdirectories\" and `objects` for files —\n * equivalent to S3's CommonPrefixes + Contents but parsed by the\n * binding itself (no XML, no SDK).\n */\n async listDir(rel: string): Promise<string[]> {\n const prefix = this.key(rel) + '/'\n const results: string[] = []\n let cursor: string | undefined\n\n try {\n do {\n const listing = await this.bucket.list({\n prefix,\n delimiter: '/',\n ...(cursor !== undefined ? { cursor } : {}),\n })\n\n // Files directly under this prefix\n for (const obj of listing.objects) {\n const name = obj.key.slice(prefix.length)\n if (name && !name.includes('/')) {\n results.push(name)\n }\n }\n\n // \"Subdirectories\" — delimitedPrefixes come back as full paths\n // ending in '/'. Slice off the parent prefix and trailing slash.\n for (const dp of listing.delimitedPrefixes ?? []) {\n const name = dp.slice(prefix.length).replace(/\\/$/, '')\n if (name) results.push(name)\n }\n\n cursor = listing.truncated ? listing.cursor : undefined\n } while (cursor !== undefined)\n\n return results\n } catch (err) {\n throw new StorageError(`Failed to list R2 directory: ${rel}`, err)\n }\n }\n\n mkdir(rel: string): Promise<void> {\n // No-op — R2 has no directories. Validate path shape for parity with\n // other adapters so traversal attempts are rejected at the entrypoint.\n return Promise.resolve().then(() => validateRelativePath(rel))\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const prefix = this.key(rel) + '/'\n try {\n const listing = await this.bucket.list({ prefix, limit: 1 })\n return listing.objects.length > 0 || (listing.delimitedPrefixes?.length ?? 0) > 0\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const key = this.key(rel)\n try {\n const head = await this.bucket.head(key)\n if (head === null) return null\n return { size: head.size, mtime: head.uploaded }\n } catch (err) {\n throw new StorageError(`Failed to stat R2 object: ${rel}`, err)\n }\n }\n}\n","/**\n * TranscriptReader — reconstructs a transcript from its sharded form.\n *\n * The reader locates shards in `{logPath}/`, sorts them numerically, and\n * streams the parsed `Entry` objects back in their original order. Two\n * strategies are used to enumerate shards:\n *\n * 1. **Meta-guided** (fast path): if `meta.json` exists, use its\n * `lastShardIndex + 1` as the shard count and read `000000.jsonl` …\n * `{lastShardIndex}.jsonl` in order.\n * 2. **Directory scan** (fallback): list the log directory and filter\n * entries matching `/^\\d{6}\\.jsonl$/`, sort by the numeric prefix.\n *\n * The second mode handles recovery scenarios where `meta.json` is missing\n * or corrupted, and also makes the reader robust against partial writes\n * during a crash (we still read whatever shards landed on disk).\n *\n * Corrupt lines raise an error that identifies the shard filename and\n * the 1-indexed line number, so callers can investigate.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { parseEntryLine, type Entry } from './entries.js'\nimport { readMeta } from './meta.js'\n\nconst SHARD_PATTERN = /^(\\d{6})\\.jsonl$/\n\nexport class TranscriptReader {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logPath: string,\n ) {}\n\n /**\n * Async iterator over entries, streamed shard by shard. Use this when\n * the transcript might be large — it avoids materializing everything\n * into memory at once.\n */\n async *entries(): AsyncGenerator<Entry, void, void> {\n const shardNames = await this.discoverShards()\n for (const shardName of shardNames) {\n const key = `${this.logPath}/${shardName}`\n const content = await this.storage.readFile(key)\n if (content === null || content.length === 0) continue\n const lines = content.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n if (line === undefined || line.length === 0) continue\n try {\n yield parseEntryLine(line)\n } catch {\n // Corrupted line — skip with warning instead of crashing.\n // A single bad line should not block resume of the entire transcript.\n if (typeof console !== 'undefined') {\n console.warn(`TranscriptReader: skipping corrupted line in ${shardName}:${i + 1}`)\n }\n }\n }\n }\n }\n\n /** Collect every entry into an array. Convenient for small transcripts. */\n async readAll(): Promise<Entry[]> {\n const out: Entry[] = []\n for await (const e of this.entries()) out.push(e)\n return out\n }\n\n // ---------- shard discovery ----------\n\n private async discoverShards(): Promise<string[]> {\n // Fast path: if meta exists, we know exactly how many shards to read.\n const meta = await readMeta(this.storage, this.logPath)\n if (meta && meta.lastShardIndex !== null) {\n const names: string[] = []\n for (let i = 0; i <= meta.lastShardIndex; i++) {\n names.push(`${String(i).padStart(6, '0')}.jsonl`)\n }\n return names\n }\n\n // Fallback: scan the directory, filter, sort numerically.\n const all = await this.storage.listDir(this.logPath)\n const shards: Array<{ name: string; index: number }> = []\n for (const name of all) {\n const match = SHARD_PATTERN.exec(name)\n if (!match || match[1] === undefined) continue\n shards.push({ name, index: parseInt(match[1], 10) })\n }\n shards.sort((a, b) => a.index - b.index)\n return shards.map((s) => s.name)\n }\n}\n","/**\n * rehydrate — reconstruct an Anthropic Messages API conversation\n * (`MessageParam[]`) from a stream of `Entry` objects read from a\n * transcript on resume.\n *\n * The transcript is the source of truth for what happened during a\n * paused run. The snapshot only stores counters and pointers; the\n * messages themselves come from replaying the JSONL shards.\n *\n * Reconstruction rules:\n * - `user` entry → push as a user message with the original content blocks\n * - `assistant` entry → push as an assistant message with the original blocks\n * - `tool_result` entry → wrap in a user message with a `tool_result`\n * content block. If the previous message was already a tool-result-only\n * user message, append to it (matching the Anthropic API contract for\n * batched tool results in one turn).\n * - `meta` and `error` entries → not part of the conversation; skipped\n * - `subagent_spawn` and `subagent_done` → not part of the conversation\n * (the parent's transcript only stores the tool_use + tool_result;\n * the spawn/done entries are auxiliary metadata)\n */\n\nimport type {\n ContentBlockParam,\n MessageParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { Entry } from '../transcript/entries.js'\n\nexport function rebuildMessagesFromEntries(entries: ReadonlyArray<Entry>): MessageParam[] {\n const messages: MessageParam[] = []\n\n for (const entry of entries) {\n if (entry.type === 'user') {\n messages.push({\n role: 'user',\n content: entry.message.content as ContentBlockParam[],\n })\n } else if (entry.type === 'assistant') {\n messages.push({\n role: 'assistant',\n content: entry.message.content as ContentBlockParam[],\n })\n } else if (entry.type === 'tool_result') {\n const block: ToolResultBlockParam = {\n type: 'tool_result',\n tool_use_id: entry.toolUseId,\n content: typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content),\n ...(entry.isError === true ? { is_error: true } : {}),\n }\n const prev = messages[messages.length - 1]\n if (\n prev !== undefined &&\n prev.role === 'user' &&\n Array.isArray(prev.content) &&\n prev.content.every(\n (b) => typeof b === 'object' && (b as { type: string }).type === 'tool_result',\n )\n ) {\n prev.content.push(block)\n } else {\n messages.push({ role: 'user', content: [block] })\n }\n }\n // Other entry types (meta, error, subagent_*) are not replayed\n // into the conversation history.\n }\n\n return messages\n}\n","/**\n * EngineResponse — unified response shape for the public API.\n *\n * Every engine.run() and engine.resume() returns this single flat shape.\n * Internal code uses RunResult (the discriminated union); this module\n * converts it to the client-facing format.\n *\n * {\n * status: 'done' | 'paused' | 'failed',\n * data: any, // user-defined — text or JSON from outputSchema\n * meta: { ... }, // tokens, turns, timing, snapshot, transcript\n * errors: [], // structured error array\n * timestamp: number, // unix ms\n * }\n */\n\nimport type {\n RunResult,\n TokenUsage,\n RunSnapshot,\n PauseReason,\n TranscriptLocation,\n} from './types.js'\nimport type { EngineError } from './errors.js'\n\nexport interface ResponseError {\n readonly code: string\n readonly message: string\n readonly details?: unknown\n}\n\nexport interface ResponseMeta {\n readonly nodeId: string\n readonly turns?: number\n readonly tokensUsed?: TokenUsage\n readonly durationMs?: number\n readonly output?: string\n readonly snapshot?: RunSnapshot\n readonly pendingToolCall?: RunSnapshot['pendingToolCall']\n readonly pauseReason?: PauseReason\n readonly transcript?: TranscriptLocation\n /**\n * Plan 019 — names of tools whose capability-stub fired during this\n * run (deduped). Callers can detect \"this run ran against a runtime\n * that couldn't execute these tools\" and retry as async with a\n * runner configured. Absent when no stub fired.\n */\n readonly capabilitiesMissing?: readonly string[]\n /** Additional context-specific fields (e.g., activity, lastTool, cancelled). */\n readonly [key: string]: unknown\n}\n\nexport interface EngineResponse {\n /** Unique run identifier — client's primary handle. Use this for resume. */\n readonly runId: string\n readonly status: 'done' | 'paused' | 'failed' | 'queued' | 'running' | 'cancelled' | 'not_found'\n readonly data: unknown\n readonly meta: ResponseMeta\n readonly errors: readonly ResponseError[]\n readonly timestamp: number\n}\n\n/**\n * Convert internal RunResult to the unified EngineResponse shape.\n */\nexport function toResponse(\n result: RunResult,\n extra: {\n runId: string\n nodeId: string\n durationMs: number\n logPath?: string\n /** Plan 019 — capability-stub names observed during the run. */\n capabilitiesMissing?: readonly string[]\n },\n): EngineResponse {\n const timestamp = Date.now()\n const capsField =\n extra.capabilitiesMissing !== undefined && extra.capabilitiesMissing.length > 0\n ? { capabilitiesMissing: extra.capabilitiesMissing }\n : {}\n\n if (result.status === 'done') {\n return {\n runId: extra.runId,\n status: 'done',\n data: result.data !== undefined ? result.data : result.output,\n meta: {\n nodeId: extra.nodeId,\n turns: result.turns,\n tokensUsed: result.tokensUsed,\n durationMs: extra.durationMs,\n output: result.output,\n ...(extra.logPath !== undefined\n ? { transcript: { path: extra.logPath, lastShardIndex: 0 } }\n : {}),\n ...capsField,\n },\n errors: [],\n timestamp,\n }\n }\n\n if (result.status === 'paused') {\n return {\n runId: extra.runId,\n status: 'paused',\n data: extractPausedData(result.snapshot.pendingToolCall),\n meta: {\n nodeId: extra.nodeId,\n turns: result.snapshot.turnsUsed,\n tokensUsed: result.snapshot.tokensUsedSoFar,\n durationMs: extra.durationMs,\n snapshot: result.snapshot,\n ...(result.snapshot.pendingToolCall !== undefined\n ? { pendingToolCall: result.snapshot.pendingToolCall }\n : {}),\n pauseReason: result.reason,\n ...(extra.logPath !== undefined\n ? { transcript: { path: extra.logPath, lastShardIndex: result.snapshot.lastShardIndex } }\n : {}),\n ...capsField,\n },\n errors: [],\n timestamp,\n }\n }\n\n // failed\n const err = result.error\n return {\n runId: extra.runId,\n status: 'failed',\n data: null,\n meta: {\n nodeId: extra.nodeId,\n turns: 0,\n tokensUsed: { input: 0, output: 0 },\n durationMs: extra.durationMs,\n transcript: result.transcript,\n },\n errors: [\n {\n code: (err as EngineError).code ?? 'ERR_UNKNOWN',\n message: err.message,\n ...(err.cause !== undefined ? { details: err.cause } : {}),\n },\n ],\n timestamp,\n }\n}\n\n/**\n * Extract the user-facing data from a pending tool call.\n *\n * For Write/Edit tools, the client only cares about the content —\n * the path is internal engine detail (available in meta.pendingToolCall).\n * For other tools, return the full input.\n */\nfunction extractPausedData(pending?: RunSnapshot['pendingToolCall']): unknown {\n if (!pending) return null\n const input = pending.input as Record<string, unknown> | undefined\n if (!input) return null\n\n // Write tool: data = content (the text being written)\n if (pending.toolName === 'Write' && typeof input.content === 'string') {\n return input.content\n }\n\n // Edit tool: data = { old_string, new_string } (the change being made)\n if (pending.toolName === 'Edit' && input.old_string !== undefined) {\n return { old_string: input.old_string, new_string: input.new_string }\n }\n\n // Bash tool: data = command\n if (pending.toolName === 'Bash' && typeof input.command === 'string') {\n return input.command\n }\n\n // Everything else: return full input\n return input\n}\n","/**\n * RunState — durable per-run state stored in state.json.\n *\n * Lives alongside transcript shards and snapshot.json:\n * projects/{runId}/nodes/{nodeId}/state.json\n *\n * Enables:\n * - Async run tracking (getStatus, waitFor)\n * - Crash recovery (detect orphaned running runs via stale heartbeat)\n * - Webhook delivery history (retry tracking)\n * - Full response persistence (data + meta + errors) — getStatus returns\n * the same shape as sync engine.run()\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { EngineResponse } from './response.js'\nimport type { TokenUsage } from './types.js'\n\n// ---------- types ----------\n\nexport type RunStatus = 'queued' | 'running' | 'paused' | 'done' | 'failed' | 'cancelled'\n\nexport interface RunProgress {\n readonly turns: number\n readonly tokensUsed: TokenUsage\n readonly currentActivity: 'idle' | 'streaming' | 'tool_dispatch' | 'compacting'\n readonly lastTool?: string\n}\n\nexport type WebhookEvent = 'paused' | 'done' | 'failed'\n\nexport interface WebhookDelivery {\n readonly id: string\n readonly event: WebhookEvent\n readonly attempt: number\n readonly scheduledAt: number\n readonly deliveredAt?: number\n readonly status: 'pending' | 'delivered' | 'failed'\n readonly httpCode?: number\n readonly error?: string\n}\n\nexport interface WebhookConfig {\n readonly url: string\n readonly events: readonly WebhookEvent[]\n readonly secret?: string\n readonly headers?: Readonly<Record<string, string>>\n readonly deliveries: readonly WebhookDelivery[]\n}\n\nexport interface RunState {\n readonly version: 1\n readonly runId: string\n readonly nodeId: string\n readonly status: RunStatus\n readonly startedAt: number\n readonly lastHeartbeat: number\n readonly progress: RunProgress\n readonly response: EngineResponse | null\n readonly webhook?: WebhookConfig\n}\n\n// ---------- manager ----------\n\n/**\n * Reads, writes, and updates state.json files via the storage adapter.\n * Concurrent writes are NOT synchronized — callers are responsible for\n * serializing updates (in practice: only one process writes per run).\n */\nexport class RunStateManager {\n constructor(private readonly storage: StorageAdapter) {}\n\n private path(runId: string, nodeId: string): string {\n return `projects/${runId}/nodes/${nodeId}/state.json`\n }\n\n async write(state: RunState): Promise<void> {\n const content = JSON.stringify(state, null, 2)\n await this.storage.writeFile(this.path(state.runId, state.nodeId), content)\n }\n\n async read(runId: string, nodeId: string): Promise<RunState | null> {\n try {\n const content = await this.storage.readFile(this.path(runId, nodeId))\n if (content === null) return null\n return JSON.parse(content) as RunState\n } catch {\n return null\n }\n }\n\n /**\n * Merge patch into current state and write back. Returns the new state.\n * If no state exists, throws — use `write()` for initial creation.\n */\n async update(runId: string, nodeId: string, patch: Partial<RunState>): Promise<RunState> {\n const current = await this.read(runId, nodeId)\n if (current === null) {\n throw new Error(`RunStateManager.update: no state found for ${runId}/${nodeId}`)\n }\n const next: RunState = { ...current, ...patch }\n await this.write(next)\n return next\n }\n\n /**\n * Update just the heartbeat + progress (cheap, called every turn).\n */\n async heartbeat(runId: string, nodeId: string, progress: Partial<RunProgress>): Promise<void> {\n const current = await this.read(runId, nodeId)\n if (current === null) return\n const next: RunState = {\n ...current,\n lastHeartbeat: Date.now(),\n progress: { ...current.progress, ...progress },\n }\n await this.write(next)\n }\n\n /**\n * Mark terminal state with response. Used at end of run/resume.\n */\n async finalize(runId: string, nodeId: string, response: EngineResponse): Promise<RunState> {\n return this.update(runId, nodeId, {\n status:\n response.status === 'done' ? 'done' : response.status === 'paused' ? 'paused' : 'failed',\n lastHeartbeat: Date.now(),\n response,\n })\n }\n\n /**\n * List all state files under a runId (one per node). Returns empty array\n * if the runId directory doesn't exist.\n */\n async scanRun(runId: string): Promise<RunState[]> {\n const nodesDir = `projects/${runId}/nodes`\n try {\n const nodeNames = await this.storage.listDir(nodesDir)\n const states: RunState[] = []\n for (const name of nodeNames) {\n const state = await this.read(runId, name)\n if (state !== null) states.push(state)\n }\n return states\n } catch {\n return []\n }\n }\n\n /**\n * Scan all state files and return those with stale heartbeats.\n * Used by recoverOrphanedRuns().\n */\n async findOrphaned(staleThresholdMs: number): Promise<RunState[]> {\n const projectsRoot = 'projects'\n const orphaned: RunState[] = []\n const now = Date.now()\n try {\n const runIds = await this.storage.listDir(projectsRoot)\n for (const runId of runIds) {\n const states = await this.scanRun(runId)\n for (const state of states) {\n if (state.status === 'running' && now - state.lastHeartbeat > staleThresholdMs) {\n orphaned.push(state)\n }\n }\n }\n } catch {\n // projects/ doesn't exist yet — no runs to recover\n }\n return orphaned\n }\n\n /** Helper to build a fresh state for a new run. */\n static initial(runId: string, nodeId: string, webhook?: WebhookConfig): RunState {\n const now = Date.now()\n return {\n version: 1,\n runId,\n nodeId,\n status: 'queued',\n startedAt: now,\n lastHeartbeat: now,\n progress: {\n turns: 0,\n tokensUsed: { input: 0, output: 0 },\n currentActivity: 'idle',\n },\n response: null,\n ...(webhook !== undefined ? { webhook } : {}),\n }\n }\n}\n","/**\n * BackgroundExecutor — abstracts how async runs are dispatched.\n *\n * Node.js: NodeBackgroundExecutor uses `void Promise` fire-and-forget.\n * Cloudflare Workers: user provides a DurableObjectExecutor (Worker-side\n * code that dispatches to a DO with a longer execution budget).\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\n/**\n * Contract for async run dispatch. Engine calls `schedule()` with a work\n * function; executor is responsible for running it eventually.\n */\nexport interface BackgroundExecutor {\n /**\n * Schedule a work function to run in the background. Must return\n * immediately — the function will be invoked asynchronously.\n *\n * The returned AbortSignal fires if `cancel(runId)` is called.\n * Work functions should pass this to agentLoop for early termination.\n */\n schedule(runId: string, work: (signal: AbortSignal) => Promise<void>): void\n\n /**\n * Cancel a scheduled/running execution. Fires the AbortSignal so the\n * work function can exit gracefully.\n */\n cancel(runId: string): Promise<void>\n\n /** True if this executor is currently tracking a run. */\n isActive(runId: string): boolean\n}\n\n/**\n * Default Node.js implementation — fire-and-forget via `void` Promise.\n * Works in Node, Bun, Deno. Does NOT work on Cloudflare Workers because\n * the Worker instance terminates when the request handler returns.\n */\nexport class NodeBackgroundExecutor implements BackgroundExecutor {\n private readonly running = new Map<string, AbortController>()\n\n schedule(runId: string, work: (signal: AbortSignal) => Promise<void>): void {\n if (this.running.has(runId)) {\n // Already running — abort the old one before starting a new\n this.running.get(runId)!.abort()\n }\n const ctl = new AbortController()\n this.running.set(runId, ctl)\n\n void work(ctl.signal)\n .catch((err) => {\n // Background errors are logged via state.json updates in the engine.\n // Last-resort: log to stderr so it's not completely silent.\n if (typeof console !== 'undefined') {\n console.error(`[la-machina/engine] Background run ${runId} threw:`, err)\n }\n })\n .finally(() => {\n this.running.delete(runId)\n })\n }\n\n async cancel(runId: string): Promise<void> {\n const ctl = this.running.get(runId)\n if (ctl !== undefined) {\n ctl.abort()\n this.running.delete(runId)\n }\n }\n\n isActive(runId: string): boolean {\n return this.running.has(runId)\n }\n\n /** For tests/observability — current count of running tasks. */\n size(): number {\n return this.running.size\n }\n}\n","/**\n * WebhookDispatcher — delivers status changes to client URLs.\n *\n * Features:\n * - HMAC-SHA256 signing via Web Crypto API (works everywhere)\n * - Exponential backoff retries: 10s → 60s → 5min → 30min → give up\n * - HTTP 4xx → no retry (client bug); 5xx/network → retry\n * - HTTP 410 Gone → give up immediately (resource deliberately removed)\n * - Delivery tracking: each attempt recorded in state.json\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\nimport type { EngineResponse } from './response.js'\nimport type { WebhookDelivery, WebhookEvent } from './state.js'\n\n// ---------- retry schedule ----------\n\n/** Milliseconds to wait before attempt N (1-indexed). */\nexport const RETRY_DELAYS_MS = [\n 0, // attempt 1: immediate\n 10_000, // attempt 2: 10s after failure\n 60_000, // attempt 3: 60s after failure\n 5 * 60_000, // attempt 4: 5min after failure\n 30 * 60_000, // attempt 5: 30min after failure\n] as const\n\nexport const MAX_ATTEMPTS = RETRY_DELAYS_MS.length\n\n// ---------- HMAC signing ----------\n\n/**\n * Sign a webhook payload with HMAC-SHA256 using Web Crypto API.\n * Returns the full header value: `sha256=<hex>`.\n */\nexport async function signPayload(\n secret: string,\n timestamp: number,\n body: string,\n): Promise<string> {\n const data = `${timestamp}.${body}`\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, new TextEncoder().encode(data))\n const hex = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return `sha256=${hex}`\n}\n\n// ---------- retryability ----------\n\nfunction isRetryableHttpStatus(code: number): boolean {\n if (code === 410) return false // Gone — give up permanently\n if (code >= 500 && code < 600) return true // 5xx server errors\n if (code === 408) return true // Request Timeout\n if (code === 429) return true // Rate limited\n // Other 4xx → no retry (client bug in payload/auth)\n return false\n}\n\n// ---------- dispatcher ----------\n\nexport interface DeliverOptions {\n readonly url: string\n readonly event: WebhookEvent\n readonly payload: EngineResponse\n readonly secret?: string\n readonly headers?: Readonly<Record<string, string>>\n readonly attempt?: number\n readonly deliveryId?: string\n readonly timeoutMs?: number\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport interface DeliverResult {\n readonly delivery: WebhookDelivery\n readonly shouldRetry: boolean\n readonly nextRetryDelayMs?: number\n}\n\nexport class WebhookDispatcher {\n constructor(\n private readonly fetchImpl: typeof globalThis.fetch = globalThis.fetch.bind(globalThis),\n ) {}\n\n /**\n * Attempt one delivery. Returns a delivery record and whether to retry.\n */\n async deliver(options: DeliverOptions): Promise<DeliverResult> {\n const attempt = options.attempt ?? 1\n const deliveryId = options.deliveryId ?? randomUUID()\n const scheduledAt = Date.now()\n const timestamp = scheduledAt\n const body = JSON.stringify(options.payload)\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-LaMachina-Event': `status.${options.event}`,\n 'X-LaMachina-RunId': options.payload.runId,\n 'X-LaMachina-Delivery': deliveryId,\n 'X-LaMachina-Timestamp': String(timestamp),\n ...(options.headers ?? {}),\n }\n\n if (options.secret !== undefined && options.secret.length > 0) {\n headers['X-LaMachina-Signature'] = await signPayload(options.secret, timestamp, body)\n }\n\n const controller = new AbortController()\n const timeout = options.timeoutMs ?? 30_000\n const timer = setTimeout(() => controller.abort(), timeout)\n\n const fetchImpl = options.fetch ?? this.fetchImpl\n\n try {\n const response = await fetchImpl(options.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n })\n\n const delivery: WebhookDelivery = {\n id: deliveryId,\n event: options.event,\n attempt,\n scheduledAt,\n deliveredAt: Date.now(),\n status: response.ok ? 'delivered' : 'failed',\n httpCode: response.status,\n ...(response.ok ? {} : { error: `HTTP ${response.status}` }),\n }\n\n if (response.ok) {\n return { delivery, shouldRetry: false }\n }\n\n const shouldRetry = attempt < MAX_ATTEMPTS && isRetryableHttpStatus(response.status)\n return {\n delivery,\n shouldRetry,\n ...(shouldRetry ? { nextRetryDelayMs: RETRY_DELAYS_MS[attempt] ?? 0 } : {}),\n }\n } catch (err) {\n // Network error, timeout, etc. — retry if attempts remain.\n const errorMsg = err instanceof Error ? err.message : String(err)\n const delivery: WebhookDelivery = {\n id: deliveryId,\n event: options.event,\n attempt,\n scheduledAt,\n deliveredAt: Date.now(),\n status: 'failed',\n error: errorMsg,\n }\n const shouldRetry = attempt < MAX_ATTEMPTS\n return {\n delivery,\n shouldRetry,\n ...(shouldRetry ? { nextRetryDelayMs: RETRY_DELAYS_MS[attempt] ?? 0 } : {}),\n }\n } finally {\n clearTimeout(timer)\n }\n }\n}\n"],"mappings":"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","names":["z","path","z","json","text","runAgent","path","failed","z","z","z","text","path","text","text","inputSchema","text","isSubagentPausedError","z","z","createFetchDataTool","inputSchema","z","spawn","result","t","z","inputSchema","z","inputSchema","z","inputSchema","path","z","inputSchema","path","base64","z","inputSchema","path","z","inputSchema","z","picomatch","z","inputSchema","z","picomatch","z","inputSchema","MAX_OUTPUT_BYTES","text","html","path","z","inputSchema","html","text","htmlToText","z","inputSchema","z","inputSchema","z","inputSchema","text","z","inputSchema","z","inputSchema","z","text","safeText","parsed","inputSchema","z","z","picomatch","text","text","SAFE_NAME","zodToJsonSchema","jsonSchema","tryParseJSON","text","z","SAFE_NAME","inputSchema","z","inputSchema","byteLength","raw","path","z","text","byteLength","text","inputSchema","z","cached","z","inputSchema","z","loadIndex","cached","path","SAFE_NAME","path","SAFE_NAME","DEFAULT_TIMEOUT_MS","cached","text","path","path","tryParseJSON","resolveAuth"]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/tools/contract.ts","../src/tools/fetchData.ts","../src/orchestrator/types.ts","../src/orchestrator/planParser.ts","../src/orchestrator/agentPrompts.ts","../src/orchestrator/phases.ts","../src/orchestrator/retry.ts","../src/orchestrator/snapshot.ts","../src/orchestrator/synthesize.ts","../src/orchestrator/orchestrate.ts","../src/index.ts","../src/config/merge.ts","../src/config/defaults.ts","../src/config/schema.ts","../src/engine/engine.ts","../src/model/factory.ts","../src/api/providerSelector.ts","../src/engine/errors.ts","../src/model/anthropicAdapter.ts","../src/api/anthropicClient.ts","../src/api/betaHeaders.ts","../src/api/streaming.ts","../src/model/aiSdkAdapter.ts","../src/model/messageConverter.ts","../src/model/toolConverter.ts","../src/runtime/detect.ts","../src/tools/capabilityStub.ts","../src/subagent/registry.ts","../src/runtime/uuid.ts","../src/tools/agent.ts","../src/subagent/runner.ts","../src/engine/agentLoop.ts","../src/transcript/snapshot.ts","../src/engine/toolResultOffload.ts","../src/engine/toolResultSummarizer.ts","../src/hooks/dispatch.ts","../src/engine/normalizeMessages.ts","../src/compact/compactor.ts","../src/compact/dropMiddle.ts","../src/compact/microcompact.ts","../src/compact/summarize.ts","../src/compact/prompt.ts","../src/engine/streamingExecutor.ts","../src/engine/runContext.ts","../src/engine/toolRuntime.ts","../src/transcript/writer.ts","../src/transcript/entries.ts","../src/transcript/meta.ts","../src/subagent/fork.ts","../src/tools/bash.ts","../src/tools/sendMessage.ts","../src/tools/fileEdit.ts","../src/tools/fileRead.ts","../src/tools/fileWrite.ts","../src/tools/glob.ts","../src/tools/walkAdapter.ts","../src/tools/grep.ts","../src/tools/webFetch.ts","../src/tools/fileTracker.ts","../src/tools/webSearch.ts","../src/tools/sleep.ts","../src/tools/toolSearch.ts","../src/tools/memorize.ts","../src/tools/recall.ts","../src/tools/notebookEdit.ts","../src/tools/tasks/store.ts","../src/tools/tasks/tools.ts","../src/logging/logger.ts","../src/agents/loader.ts","../src/coordinator/mode.ts","../src/coordinator/prompt.ts","../src/mcp/manager.ts","../src/mcp/client.ts","../src/mcp/bindingTransport.ts","../src/mcp/errors.ts","../src/mcp/toolAdapter.ts","../src/mcp/sampling.ts","../src/permissions/evaluator.ts","../src/permissions/allowlist.ts","../src/permissions/rules.ts","../src/memory/memoryConfig.ts","../src/memory/episodes.ts","../src/memory/hippocampus.ts","../src/prompts/systemPrompt.ts","../src/skills/loader.ts","../src/prompts/sections/base.ts","../src/prompts/sections/doingTasks.ts","../src/prompts/sections/actions.ts","../src/prompts/sections/usingTools.ts","../src/prompts/sections/toneAndStyle.ts","../src/prompts/sections/environment.ts","../src/prompts/sections/mcp.ts","../src/engine/jsonOutput.ts","../src/skills/skillPage.ts","../src/tools/apiCall.ts","../src/tools/searchKnowledge.ts","../src/knowledge/indexer.ts","../src/knowledge/tokenize.ts","../src/knowledge/scope.ts","../src/tools/readKnowledge.ts","../src/knowledge/extractors.ts","../src/skills/storageSkillSource.ts","../src/skills/inlineSkillSource.ts","../src/storage/factory.ts","../src/storage/interface.ts","../src/storage/localAdapter.ts","../src/storage/pathSafety.ts","../src/storage/r2Adapter.ts","../src/storage/r2BindingAdapter.ts","../src/transcript/reader.ts","../src/engine/rehydrate.ts","../src/engine/response.ts","../src/engine/state.ts","../src/engine/executor.ts","../src/engine/webhook.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Tool contract — the shape every tool implements, plus a registry to\n * collect them by name.\n *\n * The contract is intentionally minimal:\n *\n * 1. A tool has a `name`, a `description`, and a Zod `inputSchema`.\n * Zod gives both runtime validation and a TypeScript-inferred\n * input type for `execute()`.\n * 2. `execute(input, context)` returns a `ToolResult` (or rejects).\n * The runtime catches rejections and turns them into error\n * results — a misbehaving tool can never crash the agent loop.\n * 3. The runtime supplies a `ToolContext` carrying at least an\n * `AbortSignal` for cancellation.\n *\n * Phase 5 ships the types and the registry. Phase 6 fills the registry\n * with the core tool set (Bash, Read, Write, Edit, Glob, Grep, WebFetch).\n * Custom tools come from `config.tools.custom` at engine init time.\n */\n\nimport type { z } from 'zod'\n\n/**\n * The execution context passed to every tool. Phase 5 keeps this\n * minimal — only an AbortSignal — so the contract stays portable.\n * Later phases extend with storage, run/node ids, hook handles, etc.\n */\nexport interface ToolContext {\n readonly signal: AbortSignal\n}\n\n/**\n * The result of a single tool invocation. The runtime wraps thrown\n * errors in this shape so the agent loop only ever sees success/error\n * as data, not exceptions.\n */\nexport interface ToolResult {\n /** Human- and model-readable output. The agent's next turn sees this. */\n readonly content: string\n /** True when the tool failed. */\n readonly isError?: boolean\n /** Optional structured metadata for hooks / observability. */\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\n/**\n * A tool definition. Generic on a Zod schema so that `execute()`'s\n * input parameter is statically typed via `z.infer<TSchema>`.\n *\n * Tool authors normally use `defineTool()` to get the inference\n * without writing the generic by hand.\n */\nexport interface Tool<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {\n readonly name: string\n readonly description: string\n readonly inputSchema: TSchema\n /**\n * Optional raw JSON Schema to send to the Anthropic API as\n * `input_schema`, bypassing Zod-to-JSON-Schema conversion. Used by\n * MCP-sourced tools whose schema is authored in JSON Schema directly\n * and whose Zod schema is a `z.unknown()` passthrough.\n *\n * When set, `toAnthropicTool()` in the agent loop prefers this over\n * running `zodToJsonSchema(inputSchema)`. Normal in-process tools\n * defined via `defineTool()` should leave this undefined.\n */\n readonly anthropicSchemaOverride?: Record<string, unknown>\n /**\n * Returns true if this tool is safe to run concurrently with other\n * concurrency-safe tools. Read-only tools (Read, Glob, Grep, etc.)\n * should return true; mutating tools (Write, Edit, Bash) should\n * return false. Default: false (fail-closed).\n *\n * The agent loop uses this to batch consecutive safe tool calls\n * into a single `Promise.all()` for parallel execution, while\n * running unsafe tools serially.\n *\n * Input is typed as `unknown` (not `z.infer<TSchema>`) so that\n * `Tool<ZodObject<...>>` remains assignable to `Tool<ZodTypeAny>`\n * under `exactOptionalPropertyTypes`.\n */\n isConcurrencySafe?: ((input: unknown) => boolean) | undefined\n /**\n * Declares that this tool needs Node-only capabilities\n * (`node:child_process`, the real filesystem, stdio-based MCP, etc.)\n * When true AND the runtime can't support them, the engine replaces\n * this tool with a capability stub (see `src/tools/capabilityStub.ts`)\n * that returns a structured `isError` result instead of crashing.\n *\n * Leave undefined / false for tools that work anywhere (Read, Write,\n * WebFetch, http-based MCP). Default: false.\n */\n readonly requiresNode?: boolean\n /**\n * Internal marker set by `capabilityStub()` so the agent-loop's\n * runner-handoff check (Plan 019 §4) can distinguish a stubbed tool\n * from a real one without reflecting on the implementation.\n * Do not set this manually.\n */\n readonly isCapabilityStub?: boolean\n execute(input: z.infer<TSchema>, context: ToolContext): Promise<ToolResult>\n}\n\n/**\n * Identity helper that locks in the schema generic so callers don't have\n * to write it. Use this whenever defining a tool — it costs nothing at\n * runtime and gives you full inference inside `execute()`.\n *\n * @example\n * ```ts\n * const Echo = defineTool({\n * name: 'Echo',\n * description: 'Echoes its input back',\n * inputSchema: z.object({ msg: z.string() }),\n * execute: async ({ msg }) => ({ content: msg }),\n * })\n * ```\n */\nexport function defineTool<TSchema extends z.ZodTypeAny>(tool: Tool<TSchema>): Tool<TSchema> {\n return tool\n}\n\n/**\n * In-memory registry of tools by name. Used by the engine's tool runtime\n * to dispatch tool calls. Re-registering the same name throws so typos\n * surface immediately rather than silently shadowing.\n */\nexport class ToolRegistry {\n private readonly tools = new Map<string, Tool>()\n\n register(tool: Tool): void {\n if (typeof tool.name !== 'string' || tool.name.length === 0) {\n throw new Error('ToolRegistry: tool.name must be a non-empty string')\n }\n if (this.tools.has(tool.name)) {\n throw new Error(`ToolRegistry: \"${tool.name}\" is already registered`)\n }\n this.tools.set(tool.name, tool)\n }\n\n registerAll(tools: ReadonlyArray<Tool>): void {\n for (const tool of tools) this.register(tool)\n }\n\n unregister(name: string): void {\n this.tools.delete(name)\n }\n\n get(name: string): Tool | undefined {\n return this.tools.get(name)\n }\n\n has(name: string): boolean {\n return this.tools.has(name)\n }\n\n list(): Tool[] {\n return Array.from(this.tools.values())\n }\n\n count(): number {\n return this.tools.size\n }\n}\n","/**\n * FetchData — built-in tool that rehydrates an offloaded tool result\n * (Plan 021).\n *\n * When offload is enabled, large tool results get stored under the\n * current agent's log path (`{logPath}/toolResults/{ref}.json`) and\n * replaced in the model's context with a short summary + a `ref`\n * token. If the model needs the full payload it calls:\n *\n * FetchData({ ref: \"tu_abc\" })\n *\n * and this tool reads the blob back. Each agent gets its own\n * `FetchData` instance bound to the agent's own log path — a\n * subagent can't reach the parent's blobs and vice versa.\n *\n * Safety rails:\n * - `ref` must match `/^[a-zA-Z0-9_-]+$/` — tool_use IDs fit, path-\n * traversal attempts (`../`, absolute paths, slashes) don't.\n * - Missing ref → `isError: true` with a clear message.\n * - Path is computed server-side from the caller's logPath; the\n * model only supplies the ref.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\n\nconst SAFE_REF = /^[a-zA-Z0-9_-]+$/\n\nexport interface CreateFetchDataToolOptions {\n readonly storage: StorageAdapter\n /**\n * This agent's log path, e.g. `projects/{runId}/nodes/{nodeId}`\n * for the top-level run, or\n * `projects/{runId}/nodes/{nodeId}/subagents/{agentId}` for a\n * subagent. The tool reads `{logPath}/toolResults/{ref}.json`.\n */\n readonly logPath: string\n}\n\nconst inputSchema = z.object({\n ref: z.string().min(1),\n})\n\nexport function createFetchDataTool(opts: CreateFetchDataToolOptions): Tool {\n return defineTool({\n name: 'FetchData',\n description:\n 'Fetch the full content of a tool result that was offloaded because it ' +\n 'was too large for the main context. Pass the `ref` token from the ' +\n 'summarized tool_result message (the text that looked like ' +\n '\\'Use FetchData with ref=\"...\"\\'). Returns the raw bytes of the original ' +\n 'tool output.',\n inputSchema,\n execute: async ({ ref }) => {\n if (!SAFE_REF.test(ref)) {\n return {\n content: `ERR_OFFLOAD_INVALID_REF: ref \"${ref}\" contains unsafe characters`,\n isError: true,\n }\n }\n const path = `${opts.logPath}/toolResults/${ref}.json`\n const raw = await opts.storage.readFile(path)\n if (raw === null) {\n return {\n content: `ERR_OFFLOAD_REF_NOT_FOUND: no data found for ref \"${ref}\"`,\n isError: true,\n }\n }\n return {\n content: raw,\n isError: false,\n metadata: { ref, bytes: raw.length },\n }\n },\n })\n}\n","/**\n * Orchestrator types — plan schema, step results, retry policy,\n * orchestrator config, and the public OrchestratorResult.\n */\n\nimport { z } from 'zod'\nimport type { TokenUsage } from '../api/streaming.js'\n\n// ---------- Plan schema ----------\n\nexport const PlanStepSchema = z.object({\n id: z.string().min(1),\n description: z.string().min(1),\n action: z.enum(['research', 'implement', 'verify', 'review', 'custom']),\n files: z.array(z.string()).optional(),\n spec: z.string().optional(),\n dependsOn: z.array(z.string()).optional(),\n})\n\nexport const PlanSchema = z.object({\n summary: z.string().min(1),\n steps: z.array(PlanStepSchema).min(1),\n})\n\nexport type PlanStep = z.infer<typeof PlanStepSchema>\nexport type Plan = z.infer<typeof PlanSchema>\n\n// ---------- Step results ----------\n\nexport type StepStatus = 'done' | 'failed' | 'skipped' | 'reverted'\n\nexport interface StepResult {\n readonly stepId: string\n readonly action: string\n readonly status: StepStatus\n readonly output?: string | undefined\n readonly error?: string | undefined\n readonly attempts: number\n readonly agentId?: string | undefined\n}\n\n// ---------- File snapshots ----------\n\nexport interface FileSnapshot {\n readonly path: string\n /** null = file didn't exist before (delete on revert). */\n readonly content: string | null\n}\n\n// ---------- Retry policy ----------\n\nexport interface RetryPolicy {\n readonly maxAttempts: number\n readonly backoffMs: number\n readonly onExhausted: 'revert' | 'skip' | 'fail'\n}\n\nexport interface ResolvedRetryPolicies {\n readonly plan: RetryPolicy\n readonly research: RetryPolicy\n readonly implement: RetryPolicy\n readonly verify: RetryPolicy\n readonly review: RetryPolicy\n}\n\n// ---------- Orchestrator config ----------\n\nexport interface ResolvedOrchestratorConfig {\n readonly enabled: boolean\n readonly retries: ResolvedRetryPolicies\n readonly maxParallelResearchers: number\n readonly enableReview: boolean\n readonly enableRollback: boolean\n readonly maxPlanSteps: number\n /** Max turns per internal agent run (planner, researcher, implementer, verifier). Default: 15. */\n readonly agentMaxTurns: number\n}\n\n// ---------- Orchestrator result ----------\n\nexport interface OrchestratorResult {\n readonly status: 'done' | 'partial' | 'failed'\n readonly output: string\n readonly plan: Plan | null\n readonly steps: readonly StepResult[]\n readonly tokensUsed: TokenUsage\n readonly agentRuns: number\n readonly reverted: readonly string[]\n readonly durationMs: number\n}\n\n// ---------- Orchestrate options (public API) ----------\n\nexport interface OrchestrateOptions {\n readonly runId: string\n readonly nodeId: string\n readonly task: string\n /** Optional pre-built plan — skip the Planner agent. */\n readonly plan?: Plan | undefined\n}\n","/**\n * Plan parser — extract and validate a JSON plan from LLM output.\n *\n * The Planner agent may wrap JSON in markdown fences, include preamble\n * text, or produce slightly malformed JSON. This parser is tolerant:\n * 1. Strips markdown ```json ... ``` fences\n * 2. Finds the first { ... } block in the text\n * 3. Parses as JSON\n * 4. Validates against PlanSchema with Zod\n */\n\nimport { PlanSchema, type Plan } from './types.js'\n\n/**\n * Extract a valid Plan from raw LLM output. Returns null if the output\n * can't be parsed into a valid plan.\n */\nexport function parsePlan(raw: string, maxSteps: number): Plan | null {\n const json = extractJson(raw)\n if (json === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(json)\n } catch {\n return null\n }\n\n const result = PlanSchema.safeParse(parsed)\n if (!result.success) return null\n\n const plan = result.data\n if (plan.steps.length > maxSteps) return null\n\n return plan\n}\n\n/**\n * Find the first top-level JSON object in a string. Handles markdown\n * fences and leading/trailing text.\n */\nfunction extractJson(text: string): string | null {\n // Try stripping markdown fences first.\n const fenceMatch = text.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?```/)\n if (fenceMatch?.[1]) {\n const inner = fenceMatch[1].trim()\n if (inner.startsWith('{')) return inner\n }\n\n // Find the first { ... } block by tracking brace depth.\n let start = -1\n let depth = 0\n for (let i = 0; i < text.length; i++) {\n const c = text[i]\n if (c === '{') {\n if (depth === 0) start = i\n depth++\n } else if (c === '}') {\n depth--\n if (depth === 0 && start !== -1) {\n return text.slice(start, i + 1)\n }\n }\n }\n\n return null\n}\n","/**\n * System prompts for each orchestrator agent role.\n * Static strings — no LLM generates them.\n */\n\nexport const PLANNER_PROMPT = `You are a planning agent. Your job is to decompose a task into executable steps.\n\nOutput a JSON object with this EXACT shape:\n{\n \"summary\": \"one-line task summary\",\n \"steps\": [\n {\n \"id\": \"step-1\",\n \"description\": \"what this step does\",\n \"action\": \"research|implement|verify|review\",\n \"files\": [\"src/file.ts\"],\n \"dependsOn\": []\n }\n ]\n}\n\nRules:\n- Actions: \"research\" (read-only investigation), \"implement\" (code changes), \"verify\" (test/validate), \"review\" (optional code review)\n- Every \"implement\" step MUST be followed by a \"verify\" step that depends on it\n- Research steps with no dependencies can run in parallel — use this for speed\n- Keep steps focused — one concern per step\n- Include specific file paths in the \"files\" field when known\n- \"dependsOn\" lists step IDs that must complete before this step starts\n- Do NOT implement anything — only plan\n\nOutput ONLY the JSON object. No explanation, no markdown fences, no preamble.`\n\nexport const RESEARCHER_PROMPT = `You are a research agent. Investigate the given question thoroughly.\n\nRules:\n- Do NOT modify any files. Read-only investigation.\n- Report specific file paths, line numbers, type signatures, and code snippets\n- Be thorough — anything you don't report will be lost\n- If you can't find something, say so explicitly\n- Structure your findings clearly with headers and bullet points`\n\nexport const IMPLEMENTER_PROMPT = `You are an implementation agent. Execute the given specification exactly.\n\nRules:\n- Make the minimum changes needed to satisfy the spec\n- Read files before editing them\n- After making changes, verify they compile/work if possible\n- Report: which files you changed, what you changed, and the result\n- If you encounter errors, report them with full details — do not skip\n- Do not add features or improvements beyond what the spec asks for\n- Commit your changes if the spec asks for it`\n\nexport const VERIFIER_PROMPT = `You are a verification agent. Prove that recent changes work correctly.\n\nRules:\n- Run tests if available. Report pass/fail with output.\n- Check for type errors, syntax errors, import errors\n- Try edge cases — don't just verify the happy path\n- Be skeptical — if something looks wrong, investigate\n- Do NOT rubber-stamp. If you can't verify, say so.\n- Your output MUST include a clear verdict: PASS or FAIL\n- If FAIL, include the specific error and what needs fixing`\n\nexport const REVIEWER_PROMPT = `You are a code review agent. Review recent changes for quality and correctness.\n\nReview for:\n- Correctness: does the code do what it should?\n- Security: any injection, XSS, auth bypass, or data exposure?\n- Quality: naming, structure, unnecessary complexity?\n- Edge cases: what happens with empty input, null, large data?\n\nReport findings as bullet points. Be specific — include file paths and line numbers.\nIf no issues found, say \"No issues found\" explicitly.`\n\nexport const FINALIZER_PROMPT = `You are a reporting agent. Assemble a final report from the workflow results.\n\nInclude:\n1. What was the original task\n2. What steps were executed and their outcomes\n3. What succeeded and what failed\n4. Any files that were reverted (rolled back)\n5. Key decisions made during execution\n6. Recommended next steps (if any)\n\nBe concise but complete. Use bullet points for lists.\nIf there were failures, explain what went wrong and suggest fixes.\nSave key decisions and learnings using the Memorize tool.`\n","/**\n * Phase runners — each function spawns one agent role via engine.run()\n * and returns the result. The orchestrator calls these in sequence\n * according to the plan.\n *\n * Each phase:\n * 1. Builds a RunOptions with the role-specific system prompt\n * 2. Calls engine.run() (isolated context, isolated transcript)\n * 3. Extracts the relevant output\n * 4. Returns it to the orchestrator\n *\n * All phases are pure async functions — no platform dependencies.\n */\n\nimport type { Engine } from '../engine/engine.js'\nimport type { EngineResponse } from '../engine/response.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { parsePlan } from './planParser.js'\nimport type { Plan, PlanStep, StepResult } from './types.js'\nimport {\n PLANNER_PROMPT,\n RESEARCHER_PROMPT,\n IMPLEMENTER_PROMPT,\n VERIFIER_PROMPT,\n REVIEWER_PROMPT,\n FINALIZER_PROMPT,\n} from './agentPrompts.js'\n\n/** Aggregate token usage tracker + per-phase maxTurns. */\nexport class TokenTracker {\n input = 0\n output = 0\n runs = 0\n /** Max turns each internal agent run is allowed. */\n maxTurns: number = 15\n\n add(usage: TokenUsage): void {\n this.input += usage.input\n this.output += usage.output\n this.runs++\n }\n\n get total(): TokenUsage {\n return { input: this.input, output: this.output }\n }\n}\n\n// ---------- Planner ----------\n\nexport async function runPlanner(\n engine: Engine,\n task: string,\n runId: string,\n maxSteps: number,\n tracker: TokenTracker,\n): Promise<Plan | null> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: 'planner',\n task: `Plan the following task:\\n\\n${task}`,\n systemOverride: PLANNER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n if (result.status !== 'done') return null\n return parsePlan(\n result.meta.output ?? (typeof result.data === 'string' ? result.data : ''),\n maxSteps,\n )\n}\n\n// ---------- Researcher ----------\n\nexport async function runResearcher(\n engine: Engine,\n step: PlanStep,\n runId: string,\n index: number,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `research-${step.id}-${index}`,\n task:\n step.description + (step.files?.length ? `\\n\\nFocus on files: ${step.files.join(', ')}` : ''),\n systemOverride: RESEARCHER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'research',\n status: result.status === 'done' ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: result.status === 'failed' ? (result.errors[0]?.message ?? 'unknown') : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Implementer ----------\n\nexport async function runImplementer(\n engine: Engine,\n spec: string,\n step: PlanStep,\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `implement-${step.id}`,\n task: spec,\n systemOverride: IMPLEMENTER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'implement',\n status: result.status === 'done' ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: result.status === 'failed' ? (result.errors[0]?.message ?? 'unknown') : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Verifier ----------\n\nexport async function runVerifier(\n engine: Engine,\n step: PlanStep,\n implResult: StepResult,\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const task = [\n `Verify the following changes:\\n`,\n step.description,\n implResult.output ? `\\n\\nImplementation result:\\n${implResult.output}` : '',\n step.files?.length ? `\\n\\nFiles involved: ${step.files.join(', ')}` : '',\n `\\n\\nRun tests if available. Report PASS or FAIL with details.`,\n ].join('')\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `verify-${step.id}`,\n task,\n systemOverride: VERIFIER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n const passed =\n result.status === 'done' &&\n /\\bPASS\\b/i.test(result.meta.output ?? (typeof result.data === 'string' ? result.data : '')) &&\n !/\\bFAIL\\b/i.test(result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n\n return {\n stepId: step.id,\n action: 'verify',\n status: passed ? 'done' : 'failed',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n error: !passed\n ? result.status === 'failed'\n ? (result.errors[0]?.message ?? 'unknown')\n : 'Verification failed'\n : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Reviewer ----------\n\nexport async function runReviewer(\n engine: Engine,\n step: PlanStep,\n allResults: readonly StepResult[],\n runId: string,\n tracker: TokenTracker,\n): Promise<StepResult> {\n const implResults = allResults\n .filter((r) => r.action === 'implement' && r.status === 'done')\n .map((r) => r.output)\n .join('\\n\\n')\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: `review-${step.id}`,\n task: `Review the following changes:\\n\\n${implResults}`,\n systemOverride: REVIEWER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return {\n stepId: step.id,\n action: 'review',\n status: result.status === 'done' ? 'done' : 'skipped',\n output:\n result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : undefined,\n attempts: 1,\n }\n}\n\n// ---------- Finalizer ----------\n\nexport async function runFinalizer(\n engine: Engine,\n task: string,\n results: readonly StepResult[],\n reverted: readonly string[],\n runId: string,\n tracker: TokenTracker,\n): Promise<string> {\n const summary = results\n .map(\n (r) =>\n `- [${r.status.toUpperCase()}] ${r.stepId} (${r.action}): ${r.output?.slice(0, 200) ?? r.error ?? 'no output'}`,\n )\n .join('\\n')\n\n const revertedList = reverted.length > 0 ? `\\n\\nReverted files: ${reverted.join(', ')}` : ''\n\n const result = await runAgent(engine, {\n maxTurns: tracker.maxTurns,\n runId,\n nodeId: 'finalizer',\n task: `Original task: ${task}\\n\\nStep results:\\n${summary}${revertedList}\\n\\nAssemble a final report.`,\n systemOverride: FINALIZER_PROMPT,\n })\n\n tracker.add(getTokens(result))\n\n return result.status === 'done'\n ? (result.meta.output ?? (typeof result.data === 'string' ? result.data : ''))\n : `Orchestration completed with issues. ${results.filter((r) => r.status === 'failed').length} step(s) failed.`\n}\n\n// ---------- Helpers ----------\n\ninterface AgentRunOptions {\n runId: string\n nodeId: string\n task: string\n systemOverride: string\n maxTurns?: number\n}\n\nasync function runAgent(engine: Engine, options: AgentRunOptions): Promise<EngineResponse> {\n const task = `${options.systemOverride}\\n\\n---\\n\\n${options.task}`\n return engine.run({\n runId: options.runId,\n nodeId: options.nodeId,\n task,\n ...(options.maxTurns !== undefined ? { maxTurns: options.maxTurns } : {}),\n })\n}\n\nfunction getTokens(result: EngineResponse): TokenUsage {\n return result.meta.tokensUsed ?? { input: 0, output: 0 }\n}\n","/**\n * Generic retry-with-backoff wrapper. Pure JS — no platform APIs\n * beyond setTimeout.\n */\n\nimport type { RetryPolicy } from './types.js'\n\nexport interface RetryResult<T> {\n readonly success: boolean\n readonly value?: T\n readonly error?: string\n readonly attempts: number\n}\n\n/**\n * Execute `fn` up to `policy.maxAttempts` times with exponential backoff.\n * Returns the first successful result or the last error.\n */\nexport async function runWithRetry<T>(\n fn: () => Promise<T>,\n policy: RetryPolicy,\n): Promise<RetryResult<T>> {\n let lastError = ''\n\n for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {\n try {\n const value = await fn()\n return { success: true, value, attempts: attempt }\n } catch (err) {\n lastError = err instanceof Error ? err.message : String(err)\n\n // Don't backoff after the last attempt.\n if (attempt < policy.maxAttempts && policy.backoffMs > 0) {\n const delay = policy.backoffMs * Math.pow(2, attempt - 1)\n await sleep(delay)\n }\n }\n }\n\n return { success: false, error: lastError, attempts: policy.maxAttempts }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(resolve, ms)\n if (typeof timer.unref === 'function') timer.unref()\n })\n}\n","/**\n * File snapshot + restore — rollback mechanism for implementation failures.\n * Operates through the StorageAdapter abstraction — works on both\n * local filesystem and R2.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { FileSnapshot } from './types.js'\n\n/**\n * Read and store the current content of a list of files. Files that\n * don't exist get `content: null` — restoring them will delete the file\n * (reversing a create).\n */\nexport async function snapshotFiles(\n storage: StorageAdapter,\n paths: readonly string[],\n): Promise<FileSnapshot[]> {\n return Promise.all(\n paths.map(async (path) => {\n const content = await storage.readFile(path)\n return { path, content }\n }),\n )\n}\n\n/**\n * Restore files to their snapshotted state. Files that didn't exist\n * (content === null) are deleted. Files that existed are overwritten\n * with their original content.\n */\nexport async function restoreSnapshot(\n storage: StorageAdapter,\n snapshots: readonly FileSnapshot[],\n): Promise<string[]> {\n const reverted: string[] = []\n for (const snap of snapshots) {\n try {\n if (snap.content === null) {\n await storage.deleteFile(snap.path)\n } else {\n await storage.writeFile(snap.path, snap.content)\n }\n reverted.push(snap.path)\n } catch {\n // Best-effort restore — don't crash the orchestrator.\n }\n }\n return reverted\n}\n","/**\n * Synthesize — combine research findings into an implementation spec.\n *\n * This is CODE, not an LLM call. It takes the research step results\n * for a given implementation step and produces a combined spec string\n * that the Implementer agent receives as its task.\n *\n * The synthesis is deliberately simple: concatenate research findings\n * with the step's description and any file paths. The Implementer\n * LLM does the actual reasoning — the synthesizer just assembles context.\n */\n\nimport type { PlanStep, StepResult } from './types.js'\n\n/**\n * Build an implementation spec from the step's description, prior\n * research results, and file list.\n */\nexport function synthesizeSpec(step: PlanStep, allResults: readonly StepResult[]): string {\n const parts: string[] = []\n\n parts.push(`## Task\\n${step.description}`)\n\n // Include relevant research findings.\n const deps = new Set(step.dependsOn ?? [])\n const researchResults = allResults.filter(\n (r) => deps.has(r.stepId) && r.status === 'done' && r.output,\n )\n\n if (researchResults.length > 0) {\n parts.push('## Research Findings')\n for (const r of researchResults) {\n parts.push(`### ${r.stepId}\\n${r.output}`)\n }\n }\n\n // Include file list if specified.\n if (step.files && step.files.length > 0) {\n parts.push(`## Files\\n${step.files.map((f) => `- ${f}`).join('\\n')}`)\n }\n\n // Include the explicit spec if provided.\n if (step.spec) {\n parts.push(`## Spec\\n${step.spec}`)\n }\n\n return parts.join('\\n\\n')\n}\n","/**\n * Orchestrate — the main state machine.\n *\n * Pure JS. No platform APIs. Calls engine.run() internally for each\n * agent phase. Enforces retry policies, file snapshots for rollback,\n * dependency ordering, and parallel research execution.\n *\n * Flow:\n * 1. Plan — Planner agent produces a JSON plan (or use caller-supplied plan)\n * 2. Execute — for each step in dependency order:\n * - research: spawn N researchers in parallel\n * - implement: synthesize spec from research → run implementer with retry\n * - verify: run verifier → on fail, retry implementer or revert\n * - review: optional code review\n * 3. Finalize — Finalizer agent assembles the report\n * 4. Return — OrchestratorResult with full provenance\n */\n\nimport type { Engine } from '../engine/engine.js'\nimport type { Logger } from '../logging/logger.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport {\n runPlanner,\n runResearcher,\n runImplementer,\n runVerifier,\n runReviewer,\n runFinalizer,\n TokenTracker,\n} from './phases.js'\nimport { runWithRetry } from './retry.js'\nimport { snapshotFiles, restoreSnapshot } from './snapshot.js'\nimport { synthesizeSpec } from './synthesize.js'\nimport type {\n OrchestrateOptions,\n OrchestratorResult,\n Plan,\n PlanStep,\n ResolvedOrchestratorConfig,\n StepResult,\n} from './types.js'\n\n/**\n * Execute a structured orchestration. This is the internal implementation\n * called by engine.orchestrate().\n */\nexport async function orchestrate(\n engine: Engine,\n options: OrchestrateOptions,\n config: ResolvedOrchestratorConfig,\n storage: StorageAdapter,\n logger: Logger,\n): Promise<OrchestratorResult> {\n const start = Date.now()\n const tracker = new TokenTracker()\n tracker.maxTurns = config.agentMaxTurns\n const results: StepResult[] = []\n const allReverted: string[] = []\n\n logger.info('orchestrator.start', { runId: options.runId, task: options.task.slice(0, 100) })\n\n // ── Phase 1: Plan ──\n\n let plan: Plan | null = options.plan ?? null\n\n if (plan === null) {\n const planRetry = await runWithRetry(async () => {\n const p = await runPlanner(engine, options.task, options.runId, config.maxPlanSteps, tracker)\n if (p === null) throw new Error('Planner produced invalid plan')\n return p\n }, config.retries.plan)\n\n if (planRetry.success && planRetry.value) {\n plan = planRetry.value\n logger.info('orchestrator.plan', {\n summary: plan.summary,\n steps: plan.steps.length,\n })\n } else {\n logger.warn('orchestrator.plan failed, using single-step fallback', {\n error: planRetry.error,\n })\n // Fallback: single implementation step\n plan = {\n summary: options.task,\n steps: [{ id: 'fallback', description: options.task, action: 'implement' }],\n }\n }\n }\n\n // ── Phase 2: Execute steps in dependency order ──\n\n const completed = new Set<string>()\n const sorted = topologicalSort(plan.steps)\n\n for (const step of sorted) {\n // Wait for dependencies (already completed in topo order).\n const depsReady = (step.dependsOn ?? []).every((d) => completed.has(d))\n if (!depsReady) {\n // Dependency failed — skip this step.\n const failedDep = (step.dependsOn ?? []).find(\n (d) => results.find((r) => r.stepId === d)?.status === 'failed',\n )\n if (failedDep) {\n results.push({\n stepId: step.id,\n action: step.action,\n status: 'skipped',\n error: `Dependency \"${failedDep}\" failed`,\n attempts: 0,\n })\n logger.info('orchestrator.step skipped', {\n stepId: step.id,\n reason: `dep ${failedDep} failed`,\n })\n continue\n }\n }\n\n logger.info('orchestrator.step start', { stepId: step.id, action: step.action })\n\n switch (step.action) {\n case 'research': {\n const stepResult = await executeResearch(\n engine,\n step,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n\n case 'implement': {\n const stepResult = await executeImplement(\n engine,\n step,\n results,\n config,\n options.runId,\n storage,\n tracker,\n logger,\n allReverted,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n\n case 'verify': {\n const implStep = (step.dependsOn ?? [])\n .map((id) => results.find((r) => r.stepId === id))\n .find((r) => r?.action === 'implement')\n\n if (!implStep || implStep.status !== 'done') {\n results.push({\n stepId: step.id,\n action: 'verify',\n status: 'skipped',\n error: 'No implementation to verify',\n attempts: 0,\n })\n } else {\n const stepResult = await executeVerify(\n engine,\n step,\n implStep,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n }\n break\n }\n\n case 'review': {\n if (!config.enableReview) {\n results.push({\n stepId: step.id,\n action: 'review',\n status: 'skipped',\n error: 'Review disabled in config',\n attempts: 0,\n })\n } else {\n const review = await runReviewer(engine, step, results, options.runId, tracker)\n results.push(review)\n completed.add(step.id)\n }\n break\n }\n\n case 'custom':\n default: {\n // Custom steps are treated as research (read-only).\n const stepResult = await executeResearch(\n engine,\n step,\n config,\n options.runId,\n tracker,\n logger,\n )\n results.push(stepResult)\n if (stepResult.status === 'done') completed.add(step.id)\n break\n }\n }\n\n logger.info('orchestrator.step end', {\n stepId: step.id,\n status: results[results.length - 1]?.status,\n })\n }\n\n // ── Phase 3: Finalize ──\n\n const report = await runFinalizer(\n engine,\n options.task,\n results,\n allReverted,\n options.runId,\n tracker,\n )\n\n const allDone = results.every((r) => r.status === 'done' || r.status === 'skipped')\n const anyFailed = results.some((r) => r.status === 'failed' || r.status === 'reverted')\n const status = allDone ? 'done' : anyFailed ? 'partial' : 'done'\n\n logger.info('orchestrator.done', {\n status,\n steps: results.length,\n done: results.filter((r) => r.status === 'done').length,\n failed: results.filter((r) => r.status === 'failed').length,\n reverted: allReverted.length,\n agentRuns: tracker.runs,\n })\n\n return {\n status,\n output: report,\n plan,\n steps: results,\n tokensUsed: tracker.total,\n agentRuns: tracker.runs,\n reverted: allReverted,\n durationMs: Date.now() - start,\n }\n}\n\n// ---------- Phase executors ----------\n\nasync function executeResearch(\n engine: Engine,\n step: PlanStep,\n config: ResolvedOrchestratorConfig,\n runId: string,\n tracker: TokenTracker,\n _logger: Logger,\n): Promise<StepResult> {\n const retryResult = await runWithRetry(async () => {\n // Launch parallel researchers (up to maxParallelResearchers).\n const count = config.maxParallelResearchers\n const researchers = Array.from({ length: count }, (_, i) =>\n runResearcher(engine, step, runId, i, tracker),\n )\n const results = await Promise.all(researchers)\n const failed = results.filter((r) => r.status === 'failed')\n if (failed.length === results.length) throw new Error('All researchers failed')\n\n // Combine findings from successful researchers.\n const findings = results\n .filter((r) => r.status === 'done' && r.output)\n .map((r) => r.output!)\n .join('\\n\\n---\\n\\n')\n\n return findings\n }, config.retries.research)\n\n return {\n stepId: step.id,\n action: 'research',\n status: retryResult.success\n ? 'done'\n : config.retries.research.onExhausted === 'skip'\n ? 'skipped'\n : 'failed',\n output: retryResult.value,\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\nasync function executeImplement(\n engine: Engine,\n step: PlanStep,\n allResults: readonly StepResult[],\n config: ResolvedOrchestratorConfig,\n runId: string,\n storage: StorageAdapter,\n tracker: TokenTracker,\n logger: Logger,\n allReverted: string[],\n): Promise<StepResult> {\n // Snapshot files for rollback.\n const filePaths = step.files ?? []\n const snapshots =\n config.enableRollback && filePaths.length > 0 ? await snapshotFiles(storage, filePaths) : []\n\n // Synthesize spec from prior results.\n const spec = synthesizeSpec(step, allResults)\n\n const retryResult = await runWithRetry(async () => {\n const result = await runImplementer(engine, spec, step, runId, tracker)\n if (result.status === 'failed') throw new Error(result.error ?? 'Implementation failed')\n return result\n }, config.retries.implement)\n\n if (retryResult.success && retryResult.value) {\n return { ...retryResult.value, attempts: retryResult.attempts }\n }\n\n // Failed after retries — revert if enabled.\n if (config.enableRollback && snapshots.length > 0) {\n const reverted = await restoreSnapshot(storage, snapshots)\n allReverted.push(...reverted)\n logger.warn('orchestrator.revert', { stepId: step.id, files: reverted })\n return {\n stepId: step.id,\n action: 'implement',\n status: 'reverted',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n }\n\n return {\n stepId: step.id,\n action: 'implement',\n status: 'failed',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\nasync function executeVerify(\n engine: Engine,\n step: PlanStep,\n implResult: StepResult,\n config: ResolvedOrchestratorConfig,\n runId: string,\n tracker: TokenTracker,\n _logger: Logger,\n): Promise<StepResult> {\n const retryResult = await runWithRetry(async () => {\n const result = await runVerifier(engine, step, implResult, runId, tracker)\n if (result.status === 'failed') throw new Error(result.error ?? 'Verification failed')\n return result\n }, config.retries.verify)\n\n if (retryResult.success && retryResult.value) {\n return { ...retryResult.value, attempts: retryResult.attempts }\n }\n\n return {\n stepId: step.id,\n action: 'verify',\n status: 'failed',\n error: retryResult.error,\n attempts: retryResult.attempts,\n }\n}\n\n// ---------- Topological sort ----------\n\nfunction topologicalSort(steps: readonly PlanStep[]): PlanStep[] {\n const byId = new Map(steps.map((s) => [s.id, s]))\n const visited = new Set<string>()\n const sorted: PlanStep[] = []\n\n function visit(step: PlanStep): void {\n if (visited.has(step.id)) return\n visited.add(step.id)\n for (const dep of step.dependsOn ?? []) {\n const depStep = byId.get(dep)\n if (depStep) visit(depStep)\n }\n sorted.push(step)\n }\n\n for (const step of steps) visit(step)\n return sorted\n}\n","/**\n * la-machina-engine — public API.\n *\n * The single entry point is `initEngine()`. Every config option has a\n * default; `initEngine()` with no arguments must work, so long as either\n * `config.model.apiKey` is set OR `ANTHROPIC_API_KEY` is in the environment.\n *\n * See plans/002-la-machina-engine.md for the full spec.\n */\n\nimport { mergeConfig } from './config/merge.js'\nimport type { ResolvedConfig, UserConfig } from './config/types.js'\nimport { Engine } from './engine/engine.js'\nimport { ConfigError } from './engine/errors.js'\n\n// ---------- model adapter ----------\nexport type {\n ModelAdapter,\n NormalizedEvent,\n StreamRequest,\n ModelToolDefinition,\n ModelMessage,\n} from './model/adapter.js'\nexport { AnthropicAdapter } from './model/anthropicAdapter.js'\nexport { AISdkAdapter } from './model/aiSdkAdapter.js'\nexport { createModelAdapter } from './model/factory.js'\n\n// ---------- engine surface ----------\nexport { Engine } from './engine/engine.js'\nexport type {\n StartOptions,\n ResumeAsyncOptions,\n WaitForOptions,\n WebhookOptions,\n EngineInternals,\n} from './engine/engine.js'\nexport { RunStateManager } from './engine/state.js'\nexport type {\n RunState,\n RunStatus,\n RunProgress,\n WebhookEvent,\n WebhookConfig,\n WebhookDelivery,\n} from './engine/state.js'\nexport { NodeBackgroundExecutor } from './engine/executor.js'\nexport type { BackgroundExecutor } from './engine/executor.js'\nexport { WebhookDispatcher, signPayload, RETRY_DELAYS_MS, MAX_ATTEMPTS } from './engine/webhook.js'\nexport {\n ApiError,\n AuthError,\n ConfigError,\n EngineError,\n NotImplementedError,\n RateLimitError,\n RunTimeoutError,\n StreamIncompleteError,\n StreamParseError,\n} from './engine/errors.js'\nexport type {\n PauseReason,\n ResumeOptions,\n RunOptions,\n RunResult,\n RunSnapshot,\n TokenUsage,\n TranscriptLocation,\n} from './engine/types.js'\n\n// ---------- config types ----------\nexport type {\n FlushPolicy,\n GateBeforeToolHook,\n LogEntry,\n LogLevel,\n LogSink,\n MemoryMode,\n MemoryScope,\n ModelProvider,\n PostRunHook,\n PostToolCallHook,\n PostTurnHook,\n PreRunHook,\n PreToolCallHook,\n PreTurnHook,\n ResolvedAgentsConfig,\n ResolvedConfig,\n ResolvedExecutionConfig,\n ResolvedHooksConfig,\n ResolvedLoggingConfig,\n ResolvedMemoryConfig,\n ResolvedModelConfig,\n ResolvedR2Config,\n ResolvedRunnerConfig,\n ResolvedSkillsConfig,\n ResolvedStorageConfig,\n ResolvedToolsConfig,\n ResolvedTranscriptConfig,\n StorageProvider,\n UserConfig,\n} from './config/types.js'\n\n// ---------- hook event payloads ----------\nexport type {\n GateDecision,\n PostRunEvent,\n PostToolCallEvent,\n PostTurnEvent,\n PreRunEvent,\n PreToolCallEvent,\n PreTurnEvent,\n StopHook,\n StopHookEvent,\n StopHookResult,\n} from './hooks/types.js'\n\n// ---------- tool contract (for custom tools) ----------\nexport { ToolRegistry, defineTool } from './tools/contract.js'\nexport { capabilityStub, withCapabilityCheck } from './tools/capabilityStub.js'\n\n// ---------- tool-result offload (Plan 021) ----------\nexport { createFetchDataTool } from './tools/fetchData.js'\nexport type { CreateFetchDataToolOptions } from './tools/fetchData.js'\nexport { defaultToolResultSummarizer } from './engine/toolResultSummarizer.js'\nexport type {\n ToolResultOffloadConfigV1,\n ToolResultSummarizerV1,\n ToolResultSummarizerCtxV1,\n ResolvedToolResultOffloadConfigV1,\n} from './engine/toolResultOffload.types.js'\nexport type { Tool, ToolContext, ToolResult } from './tools/contract.js'\n\n// ---------- unified response ----------\nexport { toResponse } from './engine/response.js'\nexport type { EngineResponse, ResponseError, ResponseMeta } from './engine/response.js'\n\n// ---------- structured output ----------\nexport { tryParseJSON, buildSchemaPrompt, validateOutput } from './engine/jsonOutput.js'\n\n// ---------- tool batching ----------\nexport { partitionToolCalls } from './engine/agentLoop.js'\nexport type { LoopProgress } from './engine/agentLoop.js'\nexport { StreamingToolExecutor } from './engine/streamingExecutor.js'\n\n// ---------- SendMessage (inter-agent communication) ----------\nexport { createSendMessageTool } from './tools/sendMessage.js'\n\n// ---------- subagent registry ----------\nexport { SubagentRegistry } from './subagent/registry.js'\nexport { isInForkChild, buildForkedMessages } from './subagent/fork.js'\nexport type {\n BackgroundAgentResult,\n SerializedAgent,\n SpawnResult,\n SubagentRegistryOptions,\n} from './subagent/registry.js'\n\n// ---------- storage adapter (for custom backends) ----------\nexport { LocalStorageAdapter } from './storage/localAdapter.js'\nexport { R2StorageAdapter } from './storage/r2Adapter.js'\nexport { R2BindingStorageAdapter } from './storage/r2BindingAdapter.js'\nexport type { R2BucketBinding } from './storage/r2BindingAdapter.js'\nexport { StorageError } from './storage/interface.js'\nexport type { EngineStorage, FileStat, StorageAdapter } from './storage/interface.js'\nexport type { R2ClientConfig } from './storage/r2Adapter.js'\n\n// ---------- transcript (for custom readers) ----------\nexport type { Entry } from './transcript/entries.js'\nexport type { TranscriptMeta, TranscriptStatus } from './transcript/meta.js'\n\n// ---------- memory (for callers that want direct access) ----------\nexport { Hippocampus } from './memory/hippocampus.js'\nexport { EpisodicMemory } from './memory/episodes.js'\nexport { createSmartMemory } from './memory/memoryConfig.js'\nexport type { SmartMemory, SmartMemoryConfig } from './memory/memoryConfig.js'\nexport type {\n Engram,\n EngramConfidence,\n EngramKind,\n EngramScope,\n EngramSource,\n Episode,\n} from './memory/types.js'\n\n// ---------- skills (for caller-driven discovery) ----------\nexport { loadSkills } from './skills/loader.js'\nexport type { LoadedSkill } from './skills/loader.js'\nexport { createSkillPageTool } from './skills/skillPage.js'\nexport type {\n SkillSource,\n ResolvedSkill,\n SkillOverride,\n SkillPageOverride,\n} from './skills/source.js'\nexport { StorageSkillSource } from './skills/storageSkillSource.js'\nexport { InlineSkillSource } from './skills/inlineSkillSource.js'\n\n// ---------- Knowledge (Plan 023) ----------\nexport { writeKnowledgeIndex, buildKnowledgeIndex } from './knowledge/indexer.js'\nexport { createSearchKnowledgeTool } from './tools/searchKnowledge.js'\nexport type { CreateSearchKnowledgeToolOptions } from './tools/searchKnowledge.js'\nexport { createReadKnowledgeTool } from './tools/readKnowledge.js'\nexport type { CreateReadKnowledgeToolOptions } from './tools/readKnowledge.js'\nexport { getExtractor } from './knowledge/extractors.js'\nexport type { KnowledgeExtractorV1 } from './knowledge/extractors.js'\nexport type {\n KnowledgeFolderRefV1,\n KnowledgeExternalLinkV1,\n KnowledgeFormatV1,\n KnowledgeConfigV1,\n ResolvedKnowledgeConfigV1,\n RunKnowledgeOptionsV1,\n SectionEntryV1,\n FileMetaV1,\n KnowledgeIndexV1,\n} from './knowledge/types.js'\n\n// ---------- ApiCall (Plan 020) ----------\nexport { createApiCallTool } from './tools/apiCall.js'\nexport type { CreateApiCallToolOptions } from './tools/apiCall.js'\nexport type {\n ApiHttpMethodV1,\n ApiAuthV1,\n ApiServiceV1,\n ApiResolverCtxV1,\n ApiAuthResolverV1,\n ApiRequestEventV1,\n ApiResponseEventV1,\n ResolvedApiConfigV1,\n} from './tools/apiCall.types.js'\nexport type { ResolvedApiConfig } from './config/types.js'\n\n// ---------- runtime detection ----------\nexport { detectRuntime, canSpawnProcesses, hasProcessLifecycle } from './runtime/detect.js'\nexport type { RuntimeKind } from './runtime/detect.js'\n\n// ---------- orchestrator ----------\nexport { orchestrate } from './orchestrator/orchestrate.js'\nexport { parsePlan } from './orchestrator/planParser.js'\nexport { runWithRetry } from './orchestrator/retry.js'\nexport { snapshotFiles, restoreSnapshot } from './orchestrator/snapshot.js'\nexport { synthesizeSpec } from './orchestrator/synthesize.js'\nexport type {\n OrchestrateOptions,\n OrchestratorResult,\n Plan,\n PlanStep,\n StepResult,\n StepStatus,\n FileSnapshot,\n RetryPolicy,\n ResolvedOrchestratorConfig,\n} from './orchestrator/types.js'\nexport { PlanSchema, PlanStepSchema } from './orchestrator/types.js'\n\n// ---------- agents (for caller-driven custom agent loading) ----------\nexport { loadAgents } from './agents/loader.js'\nexport type { AgentDefinition } from './tools/agent.js'\n\n// ---------- coordinator ----------\nexport {\n isCoordinatorMode,\n buildWorkerAgent,\n getCoordinatorBasePrompt,\n} from './coordinator/mode.js'\nexport { getCoordinatorSystemPrompt } from './coordinator/prompt.js'\nexport type { ResolvedCoordinatorConfig } from './coordinator/types.js'\n\n// ---------- mcp (caller-driven access to the Model Context Protocol) ----------\nexport { McpClient } from './mcp/client.js'\nexport { BindingHttpTransport } from './mcp/bindingTransport.js'\nexport { McpManager } from './mcp/manager.js'\nexport { defaultSamplingHandler, DEFAULT_SAMPLING_MAX_DEPTH } from './mcp/sampling.js'\nexport type {\n SamplingHandler,\n SamplingRequest,\n SamplingResponse,\n SamplingMessage,\n SamplingTextBlock,\n SamplingContext,\n SamplingModelPreferences,\n} from './mcp/sampling.js'\nexport type { McpInstructionDelta } from './mcp/manager.js'\nexport { McpConnectionError, McpProtocolError, McpTimeoutError } from './mcp/errors.js'\nexport { adaptMcpTool, mcpToolName } from './mcp/toolAdapter.js'\nexport type {\n McpCallResult,\n McpServerState,\n McpToolDef,\n ResolvedMcpConfig,\n ResolvedMcpHttpServerConfig,\n ResolvedMcpServerConfig,\n ResolvedMcpSseServerConfig,\n ResolvedMcpStdioServerConfig,\n} from './mcp/types.js'\n\n// ---------- system prompt builder ----------\nexport { buildSystemPrompt } from './prompts/systemPrompt.js'\nexport type { BuildSystemPromptOptions } from './prompts/systemPrompt.js'\n\n// ---------- logging ----------\nexport { createLogger } from './logging/logger.js'\nexport type { Logger } from './logging/logger.js'\n\n// ---------- permissions ----------\nexport { buildPermissionPolicy } from './permissions/evaluator.js'\nexport type { PermissionPolicy } from './permissions/evaluator.js'\nexport { SAFE_TOOL_ALLOWLIST, isSafeTool } from './permissions/allowlist.js'\nexport { parseRule, parseRules, matchesRule } from './permissions/rules.js'\nexport type {\n PermissionAction,\n PermissionDecision,\n PermissionMode,\n PermissionRule,\n ResolvedPermissionsConfig,\n} from './permissions/types.js'\n\nexport const ENGINE_VERSION = '0.0.0'\n\n/**\n * Initialize an Engine with (optional) user config merged over defaults.\n *\n * @param user Partial config. Every field is optional.\n * @returns A fully-configured Engine ready to `run()` (once Phase 7 lands).\n * @throws {ConfigError} If config validation fails or `apiKey` cannot be\n * resolved from either `config.model.apiKey` or `ANTHROPIC_API_KEY` env.\n */\nexport function initEngine(user: UserConfig = {}): Engine {\n // `mergeConfig` only throws ZodError (subclass of Error), so `.message`\n // is always defined. If a future refactor introduces non-Error throws,\n // the type-check on `err` below would need widening.\n let resolved: ResolvedConfig\n try {\n resolved = mergeConfig(user)\n } catch (err) {\n throw new ConfigError(`Invalid config: ${(err as Error).message}`)\n }\n\n resolved = resolveApiKey(resolved)\n\n return new Engine(resolved)\n}\n\n/**\n * Resolve `model.apiKey` with env-var fallback. If both are missing, throw.\n */\nfunction resolveApiKey(config: ResolvedConfig): ResolvedConfig {\n if (config.model.apiKey !== '') return config\n\n const fromEnv = process.env.ANTHROPIC_API_KEY\n if (fromEnv !== undefined && fromEnv !== '') {\n return {\n ...config,\n model: { ...config.model, apiKey: fromEnv },\n }\n }\n\n throw new ConfigError(\n 'apiKey is required. Set `config.model.apiKey` or the ANTHROPIC_API_KEY environment variable.',\n )\n}\n","/**\n * Deep-merge user config over DEFAULTS with three rules:\n *\n * 1. Plain objects merge recursively (deep merge).\n * 2. Arrays REPLACE — if the user provides `tools.enabled = ['Read']`, the\n * result is `['Read']`, not `['*', 'Read']`. Empty arrays are honored.\n * 3. `undefined` in the override preserves the default. Explicit falsy\n * values (`0`, `false`, `''`) are honored.\n *\n * The user config is validated by `UserConfigSchema` before merge. The\n * merged result is validated by `ResolvedConfigSchema` after merge, so both\n * input and output shape are guaranteed correct.\n *\n * The DEFAULTS object is never mutated; every merge returns a fresh object.\n *\n * Clone strategy — `deepClone` below — matters because user config can\n * contain:\n * - Hook functions (`hooks.preRun: [fn]`)\n * - Tool definitions (`tools.custom: [{ name, execute, inputSchema }]`)\n * - Zod schemas nested inside those tool definitions\n * - Logger callables (`logging.sink: fn`)\n *\n * None of those are cloneable via `structuredClone`. We deep-copy plain\n * objects and arrays (so callers get a fresh shell), but share references\n * for functions, Zod schemas, and any non-plain object. That gives us\n * isolation from caller-side mutation of the containers while preserving\n * the identity of the callable values the engine actually needs to invoke.\n */\n\nimport { DEFAULTS } from './defaults.js'\nimport { ResolvedConfigSchema, UserConfigSchema } from './schema.js'\nimport type { ResolvedConfig, UserConfig } from './types.js'\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value === null || typeof value !== 'object') return false\n return Object.getPrototypeOf(value) === Object.prototype\n}\n\n/**\n * Deep-clone a value:\n * - primitives (including functions and symbols) → return as-is\n * - plain objects → new object with recursively cloned entries\n * - arrays → new array with recursively cloned elements\n * - non-plain objects (Zod schemas, class instances, Buffers, …) → shared\n *\n * Sharing non-plain objects is deliberate. Zod schemas, tool definitions\n * produced by `defineTool`, and the like carry behavior that `structuredClone`\n * cannot reproduce. Plain-object containers are still fresh, so mutation by\n * the caller after `initEngine()` cannot affect the engine's internal config.\n */\nfunction deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) {\n return value.map((v) => deepClone(v)) as unknown as T\n }\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value)) {\n out[k] = deepClone(v)\n }\n return out as T\n }\n // Non-plain object: Zod schema, class instance, Buffer, Date, etc.\n // Share the reference — the caller owns it and the engine only reads it.\n return value\n}\n\nfunction deepMerge<T>(base: T, override: Record<string, unknown>): T {\n const baseObj = base as unknown as Record<string, unknown>\n // Caller contract: both arguments are plain objects. The top-level call\n // passes DEFAULTS + validated user config (both objects), and recursion\n // only fires inside an `isPlainObject && isPlainObject` guard below, so\n // we never recurse into a primitive or array.\n\n const result: Record<string, unknown> = {}\n const keys = new Set<string>([...Object.keys(baseObj), ...Object.keys(override)])\n\n for (const key of keys) {\n const baseValue = baseObj[key]\n const overrideValue = override[key]\n\n if (overrideValue === undefined) {\n result[key] = deepClone(baseValue)\n continue\n }\n if (Array.isArray(overrideValue)) {\n result[key] = deepClone(overrideValue)\n continue\n }\n if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {\n result[key] = deepMerge(baseValue, overrideValue)\n continue\n }\n result[key] = deepClone(overrideValue)\n }\n\n return result as T\n}\n\n/**\n * Runtime-only fields on `api` that must not flow through the Zod\n * schema (Plan 020). Holding credentials + callbacks in a shape the\n * schema validates would risk them surfacing through serialization;\n * we split them out before validation and re-attach after.\n */\nconst API_RUNTIME_KEYS = ['env', 'resolveAuth', 'onRequest', 'onResponse'] as const\n\nfunction splitApiRuntime(user: UserConfig): {\n stripped: UserConfig\n runtime: Partial<Record<(typeof API_RUNTIME_KEYS)[number], unknown>>\n} {\n const api = (user as { api?: Record<string, unknown> }).api\n if (api === undefined) return { stripped: user, runtime: {} }\n const runtime: Partial<Record<(typeof API_RUNTIME_KEYS)[number], unknown>> = {}\n const schemaSafe: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(api)) {\n if ((API_RUNTIME_KEYS as readonly string[]).includes(k)) {\n runtime[k as (typeof API_RUNTIME_KEYS)[number]] = v\n } else {\n schemaSafe[k] = v\n }\n }\n const clone = { ...user, api: schemaSafe } as UserConfig\n return { stripped: clone, runtime }\n}\n\n/**\n * Merge a (possibly-partial) user config over DEFAULTS, returning a fully\n * resolved config. Throws on schema violation (unknown keys, invalid enum\n * values, numeric invariant failures, cross-field constraint failures).\n */\n/**\n * Plan 022 — coerce the deprecated `memory.scope: 'global'` input\n * value to `'workspace'` with a one-shot warning. Legacy configs\n * keep parsing; the resolved schema only ever sees 'workspace'.\n */\nfunction coerceDeprecatedMemoryScope(user: UserConfig): UserConfig {\n const scope = (user as { memory?: { scope?: string } }).memory?.scope\n if (scope !== 'global') return user\n console.warn(\n '[la-machina] config.memory.scope: \"global\" is deprecated and has ' +\n 'been rewritten to \"workspace\". Cross-tenant memory sharing was ' +\n 'removed in Plan 022 — the workspace is the tenant root. This field ' +\n 'value will be rejected outright in a future major release.',\n )\n const memory = user.memory ?? {}\n return {\n ...user,\n memory: { ...memory, scope: 'workspace' } as UserConfig['memory'],\n }\n}\n\n/**\n * Plan 021 — split the summarizer callback off `compaction.toolResultOffload`\n * before Zod parse (it's function-valued; the schema only validates\n * scalars). Also fills inner-field defaults so users can write\n * `{ enabled: true }` and get sensible values for the rest.\n *\n * Defaults: thresholdBytes=2048, maxPreviewChars=500.\n */\nconst OFFLOAD_DEFAULTS = { thresholdBytes: 2048, maxPreviewChars: 500 } as const\n\nfunction splitOffloadRuntime(user: UserConfig): {\n stripped: UserConfig\n summarizer?: unknown\n} {\n const block = (user as { compaction?: { toolResultOffload?: Record<string, unknown> } })\n .compaction?.toolResultOffload\n if (block === undefined) return { stripped: user }\n const { summarizer, ...schemaSafe } = block\n // Fill defaults for any missing scalar so the resolved schema\n // (which requires all three) accepts the merged config.\n const filled = {\n enabled: schemaSafe.enabled ?? false,\n thresholdBytes: schemaSafe.thresholdBytes ?? OFFLOAD_DEFAULTS.thresholdBytes,\n maxPreviewChars: schemaSafe.maxPreviewChars ?? OFFLOAD_DEFAULTS.maxPreviewChars,\n }\n const clone = {\n ...user,\n compaction: {\n ...(user.compaction ?? {}),\n toolResultOffload: filled,\n },\n } as UserConfig\n return { stripped: clone, summarizer }\n}\n\n/**\n * Plan 023 — fill knowledge config inner defaults so callers can\n * write `{ enabled: true }` and get sensible values for the rest.\n *\n * Defaults: maxSearchResults=5, maxReadBytes=10_000.\n */\nconst KNOWLEDGE_DEFAULTS = { maxSearchResults: 5, maxReadBytes: 10_000 } as const\n\nfunction fillKnowledgeDefaults(user: UserConfig): UserConfig {\n const block = (user as { knowledge?: Record<string, unknown> }).knowledge\n if (block === undefined) return user\n const filled = {\n enabled: block.enabled ?? false,\n maxSearchResults: block.maxSearchResults ?? KNOWLEDGE_DEFAULTS.maxSearchResults,\n maxReadBytes: block.maxReadBytes ?? KNOWLEDGE_DEFAULTS.maxReadBytes,\n }\n return { ...user, knowledge: filled } as UserConfig\n}\n\nexport function mergeConfig(user: UserConfig): ResolvedConfig {\n const withCoercedScope = coerceDeprecatedMemoryScope(user)\n const withKnowledge = fillKnowledgeDefaults(withCoercedScope)\n const { stripped: afterOffload, summarizer } = splitOffloadRuntime(withKnowledge)\n const { stripped, runtime } = splitApiRuntime(afterOffload)\n const validatedUser = UserConfigSchema.parse(stripped)\n const merged = deepMerge(DEFAULTS, validatedUser)\n const resolved = ResolvedConfigSchema.parse(merged) as unknown as ResolvedConfig\n\n // Re-attach runtime-only api fields. Deliberately assigned AFTER\n // Zod validation + structural clone so they never round-trip\n // through the schema. This is the non-persistence guarantee.\n if (resolved.api !== undefined && Object.keys(runtime).length > 0) {\n const mutableResolved = resolved as unknown as { api: Record<string, unknown> }\n mutableResolved.api = {\n ...resolved.api,\n ...runtime,\n }\n } else if (Object.keys(runtime).length > 0) {\n // User supplied ONLY runtime fields (no `services`). That's not a\n // viable config — no tool gets registered. Keep api undefined; the\n // runtime values are discarded.\n }\n\n // Re-attach the offload summarizer callback. Only when the block\n // is present on the resolved config AND a summarizer was stripped.\n if (summarizer !== undefined && resolved.compaction.toolResultOffload !== undefined) {\n const mutable = resolved.compaction as unknown as {\n toolResultOffload: Record<string, unknown>\n }\n mutable.toolResultOffload = {\n ...resolved.compaction.toolResultOffload,\n summarizer,\n }\n }\n return resolved\n}\n","/**\n * Default values for every config option.\n *\n * This file is the single source of truth for \"what zero-config looks like.\"\n * Every default is locked by `test/unit/config/defaults.test.ts` — changing\n * a value here requires updating that test, which forces a deliberate\n * decision instead of silent drift.\n *\n * Notes on specific defaults:\n * - `model.apiKey` is an empty string; `initEngine()` fills it from\n * `ANTHROPIC_API_KEY` at runtime, or throws if neither is set.\n * - `memory.mode` defaults to `'off'` (stateless) — safer for production.\n * - `tools.enabled` is `['*']` meaning all registered tools are on.\n * - `storage.provider` is `'local'` — cloud (R2) is opt-in via config.\n */\n\nimport type { ResolvedConfig } from './types.js'\n\nexport const DEFAULTS: ResolvedConfig = {\n model: {\n provider: 'anthropic',\n modelId: 'claude-opus-4-6',\n apiKey: '',\n baseURL: undefined,\n maxTokens: 8192,\n temperature: 1,\n maxRetries: 2,\n },\n storage: {\n provider: 'local',\n rootPath: '~/.claude',\n workspaceId: 'default',\n r2: undefined,\n },\n memory: {\n mode: 'off',\n scope: 'workspace',\n },\n tools: {\n enabled: ['*'],\n disabled: [],\n custom: [],\n },\n agents: {\n builtins: ['general-purpose'],\n customPath: undefined,\n },\n skills: {\n path: undefined,\n autoload: false,\n },\n execution: {\n maxTurns: 50,\n maxSubagentDepth: 5,\n turnTimeoutMs: 300_000,\n runTimeoutMs: 1_800_000,\n contextLimit: 200_000,\n maxToolConcurrency: 10,\n },\n transcript: {\n enabled: true,\n flushPolicy: 'turn-end',\n idleFlushMs: 2000,\n },\n hooks: {\n preRun: [],\n postRun: [],\n preTurn: [],\n postTurn: [],\n preToolCall: [],\n postToolCall: [],\n gateBeforeTool: undefined,\n stopHooks: [],\n },\n logging: {\n level: 'warn',\n sink: 'stderr',\n },\n mcp: {\n servers: {},\n connectTimeoutMs: 10_000,\n callTimeoutMs: 60_000,\n shutdownTimeoutMs: 5_000,\n },\n permissions: {\n mode: 'open',\n rules: [],\n },\n compaction: {\n strategy: 'auto',\n threshold: 0.85,\n keepLast: 6,\n summaryMaxTokens: 4096,\n microcompact: true,\n microcompactAgeMs: 300_000,\n },\n coordinator: {\n enabled: false,\n workerTools: ['Bash', 'Read', 'Write', 'Edit', 'Glob', 'Grep'],\n maxConcurrentWorkers: 5,\n },\n orchestrator: {\n enabled: false,\n retries: {\n plan: { maxAttempts: 2, backoffMs: 1000, onExhausted: 'fail' as const },\n research: { maxAttempts: 2, backoffMs: 500, onExhausted: 'skip' as const },\n implement: { maxAttempts: 3, backoffMs: 2000, onExhausted: 'revert' as const },\n verify: { maxAttempts: 2, backoffMs: 1000, onExhausted: 'revert' as const },\n review: { maxAttempts: 1, backoffMs: 0, onExhausted: 'skip' as const },\n },\n maxParallelResearchers: 3,\n enableReview: false,\n enableRollback: true,\n maxPlanSteps: 20,\n agentMaxTurns: 15,\n },\n} as const\n","/**\n * Zod schemas for user-supplied and fully-resolved config.\n *\n * Two schemas, matching the two type shapes in `./types.ts`:\n *\n * - `UserConfigSchema` — validates what the caller passes to `initEngine()`.\n * Every field is optional. Unknown keys are `.strict()` rejected.\n *\n * - `ResolvedConfigSchema` — validates the fully-merged internal config.\n * Every field is required. Also enforces cross-field invariants (e.g.\n * `storage.provider === 'r2'` requires `storage.r2` to be present).\n *\n * Numeric invariants:\n * - `maxTurns`, `maxSubagentDepth`, `maxTokens` must be positive integers\n * - `temperature` must be between 0 and 2 inclusive\n * - `turnTimeoutMs`, `runTimeoutMs`, `idleFlushMs` must be non-negative integers\n * - `workspaceId` must match `/^[a-zA-Z0-9_-]+$/` (storage-safe characters)\n */\n\nimport { z } from 'zod'\n\n// ---------- enums ----------\n\nconst ModelProviderEnum = z.enum([\n 'anthropic',\n 'openai',\n 'google',\n 'openai-compatible',\n 'bedrock',\n 'vertex',\n 'proxy',\n])\nconst StorageProviderEnum = z.enum(['local', 'r2', 'r2-binding'])\nconst MemoryModeEnum = z.enum(['off', 'read-only', 'read-write'])\n// Plan 022: user-side enum still accepts 'global' to keep existing\n// configs parsing, but `mergeConfig` emits a deprecation warning\n// and coerces to 'workspace' before the resolved schema sees it.\n// The resolved enum below is narrowed to 'workspace' only.\nconst MemoryScopeUserEnum = z.enum(['workspace', 'global'])\nconst MemoryScopeResolvedEnum = z.enum(['workspace'])\nconst FlushPolicyEnum = z.enum(['turn-end', 'entry', 'manual'])\nconst LogLevelEnum = z.enum(['silent', 'error', 'warn', 'info', 'debug'])\n\n// ---------- resolved sub-schemas ----------\n\nconst R2ConfigResolved = z\n .object({\n bucket: z.string().min(1),\n region: z.string().min(1),\n accessKeyId: z.string().min(1),\n secretAccessKey: z.string().min(1),\n endpoint: z.string().url().optional(),\n })\n .strict()\n\nconst ModelConfigResolved = z\n .object({\n provider: ModelProviderEnum,\n modelId: z.string().min(1),\n apiKey: z.string(),\n baseURL: z.string().url().optional(),\n maxTokens: z.number().int().positive(),\n temperature: z.number().min(0).max(2),\n maxRetries: z.number().int().nonnegative(),\n })\n .strict()\n\n// Shape check for the R2 binding object (env.BUCKET). We don't import\n// @cloudflare/workers-types; a structural check for the methods we use\n// keeps the engine dep-free.\nconst R2BucketBindingShape = z.custom<{\n head: (...args: unknown[]) => unknown\n get: (...args: unknown[]) => unknown\n put: (...args: unknown[]) => unknown\n delete: (...args: unknown[]) => unknown\n list: (...args: unknown[]) => unknown\n}>((val) => {\n if (val === null || typeof val !== 'object') return false\n const o = val as Record<string, unknown>\n return (\n typeof o.head === 'function' &&\n typeof o.get === 'function' &&\n typeof o.put === 'function' &&\n typeof o.delete === 'function' &&\n typeof o.list === 'function'\n )\n}, 'r2Binding must expose head/get/put/delete/list methods')\n\nconst StorageConfigResolved = z\n .object({\n provider: StorageProviderEnum,\n rootPath: z.string().min(1),\n workspaceId: z.string().regex(/^[a-zA-Z0-9_-]+$/, 'workspaceId: only [a-zA-Z0-9_-] allowed'),\n r2: R2ConfigResolved.optional(),\n r2Binding: R2BucketBindingShape.optional(),\n })\n .strict()\n .refine((s) => s.provider !== 'r2' || s.r2 !== undefined, {\n message: 'storage.r2 is required when storage.provider === \"r2\"',\n path: ['r2'],\n })\n .refine((s) => s.provider !== 'r2-binding' || s.r2Binding !== undefined, {\n message: 'storage.r2Binding is required when storage.provider === \"r2-binding\"',\n path: ['r2Binding'],\n })\n\nconst MemoryConfigResolved = z\n .object({\n mode: MemoryModeEnum,\n scope: MemoryScopeResolvedEnum,\n })\n .strict()\n\nconst ToolsConfigResolved = z\n .object({\n enabled: z.array(z.string()),\n disabled: z.array(z.string()),\n custom: z.array(z.unknown()),\n })\n .strict()\n\nconst AgentsConfigResolved = z\n .object({\n builtins: z.array(z.string()),\n customPath: z.string().optional(),\n })\n .strict()\n\nconst SkillsConfigResolved = z\n .object({\n path: z.string().optional(),\n autoload: z.boolean(),\n /**\n * SSRF allowlist for per-run `InlineSkillSource` url fetches\n * (Plan 017). When undefined/empty, any URL is allowed. When set,\n * each fetched URL's host must match an entry exactly or be a\n * subdomain of it.\n */\n allowedHosts: z.array(z.string().min(1)).optional(),\n })\n .strict()\n\nconst ExecutionConfigResolved = z\n .object({\n maxTurns: z.number().int().positive(),\n maxSubagentDepth: z.number().int().positive(),\n turnTimeoutMs: z.number().int().nonnegative(),\n runTimeoutMs: z.number().int().nonnegative(),\n contextLimit: z.number().int().positive(),\n maxToolConcurrency: z.number().int().positive(),\n })\n .strict()\n\nconst TranscriptConfigResolved = z\n .object({\n enabled: z.boolean(),\n flushPolicy: FlushPolicyEnum,\n idleFlushMs: z.number().int().nonnegative(),\n })\n .strict()\n\nconst HooksConfigResolved = z\n .object({\n preRun: z.array(z.function()),\n postRun: z.array(z.function()),\n preTurn: z.array(z.function()),\n postTurn: z.array(z.function()),\n preToolCall: z.array(z.function()),\n postToolCall: z.array(z.function()),\n gateBeforeTool: z.function().optional(),\n /**\n * When true, the parent's gateBeforeTool is threaded into every\n * subagent's inner loop. A gate denial inside a subagent then\n * pauses the parent run with RunSnapshot.pendingSubagent populated.\n * Default: false (subagent tool calls ignore the parent's gate).\n */\n propagateGateToSubagents: z.boolean().optional(),\n stopHooks: z.array(z.function()),\n })\n .strict()\n\n// ---------- MCP schemas ----------\n\nconst McpStdioServerConfigResolved = z\n .object({\n type: z.literal('stdio'),\n command: z.string().min(1, 'command cannot be empty'),\n args: z.array(z.string()).readonly(),\n env: z.record(z.string(), z.string()).optional(),\n cwd: z.string().optional(),\n isolateEnv: z.boolean(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpHttpServerConfigResolved = z\n .object({\n type: z.literal('http'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).optional(),\n preferBindingTransport: z.boolean().optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpSseServerConfigResolved = z\n .object({\n type: z.literal('sse'),\n url: z.string().url(),\n headers: z.record(z.string(), z.string()).optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpServerConfigResolved = z.discriminatedUnion('type', [\n McpStdioServerConfigResolved,\n McpHttpServerConfigResolved,\n McpSseServerConfigResolved,\n])\n\nconst McpConfigResolved = z\n .object({\n servers: z.record(z.string().min(1), McpServerConfigResolved),\n connectTimeoutMs: z.number().int().nonnegative(),\n callTimeoutMs: z.number().int().nonnegative(),\n shutdownTimeoutMs: z.number().int().positive(),\n })\n .strict()\n\n// ---------- permissions schema ----------\n\nconst CompactionStrategyEnum = z.enum(['drop-middle', 'summarize', 'session-memory', 'auto'])\n\n// Plan 021 — tool-result offload. Scalars-only schema; the\n// summarizer callback (function-valued) is stripped out of user\n// config by `mergeConfig` before Zod parse and re-attached on the\n// resolved config afterwards. Structural non-persistence: callbacks\n// never round-trip through the schema.\nconst ToolResultOffloadConfigResolved = z\n .object({\n enabled: z.boolean(),\n thresholdBytes: z.number().int().positive(),\n maxPreviewChars: z.number().int().positive(),\n })\n .strict()\n\nconst CompactionConfigResolved = z\n .object({\n strategy: CompactionStrategyEnum,\n threshold: z.number().min(0).max(1),\n keepLast: z.number().int().positive(),\n summaryMaxTokens: z.number().int().positive(),\n microcompact: z.boolean(),\n microcompactAgeMs: z.number().int().nonnegative(),\n toolResultOffload: ToolResultOffloadConfigResolved.optional(),\n })\n .strict()\n\nconst CoordinatorConfigResolved = z\n .object({\n enabled: z.boolean(),\n workerTools: z.array(z.string()).readonly(),\n maxConcurrentWorkers: z.number().int().positive(),\n })\n .strict()\n\nconst RetryPolicySchema = z\n .object({\n maxAttempts: z.number().int().positive(),\n backoffMs: z.number().int().nonnegative(),\n onExhausted: z.enum(['revert', 'skip', 'fail']),\n })\n .strict()\n\nconst OrchestratorConfigResolved = z\n .object({\n enabled: z.boolean(),\n retries: z\n .object({\n plan: RetryPolicySchema,\n research: RetryPolicySchema,\n implement: RetryPolicySchema,\n verify: RetryPolicySchema,\n review: RetryPolicySchema,\n })\n .strict(),\n maxParallelResearchers: z.number().int().positive(),\n enableReview: z.boolean(),\n enableRollback: z.boolean(),\n maxPlanSteps: z.number().int().positive(),\n agentMaxTurns: z.number().int().positive(),\n })\n .strict()\n\nconst PermissionModeEnum = z.enum(['open', 'rules', 'locked'])\n\nconst PermissionsConfigResolved = z\n .object({\n mode: PermissionModeEnum,\n rules: z.array(z.string()).readonly(),\n })\n .strict()\n\nconst LogSinkSchema = z.union([z.literal('stderr'), z.literal('none'), z.function()])\n\nconst LoggingConfigResolved = z\n .object({\n level: LogLevelEnum,\n sink: LogSinkSchema,\n })\n .strict()\n\n// ---------- ApiCall (Plan 020) ----------\n//\n// We validate only the `services` list + `maxResponseBytes`. Env,\n// `resolveAuth`, `onRequest`, `onResponse` are excluded from the\n// schema — those runtime-only fields live on ResolvedConfig.api but\n// are stripped before we call `ResolvedConfigSchema.parse`. That's\n// the non-persistence guarantee: credentials cannot round-trip\n// through the Zod-validated shape.\n\nconst ApiHttpMethodEnum = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'])\n\nconst ApiAuthSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('none') }).strict(),\n z.object({ type: z.literal('bearer'), tokenRef: z.string().min(1) }).strict(),\n z\n .object({\n type: z.literal('header'),\n name: z.string().min(1),\n valueRef: z.string().min(1),\n })\n .strict(),\n z\n .object({\n type: z.literal('basic'),\n userRef: z.string().min(1),\n passRef: z.string().min(1),\n })\n .strict(),\n z.object({ type: z.literal('custom'), id: z.string().min(1) }).strict(),\n])\n\nconst ApiServiceSchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n baseUrl: z.string().url(),\n auth: ApiAuthSchema.optional(),\n // Allow both strings and RegExp values via z.union — RegExp is\n // serialized as its source when cloned, so we accept both.\n allowedPaths: z.array(z.union([z.string(), z.instanceof(RegExp)])).optional(),\n allowedMethods: z.array(ApiHttpMethodEnum).optional(),\n defaultHeaders: z.record(z.string(), z.string()).optional(),\n maxBodyBytes: z.number().int().positive().optional(),\n })\n .strict()\n\nconst ApiConfigResolved = z\n .object({\n services: z.array(ApiServiceSchema),\n maxResponseBytes: z.number().int().positive().optional(),\n })\n .strict()\n\n// ---------- knowledge (Plan 023) ----------\n//\n// Engine-level config validates ONLY scalars. Per-run external\n// links carry an optional `headers` field (auth secrets) — those\n// live on the runtime-only side and are stripped/re-attached in\n// mergeConfig the same way Plan 020's ApiCall env is handled.\n\nconst KnowledgeConfigResolved = z\n .object({\n enabled: z.boolean(),\n maxSearchResults: z.number().int().positive(),\n maxReadBytes: z.number().int().positive(),\n })\n .strict()\n\n// ---------- runner (Plan 019) ----------\n//\n// Both `url` and `secret` are required when the block is present. The\n// whole block itself is optional (the engine wraps this schema with\n// `.optional()` at the top level). Empty strings are rejected — an\n// empty URL is a misconfiguration, and auth is mandatory.\nconst RunnerConfigResolved = z\n .object({\n url: z.string().url(),\n secret: z.string().min(1, 'runner.secret cannot be empty'),\n })\n .strict()\n\n// ---------- resolved top-level schema ----------\n\nexport const ResolvedConfigSchema = z\n .object({\n model: ModelConfigResolved,\n storage: StorageConfigResolved,\n memory: MemoryConfigResolved,\n tools: ToolsConfigResolved,\n agents: AgentsConfigResolved,\n skills: SkillsConfigResolved,\n execution: ExecutionConfigResolved,\n transcript: TranscriptConfigResolved,\n hooks: HooksConfigResolved,\n logging: LoggingConfigResolved,\n mcp: McpConfigResolved,\n permissions: PermissionsConfigResolved,\n compaction: CompactionConfigResolved,\n coordinator: CoordinatorConfigResolved,\n orchestrator: OrchestratorConfigResolved,\n runner: RunnerConfigResolved.optional(),\n api: ApiConfigResolved.optional(),\n knowledge: KnowledgeConfigResolved.optional(),\n })\n .strict()\n\n// ---------- user (deep-partial) sub-schemas ----------\n//\n// We declare these explicitly instead of using .deepPartial() so that each\n// level is strictly keyed (unknown nested keys still rejected) while every\n// field itself is optional. Strictness without deepPartial would reject\n// fields missing from the literal; .deepPartial() alone would strip .strict().\n\nconst R2ConfigUser = R2ConfigResolved.partial()\n\nconst ModelConfigUser = ModelConfigResolved.partial()\n\nconst StorageConfigUser = z\n .object({\n provider: StorageProviderEnum.optional(),\n rootPath: z.string().min(1).optional(),\n workspaceId: z\n .string()\n .regex(/^[a-zA-Z0-9_-]+$/, 'workspaceId: only [a-zA-Z0-9_-] allowed')\n .optional(),\n r2: R2ConfigUser.optional(),\n r2Binding: R2BucketBindingShape.optional(),\n })\n .strict()\n\n// Knowledge user schema — same shape as resolved, but every field\n// optional. mergeConfig fills sensible defaults so callers can\n// write `{ enabled: true }` and not have to remember every knob.\nconst KnowledgeConfigUser = KnowledgeConfigResolved.partial()\n\n// User schema accepts the deprecated 'global' scope value so existing\n// configs parse; `mergeConfig` warns + coerces it to 'workspace'\n// before the resolved schema validates the final shape.\nconst MemoryConfigUser = z\n .object({\n mode: MemoryModeEnum.optional(),\n scope: MemoryScopeUserEnum.optional(),\n })\n .strict()\nconst ToolsConfigUser = ToolsConfigResolved.partial()\nconst AgentsConfigUser = AgentsConfigResolved.partial()\nconst SkillsConfigUser = SkillsConfigResolved.partial()\nconst ExecutionConfigUser = ExecutionConfigResolved.partial()\nconst TranscriptConfigUser = TranscriptConfigResolved.partial()\nconst HooksConfigUser = HooksConfigResolved.partial()\nconst LoggingConfigUser = LoggingConfigResolved.partial()\n\n// MCP user shape: each transport variant is deeply-partial. Since we\n// can't use a discriminated union on an optional `type` field at the user\n// level (callers may omit it), we merge them into one permissive shape.\n// The resolved schema (above) enforces the discriminator strictly.\nconst McpServerConfigUser = z\n .object({\n type: z.enum(['stdio', 'http', 'sse']).optional(),\n // stdio fields\n command: z.string().min(1).optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n cwd: z.string().optional(),\n isolateEnv: z.boolean().optional(),\n // http + sse fields\n url: z.string().url().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n preferBindingTransport: z.boolean().optional(),\n headersProvider: z.function().optional(),\n allowSampling: z.boolean().optional(),\n })\n .strict()\n\nconst McpConfigUser = z\n .object({\n servers: z.record(z.string().min(1), McpServerConfigUser).optional(),\n connectTimeoutMs: z.number().int().nonnegative().optional(),\n callTimeoutMs: z.number().int().nonnegative().optional(),\n shutdownTimeoutMs: z.number().int().positive().optional(),\n })\n .strict()\n\nconst PermissionsConfigUser = PermissionsConfigResolved.partial()\n// RunnerConfigUser intentionally mirrors the resolved schema — both\n// `url` and `secret` are required when the caller opts into handoff.\n// Partial here would allow `{ url }` without auth; Plan 019 §2 requires\n// the auth to be mandatory.\nconst RunnerConfigUser = RunnerConfigResolved\n\n// User-side api schema mirrors the resolved one (services + scalars).\n// Env / resolveAuth / hooks are stripped in `mergeConfig` before the\n// Zod parse runs, so they never appear here.\nconst ApiConfigUser = ApiConfigResolved.partial()\n// User schema is `.partial()` — but deep enough that the nested\n// toolResultOffload block also becomes partial. Otherwise passing\n// `toolResultOffload: { enabled: true }` would be rejected because\n// `thresholdBytes` / `maxPreviewChars` are required in the resolved\n// shape. The merge step fills defaults.\nconst ToolResultOffloadConfigUser = ToolResultOffloadConfigResolved.partial()\nconst CompactionConfigUser = z\n .object({\n strategy: CompactionStrategyEnum.optional(),\n threshold: z.number().min(0).max(1).optional(),\n keepLast: z.number().int().positive().optional(),\n summaryMaxTokens: z.number().int().positive().optional(),\n microcompact: z.boolean().optional(),\n microcompactAgeMs: z.number().int().nonnegative().optional(),\n toolResultOffload: ToolResultOffloadConfigUser.optional(),\n })\n .strict()\nconst CoordinatorConfigUser = CoordinatorConfigResolved.partial()\nconst OrchestratorConfigUser = OrchestratorConfigResolved.deepPartial()\n\nexport const UserConfigSchema = z\n .object({\n model: ModelConfigUser.optional(),\n storage: StorageConfigUser.optional(),\n memory: MemoryConfigUser.optional(),\n tools: ToolsConfigUser.optional(),\n agents: AgentsConfigUser.optional(),\n skills: SkillsConfigUser.optional(),\n execution: ExecutionConfigUser.optional(),\n transcript: TranscriptConfigUser.optional(),\n hooks: HooksConfigUser.optional(),\n logging: LoggingConfigUser.optional(),\n mcp: McpConfigUser.optional(),\n permissions: PermissionsConfigUser.optional(),\n compaction: CompactionConfigUser.optional(),\n coordinator: CoordinatorConfigUser.optional(),\n orchestrator: OrchestratorConfigUser.optional(),\n runner: RunnerConfigUser.optional(),\n api: ApiConfigUser.optional(),\n knowledge: KnowledgeConfigUser.optional(),\n })\n .strict()\n","/**\n * Engine — the top-level handle returned by `initEngine()`.\n *\n * Phase 7 wires `run()` end-to-end:\n * 1. Build the storage adapter pair (global + workspace) from config.\n * 2. Build the tool registry from the engine's core tools, filtered by\n * `config.tools.enabled`.\n * 3. Build the API client (Anthropic or proxy) from the model config.\n * 4. Build a transcript writer rooted at\n * `projects/{runId}/nodes/{nodeId}/`.\n * 5. Build the tool executor with timeout from config.\n * 6. Build a `RunContext`, seed it with the task as the first user\n * message, and drive the `agentLoop` to completion.\n * 7. Map the loop's `AgentLoopResult` into the public `RunResult`.\n *\n * `resume()` is still a Phase 10 stub.\n *\n * The optional second constructor parameter (`internals`) lets tests\n * inject a custom `fetch` implementation. The public `initEngine()`\n * factory does not expose this — it's strictly for unit/integration\n * tests that need to swap in a mock API client.\n */\n\nimport type { ResolvedConfig } from '../config/types.js'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport { createModelAdapter } from '../model/factory.js'\nimport { canSpawnProcesses } from '../runtime/detect.js'\nimport { withCapabilityCheck } from '../tools/capabilityStub.js'\nimport { SubagentRegistry } from '../subagent/registry.js'\nimport { createAgentTool } from '../tools/agent.js'\nimport { createBashTool } from '../tools/bash.js'\nimport { createSendMessageTool } from '../tools/sendMessage.js'\nimport type { Tool } from '../tools/contract.js'\nimport { ToolRegistry } from '../tools/contract.js'\nimport { createFileEditTool } from '../tools/fileEdit.js'\nimport { createFileReadTool } from '../tools/fileRead.js'\nimport { createFileWriteTool } from '../tools/fileWrite.js'\nimport { createGlobTool } from '../tools/glob.js'\nimport { createGrepTool } from '../tools/grep.js'\nimport { createWebFetchTool } from '../tools/webFetch.js'\nimport { FileTracker } from '../tools/fileTracker.js'\nimport { createWebSearchTool } from '../tools/webSearch.js'\nimport { createSleepTool } from '../tools/sleep.js'\nimport { createToolSearchTool } from '../tools/toolSearch.js'\nimport { createMemorizeTool } from '../tools/memorize.js'\nimport { createRecallTool } from '../tools/recall.js'\nimport { createNotebookEditTool } from '../tools/notebookEdit.js'\nimport { TaskStore } from '../tools/tasks/store.js'\nimport {\n createTaskCreateTool,\n createTaskGetTool,\n createTaskListTool,\n createTaskUpdateTool,\n} from '../tools/tasks/tools.js'\nimport { createLogger, type Logger } from '../logging/logger.js'\nimport { loadAgents } from '../agents/loader.js'\nimport {\n isCoordinatorMode,\n buildWorkerAgent,\n getCoordinatorBasePrompt,\n} from '../coordinator/mode.js'\nimport type { AgentDefinition } from '../tools/agent.js'\nimport { McpManager } from '../mcp/manager.js'\nimport { defaultSamplingHandler } from '../mcp/sampling.js'\nimport { buildPermissionPolicy, type PermissionPolicy } from '../permissions/evaluator.js'\nimport { createSmartMemory } from '../memory/memoryConfig.js'\nimport { buildSystemPrompt } from '../prompts/systemPrompt.js'\nimport { buildSchemaPrompt, tryParseJSON, validateOutput } from './jsonOutput.js'\nimport { createSkillPageTool } from '../skills/skillPage.js'\nimport { createApiCallTool } from '../tools/apiCall.js'\nimport { createFetchDataTool } from '../tools/fetchData.js'\nimport { createSearchKnowledgeTool } from '../tools/searchKnowledge.js'\nimport { createReadKnowledgeTool } from '../tools/readKnowledge.js'\nimport type { ResolvedApiConfig } from '../config/types.js'\nimport type { KnowledgeExternalLinkV1 } from '../knowledge/types.js'\nimport { StorageSkillSource } from '../skills/storageSkillSource.js'\nimport { InlineSkillSource } from '../skills/inlineSkillSource.js'\nimport type { SkillSource } from '../skills/source.js'\nimport { createEngineStorage } from '../storage/factory.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { TranscriptReader } from '../transcript/reader.js'\nimport { TranscriptWriter, loadWriterState } from '../transcript/writer.js'\nimport { dispatchHooks } from '../hooks/dispatch.js'\nimport type { PostRunEvent } from '../hooks/types.js'\nimport { agentLoop, type GateBeforeTool } from './agentLoop.js'\nimport { ConfigError } from './errors.js'\nimport { rebuildMessagesFromEntries } from './rehydrate.js'\nimport { RunContext } from './runContext.js'\nimport { ToolExecutor } from './toolRuntime.js'\nimport type { ResumeOptions, RunOptions, RunResult, RunSnapshot } from './types.js'\nimport { toResponse, type EngineResponse } from './response.js'\nimport { randomUUID } from '../runtime/uuid.js'\nimport {\n RunStateManager,\n type RunState,\n type RunStatus,\n type WebhookConfig,\n type WebhookEvent,\n} from './state.js'\nimport { NodeBackgroundExecutor, type BackgroundExecutor } from './executor.js'\nimport { WebhookDispatcher, RETRY_DELAYS_MS, MAX_ATTEMPTS } from './webhook.js'\n\n/** Config for webhook delivery when using async APIs. */\nexport interface WebhookOptions {\n readonly url: string\n readonly secret?: string\n readonly events?: readonly WebhookEvent[]\n readonly headers?: Record<string, string>\n}\n\n/** Options for engine.start() — extends RunOptions with webhook. */\nexport interface StartOptions extends RunOptions {\n readonly webhook?: WebhookOptions\n}\n\n/** Options for engine.resumeAsync() — extends ResumeOptions with webhook. */\nexport interface ResumeAsyncOptions extends ResumeOptions {\n readonly webhook?: WebhookOptions\n}\n\n/** Options for engine.waitFor() — blocks until terminal state. */\nexport interface WaitForOptions {\n readonly nodeId?: string\n readonly timeoutMs?: number\n readonly pollIntervalMs?: number\n}\n\nexport interface EngineInternals {\n /** Override the fetch implementation used by the API client. Tests only. */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Optional pre-tool gate. When set, every tool dispatch is checked\n * by this callback. Returning `{ allow: false }` pauses the run.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /**\n * Background executor for async runs (engine.start, engine.resumeAsync).\n * Defaults to NodeBackgroundExecutor. On Cloudflare Workers, provide a\n * DurableObjectExecutor that dispatches to a DO.\n */\n readonly backgroundExecutor?: BackgroundExecutor\n /**\n * Override the storage factory. When set, the engine calls this\n * instead of `createEngineStorage(config.storage)` for every run.\n *\n * Use this on Cloudflare Workers to build an `EngineStorage` pair\n * backed by `R2BindingStorageAdapter` (which uses the native R2\n * binding, not the S3 SDK). Example:\n *\n * new Engine(config, {\n * buildStorage: async () => ({\n * global: new R2BindingStorageAdapter(env.BUCKET, 'root/.claude'),\n * workspace: new R2BindingStorageAdapter(env.BUCKET, `root/workspaces/${ws}/.claude`),\n * }),\n * })\n */\n readonly buildStorage?: () => Promise<import('../storage/interface.js').EngineStorage>\n /**\n * Handler invoked when an MCP server with `allowSampling: true`\n * requests an LLM completion via `sampling/createMessage`. Defaults\n * to a handler that routes through the engine's own ModelAdapter\n * (same API key, same billing). Override to route to a cheaper\n * model, enforce budget limits, or refuse specific servers.\n */\n readonly samplingHandler?: import('../mcp/sampling.js').SamplingHandler\n}\n\nexport class Engine {\n readonly config: ResolvedConfig\n private readonly internals: EngineInternals\n private readonly mcpManager: McpManager\n private readonly permissionPolicy: PermissionPolicy\n private readonly backgroundExecutor: BackgroundExecutor\n private readonly webhookDispatcher: WebhookDispatcher\n\n constructor(config: ResolvedConfig, internals: EngineInternals = {}) {\n this.config = config\n this.internals = internals\n this.backgroundExecutor = internals.backgroundExecutor ?? new NodeBackgroundExecutor()\n this.webhookDispatcher = new WebhookDispatcher(\n internals.fetch ?? globalThis.fetch.bind(globalThis),\n )\n // Build the sampling handler: user override, else engine default\n // that routes to our own ModelAdapter. Only invoked when a server\n // has allowSampling: true.\n const samplingHandler =\n internals.samplingHandler ??\n defaultSamplingHandler(\n createModelAdapter(config.model, {\n ...(internals.fetch !== undefined ? { fetch: internals.fetch } : {}),\n }),\n )\n this.mcpManager = new McpManager(config.mcp, createLogger(config.logging), { samplingHandler })\n this.permissionPolicy = buildPermissionPolicy(config.permissions)\n }\n\n /**\n * Run a task synchronously to completion. The `_internal` parameter is\n * reserved for the engine's own async wrappers (`start`, `resumeAsync`)\n * to request runner handoff (Plan 019) — external callers must leave\n * it unset. Sync callers never hand off; if they hit a Node-only tool\n * on a restricted runtime, the capability stub returns an error and\n * the model adapts.\n */\n async run(\n options: RunOptions,\n _internal?: { handoffToRunner?: boolean },\n ): Promise<EngineResponse> {\n const startTime = Date.now()\n const runId = options.runId ?? `run_${randomUUID()}`\n const log = createLogger(this.config.logging)\n log.info('engine.run start', {\n runId,\n nodeId: options.nodeId,\n model: this.config.model.modelId,\n provider: this.config.model.provider,\n })\n const storage = await this.buildStorage()\n const client = this.buildClient()\n const logPath = `projects/${runId}/nodes/${options.nodeId}`\n const subagentRegistry = new SubagentRegistry({\n maxDepth: this.config.execution.maxSubagentDepth,\n })\n const memory = createSmartMemory({ storage, config: this.config.memory })\n const agents = await this.resolveAgents(storage)\n const mcpTools = await this.mcpManager.getTools()\n\n // Build the system prompt AFTER collecting MCP tools so the prompt\n // can list them, and AFTER resolving agents for the same reason.\n // We build a temporary registry first to get the full tool name set,\n // then pass it to the prompt builder, then build the real registry\n // with the final system prompt.\n const toolNameSet = this.collectToolNames(mcpTools)\n // In coordinator mode, the base prompt is swapped to the coordinator\n // version. The normal static sections (doingTasks, actions, usingTools)\n // are skipped — the coordinator prompt covers its own behavioral rules.\n const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : undefined\n // Resolve the skill source for this run. Per-run `options.skills`\n // override wins over the disk-backed autoload path. See Plan 017.\n const skillSource = this.resolveSkillSource(options.skills, storage)\n const skillList = skillSource !== undefined ? await skillSource.list() : undefined\n const apiConfig = this.resolveApiConfig(options.api)\n const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload)\n const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage)\n\n let systemPrompt = await buildSystemPrompt({\n ...(coordinatorBase !== undefined ? { base: coordinatorBase } : {}),\n memory,\n storage,\n // When an override was supplied, skip the legacy disk-scan path.\n skillsAutoload: options.skills !== undefined ? false : this.config.skills.autoload,\n ...(this.config.skills.path !== undefined ? { skillsDir: this.config.skills.path } : {}),\n ...(skillList !== undefined ? { skillList } : {}),\n modelId: this.config.model.modelId,\n provider: this.config.model.provider,\n registeredToolNames: toolNameSet,\n mcpTools,\n coordinatorMode: isCoordinatorMode(this.config),\n })\n\n // Structured output: inject schema instructions into system prompt\n if (options.outputFormat === 'json') {\n systemPrompt += '\\n\\n' + buildSchemaPrompt(options.outputSchema)\n }\n\n // Resolve gate early so it can be propagated into subagents when\n // config.hooks.propagateGateToSubagents === true.\n const gate = this.resolveGate()\n\n const registry = buildToolRegistry({\n config: this.config,\n storage,\n client,\n parentLogPath: logPath,\n parentAgentId: null,\n subagentRegistry,\n system: systemPrompt,\n agents,\n mcpTools,\n memory,\n ...(this.config.hooks.propagateGateToSubagents === true && gate !== undefined\n ? { subagentGate: gate }\n : {}),\n ...(skillSource !== undefined ? { skillSource } : {}),\n ...(apiConfig !== undefined ? { apiConfig } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n ...(knowledgeRuntime !== undefined ? { knowledge: knowledgeRuntime } : {}),\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n const writer = new TranscriptWriter({\n storage: storage.workspace,\n logPath,\n flushPolicy: this.config.transcript.flushPolicy,\n idleFlushMs: this.config.transcript.idleFlushMs,\n })\n const executor = new ToolExecutor({\n registry,\n timeoutMs: this.config.execution.turnTimeoutMs,\n permissions: this.permissionPolicy,\n hooks: {\n preToolCall: (event) => dispatchHooks(this.config.hooks.preToolCall, event),\n postToolCall: (event) => dispatchHooks(this.config.hooks.postToolCall, event),\n },\n })\n if (memory.episodes.enabled) {\n await memory.episodes.startSession()\n }\n const ctx = new RunContext({\n runId,\n nodeId: options.nodeId,\n writer,\n maxTurns: options.maxTurns ?? this.config.execution.maxTurns,\n episodes: memory.episodes,\n })\n\n const runTimeout = this.startRunTimeout()\n\n try {\n await writer.setStatus('running')\n await dispatchHooks(this.config.hooks.preRun, {\n runId,\n nodeId: options.nodeId,\n task: options.task,\n })\n await ctx.addUserMessage(options.task)\n\n const loopResult = await agentLoop({\n context: ctx,\n client,\n executor,\n tools: registry.list(),\n system: systemPrompt,\n contextLimit: this.config.execution.contextLimit,\n compactionConfig: this.config.compaction,\n storage: storage.workspace,\n registry,\n maxToolConcurrency: this.config.execution.maxToolConcurrency,\n subagentRegistry,\n preTurnHooks: this.config.hooks.preTurn,\n postTurnHooks: this.config.hooks.postTurn,\n stopHooks: this.config.hooks.stopHooks,\n onProgress: this.buildHeartbeat(storage, runId, options.nodeId),\n ...(options.tokenBudget !== undefined ? { tokenBudget: options.tokenBudget } : {}),\n ...(runTimeout.signal !== undefined\n ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs }\n : {}),\n ...(gate !== undefined ? { gateBeforeTool: gate } : {}),\n ...(_internal?.handoffToRunner === true ? { handoffToRunner: true } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n })\n\n const result = await this.finalizeResult(loopResult, writer, logPath, {\n ...(options.outputFormat !== undefined ? { outputFormat: options.outputFormat } : {}),\n ...(options.outputSchema !== undefined ? { outputSchema: options.outputSchema } : {}),\n })\n this.logRunEnd(log, runId, options.nodeId, result)\n await this.firePostRunHook(runId, options.nodeId, result, ctx, logPath)\n const capabilitiesMissing = ctx.getCapabilitiesMissing()\n return toResponse(result, {\n runId,\n nodeId: options.nodeId,\n durationMs: Date.now() - startTime,\n logPath,\n ...(capabilitiesMissing.length > 0 ? { capabilitiesMissing } : {}),\n })\n } finally {\n runTimeout.clear()\n await writer.close()\n }\n }\n\n async resume(\n options: ResumeOptions,\n _internal?: { handoffToRunner?: boolean },\n ): Promise<EngineResponse> {\n const startTime = Date.now()\n const log = createLogger(this.config.logging)\n\n // Load snapshot — either from options (internal) or from storage (client)\n const storage = await this.buildStorage()\n let snapshot: RunSnapshot\n if (options.snapshot) {\n snapshot = options.snapshot\n } else {\n // Client path: load snapshot from storage using runId (+ optional nodeId)\n snapshot = await this.loadSnapshot(storage, options.runId, options.nodeId)\n }\n\n log.info('engine.resume start', {\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n pauseReason: snapshot.pauseReason,\n messageCount: snapshot.messageCount,\n })\n if (snapshot.version !== 1) {\n throw new ConfigError(\n `Engine.resume: unsupported snapshot version ${String(snapshot.version)}`,\n )\n }\n\n const client = this.buildClient()\n const logPath = `projects/${snapshot.runId}/nodes/${snapshot.nodeId}`\n const subagentRegistry = new SubagentRegistry({\n maxDepth: this.config.execution.maxSubagentDepth,\n })\n const memory = createSmartMemory({ storage, config: this.config.memory })\n const agents = await this.resolveAgents(storage)\n const mcpTools = await this.mcpManager.getTools()\n\n const toolNameSet = this.collectToolNames(mcpTools)\n // In coordinator mode, the base prompt is swapped to the coordinator\n // version. The normal static sections (doingTasks, actions, usingTools)\n // are skipped — the coordinator prompt covers its own behavioral rules.\n const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : undefined\n // Resolve the skill source for this run. Per-run `options.skills`\n // override wins over the disk-backed autoload path. See Plan 017.\n const skillSource = this.resolveSkillSource(options.skills, storage)\n const skillList = skillSource !== undefined ? await skillSource.list() : undefined\n const apiConfig = this.resolveApiConfig(options.api)\n const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload)\n const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage)\n\n let systemPrompt = await buildSystemPrompt({\n ...(coordinatorBase !== undefined ? { base: coordinatorBase } : {}),\n memory,\n storage,\n // When an override was supplied, skip the legacy disk-scan path.\n skillsAutoload: options.skills !== undefined ? false : this.config.skills.autoload,\n ...(this.config.skills.path !== undefined ? { skillsDir: this.config.skills.path } : {}),\n ...(skillList !== undefined ? { skillList } : {}),\n modelId: this.config.model.modelId,\n provider: this.config.model.provider,\n registeredToolNames: toolNameSet,\n mcpTools,\n coordinatorMode: isCoordinatorMode(this.config),\n })\n\n // Structured output: inject schema instructions into system prompt\n if (options.outputFormat === 'json') {\n systemPrompt += '\\n\\n' + buildSchemaPrompt(options.outputSchema)\n }\n\n // Resolve gate early so it can be propagated into subagents when\n // config.hooks.propagateGateToSubagents === true.\n const gate = this.resolveGate()\n\n const registry = buildToolRegistry({\n config: this.config,\n storage,\n client,\n parentLogPath: logPath,\n parentAgentId: null,\n subagentRegistry,\n system: systemPrompt,\n agents,\n mcpTools,\n memory,\n ...(this.config.hooks.propagateGateToSubagents === true && gate !== undefined\n ? { subagentGate: gate }\n : {}),\n ...(skillSource !== undefined ? { skillSource } : {}),\n ...(apiConfig !== undefined ? { apiConfig } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n ...(knowledgeRuntime !== undefined ? { knowledge: knowledgeRuntime } : {}),\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n // Resume must continue appending to the existing transcript without\n // overwriting any shards. Load the prior writer state from meta.json\n // so the new writer's counter starts at lastShardIndex + 1.\n const priorState = await loadWriterState(storage.workspace, logPath)\n const writer = new TranscriptWriter({\n storage: storage.workspace,\n logPath,\n flushPolicy: this.config.transcript.flushPolicy,\n idleFlushMs: this.config.transcript.idleFlushMs,\n ...(priorState !== null\n ? {\n initialShardIndex: priorState.nextShardIndex,\n initialMeta: priorState.meta,\n }\n : {}),\n })\n const executor = new ToolExecutor({\n registry,\n timeoutMs: this.config.execution.turnTimeoutMs,\n permissions: this.permissionPolicy,\n hooks: {\n preToolCall: (event) => dispatchHooks(this.config.hooks.preToolCall, event),\n postToolCall: (event) => dispatchHooks(this.config.hooks.postToolCall, event),\n },\n })\n if (memory.episodes.enabled) {\n // Continue the same session id if any prior session existed.\n // For v0.1 we just start a new session on resume — episodes\n // are append-only and the new session id distinguishes them.\n await memory.episodes.startSession()\n }\n const ctx = new RunContext({\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n writer,\n maxTurns: this.config.execution.maxTurns,\n episodes: memory.episodes,\n })\n\n const runTimeout = this.startRunTimeout()\n\n try {\n // Replay the transcript shards back into the context's message\n // history. The reader walks the existing JSONL files; we\n // reconstruct the in-memory MessageParam[] without re-writing\n // any transcript entries.\n const reader = new TranscriptReader(storage.workspace, logPath)\n const entries = await reader.readAll()\n const messages = rebuildMessagesFromEntries(entries)\n ctx.rehydrate({\n messages,\n turnCount: snapshot.turnsUsed,\n tokensUsed: {\n input: snapshot.tokensUsedSoFar.input,\n output: snapshot.tokensUsedSoFar.output,\n ...(snapshot.tokensUsedSoFar.cacheCreationInput !== undefined\n ? { cacheCreationInput: snapshot.tokensUsedSoFar.cacheCreationInput }\n : {}),\n ...(snapshot.tokensUsedSoFar.cacheReadInput !== undefined\n ? { cacheReadInput: snapshot.tokensUsedSoFar.cacheReadInput }\n : {}),\n },\n lastUuid: snapshot.lastMessageUuid,\n })\n\n // If the snapshot captured a pending tool call, we need to inject\n // a tool_result so the API sees a complete tool_use ↔ tool_result\n // pair (otherwise the Messages API rejects the conversation).\n if (snapshot.pendingToolCall) {\n const pending = snapshot.pendingToolCall\n if (options.gateAnswer !== undefined) {\n // Caller provided an explicit answer — inject it as the result.\n const answer =\n typeof options.gateAnswer === 'string'\n ? options.gateAnswer\n : JSON.stringify(options.gateAnswer)\n await ctx.addToolResult(pending.toolUseId, answer, false)\n } else {\n // No answer — inject a synthetic tool_result + a retry\n // directive AS A SINGLE user message. Two separate user\n // messages (tool_result then text) trip the AI SDK's\n // MissingToolResultsError on openai-compatible providers;\n // combining them keeps the tool_use↔tool_result pairing\n // intact under all providers.\n //\n // The retry text is load-bearing: models treat tool_result\n // as passive feedback and often decide the work is \"done\"\n // without re-executing. An explicit instruction with the\n // original arguments makes retry reliable.\n const inputJson = JSON.stringify(pending.input ?? {}, null, 2)\n await ctx.addMixedUserMessage([\n {\n type: 'tool_result',\n tool_use_id: pending.toolUseId,\n content: `APPROVAL_GATE_RELEASED: the prior ${pending.toolName} call was paused for human approval and has now been approved. Retry is required.`,\n },\n {\n type: 'text',\n text:\n `The human has approved the paused ${pending.toolName} tool call. ` +\n `You MUST now re-issue the EXACT same tool call to complete the work — ` +\n `do not change the arguments, do not answer in text, do not declare the task done. ` +\n `Approved arguments (copy verbatim):\\n\\`\\`\\`json\\n${inputJson}\\n\\`\\`\\``,\n },\n ])\n }\n }\n\n await writer.setStatus('running')\n\n const loopResult = await agentLoop({\n context: ctx,\n client,\n executor,\n tools: registry.list(),\n system: systemPrompt,\n contextLimit: this.config.execution.contextLimit,\n compactionConfig: this.config.compaction,\n storage: storage.workspace,\n registry,\n maxToolConcurrency: this.config.execution.maxToolConcurrency,\n subagentRegistry,\n preTurnHooks: this.config.hooks.preTurn,\n postTurnHooks: this.config.hooks.postTurn,\n stopHooks: this.config.hooks.stopHooks,\n onProgress: this.buildHeartbeat(storage, snapshot.runId, snapshot.nodeId),\n ...(runTimeout.signal !== undefined\n ? { runSignal: runTimeout.signal, runTimeoutMs: this.config.execution.runTimeoutMs }\n : {}),\n ...(gate !== undefined ? { gateBeforeTool: gate } : {}),\n ...(_internal?.handoffToRunner === true ? { handoffToRunner: true } : {}),\n ...(offloadConfig !== undefined ? { toolResultOffload: offloadConfig } : {}),\n })\n\n const result = await this.finalizeResult(loopResult, writer, logPath, {\n ...(options.outputFormat !== undefined ? { outputFormat: options.outputFormat } : {}),\n ...(options.outputSchema !== undefined ? { outputSchema: options.outputSchema } : {}),\n })\n this.logRunEnd(log, snapshot.runId, snapshot.nodeId, result)\n await this.firePostRunHook(snapshot.runId, snapshot.nodeId, result, ctx, logPath)\n const capabilitiesMissing = ctx.getCapabilitiesMissing()\n return toResponse(result, {\n runId: snapshot.runId,\n nodeId: snapshot.nodeId,\n durationMs: Date.now() - startTime,\n logPath,\n ...(capabilitiesMissing.length > 0 ? { capabilitiesMissing } : {}),\n })\n } finally {\n runTimeout.clear()\n await writer.close()\n }\n }\n\n /**\n * Load a paused snapshot from storage using runId (and optional nodeId).\n * If nodeId is not provided, finds the most recently paused node.\n */\n private async loadSnapshot(\n storage: EngineStorage,\n runId: string,\n nodeId?: string,\n ): Promise<RunSnapshot> {\n if (nodeId) {\n const snapPath = `projects/${runId}/nodes/${nodeId}/snapshot.json`\n const content = await storage.workspace.readFile(snapPath)\n if (!content) {\n throw new ConfigError(\n `engine.resume: no snapshot found at ${snapPath}. Check runId/nodeId.`,\n )\n }\n return JSON.parse(content) as RunSnapshot\n }\n\n // Scan all nodes under this runId for the most recently paused snapshot\n const nodesDir = `projects/${runId}/nodes`\n const nodeNames = await storage.workspace.listDir(nodesDir)\n if (nodeNames.length === 0) {\n throw new ConfigError(`engine.resume: no runs found for runId=${runId}`)\n }\n\n let newest: { snapshot: RunSnapshot; ts: number } | null = null\n for (const name of nodeNames) {\n const content = await storage.workspace.readFile(`${nodesDir}/${name}/snapshot.json`)\n if (!content) continue\n try {\n const snap = JSON.parse(content) as RunSnapshot\n const ts = Date.parse(snap.pausedAt)\n if (!newest || ts > newest.ts) newest = { snapshot: snap, ts }\n } catch {\n /* skip invalid */\n }\n }\n\n if (!newest) {\n throw new ConfigError(\n `engine.resume: no paused snapshots found for runId=${runId}. ` +\n `Pass nodeId to target a specific node.`,\n )\n }\n return newest.snapshot\n }\n\n // ================================================================\n // Async APIs — start / resumeAsync / getStatus / waitFor / cancelRun\n // ================================================================\n\n /**\n * Start a run asynchronously. Writes initial state, schedules the run\n * in the background, and returns immediately. Clients should track the\n * returned runId and poll via `getStatus(runId)` or wait for a webhook.\n *\n * Workers compatibility: provide a DurableObjectExecutor via\n * EngineInternals.backgroundExecutor — the default NodeBackgroundExecutor\n * uses fire-and-forget Promises which won't survive Worker request exit.\n */\n async start(\n options: StartOptions,\n ): Promise<{ runId: string; nodeId: string; status: RunStatus }> {\n const runId = options.runId ?? `run_${randomUUID()}`\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n const webhook = options.webhook\n ? {\n url: options.webhook.url,\n events: options.webhook.events ?? ['paused', 'done', 'failed'],\n ...(options.webhook.secret !== undefined ? { secret: options.webhook.secret } : {}),\n ...(options.webhook.headers !== undefined ? { headers: options.webhook.headers } : {}),\n deliveries: [],\n }\n : undefined\n\n const initial = RunStateManager.initial(runId, options.nodeId, webhook)\n await stateManager.write(initial)\n\n const handoffEnabled = this.config.runner !== undefined\n this.backgroundExecutor.schedule(runId, async (signal) => {\n await stateManager.update(runId, options.nodeId, { status: 'running' })\n try {\n const response = await this.run({ ...options, runId }, { handoffToRunner: handoffEnabled })\n if (signal.aborted) return\n // Plan 019 — when the run paused for runner handoff, fire the\n // POST before finalizing so any runner-dispatch failure flips\n // the response to failed with ERR_RUNNER_UNREACHABLE.\n const postHandoff = await this.maybeHandoffToRunner(runId, options.nodeId, response)\n await stateManager.finalize(runId, options.nodeId, postHandoff)\n await this.maybeFireWebhook(stateManager, runId, options.nodeId, postHandoff)\n } catch (err) {\n if (signal.aborted) return\n const errorMsg = err instanceof Error ? err.message : String(err)\n const failResponse: EngineResponse = {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: options.nodeId },\n errors: [{ code: 'RUN_FAILED', message: errorMsg }],\n timestamp: Date.now(),\n }\n await stateManager.finalize(runId, options.nodeId, failResponse)\n await this.maybeFireWebhook(stateManager, runId, options.nodeId, failResponse)\n }\n })\n\n return { runId, nodeId: options.nodeId, status: 'queued' }\n }\n\n /**\n * Resume a paused run asynchronously. Equivalent to engine.resume() but\n * dispatched via the background executor. Returns immediately.\n */\n async resumeAsync(\n options: ResumeAsyncOptions,\n ): Promise<{ runId: string; nodeId: string; status: RunStatus }> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n // Must know nodeId to write state — load snapshot if not provided\n let nodeId = options.nodeId\n if (nodeId === undefined) {\n const snap = options.snapshot ?? (await this.loadSnapshot(storage, options.runId))\n nodeId = snap.nodeId\n }\n\n const existing = await stateManager.read(options.runId, nodeId)\n const webhook = options.webhook\n ? {\n url: options.webhook.url,\n events: options.webhook.events ?? ['paused', 'done', 'failed'],\n ...(options.webhook.secret !== undefined ? { secret: options.webhook.secret } : {}),\n ...(options.webhook.headers !== undefined ? { headers: options.webhook.headers } : {}),\n deliveries: [],\n }\n : existing?.webhook\n\n const next: RunState = existing\n ? {\n ...existing,\n status: 'running',\n lastHeartbeat: Date.now(),\n response: null, // clear stale paused response so getStatus returns provisional\n ...(webhook !== undefined ? { webhook } : {}),\n }\n : { ...RunStateManager.initial(options.runId, nodeId, webhook), status: 'running' }\n await stateManager.write(next)\n\n const resumeNodeId = nodeId\n const handoffEnabled = this.config.runner !== undefined\n this.backgroundExecutor.schedule(options.runId, async (signal) => {\n try {\n const response = await this.resume(options, { handoffToRunner: handoffEnabled })\n if (signal.aborted) return\n const postHandoff = await this.maybeHandoffToRunner(options.runId, resumeNodeId, response)\n await stateManager.finalize(options.runId, resumeNodeId, postHandoff)\n await this.maybeFireWebhook(stateManager, options.runId, resumeNodeId, postHandoff)\n } catch (err) {\n if (signal.aborted) return\n const errorMsg = err instanceof Error ? err.message : String(err)\n const failResponse: EngineResponse = {\n runId: options.runId,\n status: 'failed',\n data: null,\n meta: { nodeId: resumeNodeId },\n errors: [{ code: 'RESUME_FAILED', message: errorMsg }],\n timestamp: Date.now(),\n }\n await stateManager.finalize(options.runId, resumeNodeId, failResponse)\n await this.maybeFireWebhook(stateManager, options.runId, resumeNodeId, failResponse)\n }\n })\n\n return { runId: options.runId, nodeId, status: 'running' }\n }\n\n /**\n * Read the current status of a run. Returns the full EngineResponse once\n * terminal; returns a provisional response with status='running'|'queued'\n * otherwise. If nodeId is omitted, picks the most recently updated node.\n */\n async getStatus(runId: string, nodeId?: string): Promise<EngineResponse> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let state: RunState | null\n if (nodeId !== undefined) {\n state = await stateManager.read(runId, nodeId)\n } else {\n const all = await stateManager.scanRun(runId)\n state = all.reduce<RunState | null>(\n (best, cur) => (best === null || cur.lastHeartbeat > best.lastHeartbeat ? cur : best),\n null,\n )\n }\n\n if (state === null) {\n return {\n runId,\n status: 'not_found',\n data: null,\n meta: { nodeId: nodeId ?? 'unknown' },\n errors: [{ code: 'NOT_FOUND', message: `No state found for runId=${runId}` }],\n timestamp: Date.now(),\n }\n }\n\n if (state.response !== null) return state.response\n\n // Non-terminal — build a provisional response from the state.\n return {\n runId: state.runId,\n status: state.status,\n data: null,\n meta: {\n nodeId: state.nodeId,\n turns: state.progress.turns,\n tokensUsed: state.progress.tokensUsed,\n activity: state.progress.currentActivity,\n ...(state.progress.lastTool !== undefined ? { lastTool: state.progress.lastTool } : {}),\n },\n errors: [],\n timestamp: state.lastHeartbeat,\n }\n }\n\n /**\n * Poll until the run reaches a terminal state (done | failed | paused |\n * cancelled) or the timeout expires. Returns the final EngineResponse.\n */\n async waitFor(runId: string, opts: WaitForOptions = {}): Promise<EngineResponse> {\n const pollInterval = opts.pollIntervalMs ?? 1000\n const timeoutMs = opts.timeoutMs ?? 0 // 0 = no timeout\n const deadline = timeoutMs > 0 ? Date.now() + timeoutMs : Infinity\n\n for (;;) {\n const resp = await this.getStatus(runId, opts.nodeId)\n if (resp.status === 'done' || resp.status === 'failed' || resp.status === 'paused') {\n return resp\n }\n if (Date.now() >= deadline) {\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: opts.nodeId ?? 'unknown' },\n errors: [\n { code: 'WAIT_TIMEOUT', message: `waitFor timed out after ${String(timeoutMs)}ms` },\n ],\n timestamp: Date.now(),\n }\n }\n await new Promise((r) => setTimeout(r, pollInterval))\n }\n }\n\n /**\n * Cancel an async run. Aborts the background executor and marks the\n * state as cancelled. Idempotent — safe to call on already-terminal runs.\n */\n async cancelRun(runId: string, nodeId?: string): Promise<void> {\n await this.backgroundExecutor.cancel(runId)\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let targetNodeId = nodeId\n if (targetNodeId === undefined) {\n const all = await stateManager.scanRun(runId)\n const active = all.find((s) => s.status === 'running' || s.status === 'queued')\n if (active === undefined) return\n targetNodeId = active.nodeId\n }\n\n const current = await stateManager.read(runId, targetNodeId)\n if (current === null) return\n if (\n current.status === 'done' ||\n current.status === 'failed' ||\n current.status === 'cancelled'\n ) {\n return\n }\n\n const cancelledResponse: EngineResponse = {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId: targetNodeId, cancelled: true },\n errors: [{ code: 'CANCELLED', message: 'Run was cancelled by client' }],\n timestamp: Date.now(),\n }\n await stateManager.update(runId, targetNodeId, {\n status: 'cancelled',\n lastHeartbeat: Date.now(),\n response: cancelledResponse,\n })\n }\n\n /**\n * Retry a specific webhook delivery. Useful when the client acknowledges\n * they missed an event (e.g., after downtime).\n */\n async retryWebhook(runId: string, deliveryId: string, nodeId?: string): Promise<void> {\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n let targetNodeId = nodeId\n if (targetNodeId === undefined) {\n const all = await stateManager.scanRun(runId)\n const withHook = all.find((s) => s.webhook !== undefined)\n if (withHook === undefined) throw new Error(`retryWebhook: no webhook config for ${runId}`)\n targetNodeId = withHook.nodeId\n }\n\n const state = await stateManager.read(runId, targetNodeId)\n if (state === null || state.webhook === undefined || state.response === null) {\n throw new Error(`retryWebhook: no deliverable state for ${runId}/${targetNodeId}`)\n }\n\n const original = state.webhook.deliveries.find((d) => d.id === deliveryId)\n if (original === undefined) {\n throw new Error(`retryWebhook: delivery ${deliveryId} not found`)\n }\n\n await this.dispatchWebhookWithRetries(\n stateManager,\n runId,\n targetNodeId,\n original.event,\n state.response,\n 1,\n )\n }\n\n /**\n * Scan all runs for stale heartbeats and mark them as failed. Clients\n * should call this on startup to recover from crashes.\n *\n * @param opts.staleThresholdMs - Heartbeat age after which a running run\n * is considered orphaned. Default: 5 minutes.\n */\n async recoverOrphanedRuns(\n opts: { staleThresholdMs?: number } = {},\n ): Promise<readonly RunState[]> {\n const threshold = opts.staleThresholdMs ?? 5 * 60_000\n const storage = await this.buildStorage()\n const stateManager = new RunStateManager(storage.workspace)\n\n const orphaned = await stateManager.findOrphaned(threshold)\n for (const state of orphaned) {\n const failResponse: EngineResponse = {\n runId: state.runId,\n status: 'failed',\n data: null,\n meta: { nodeId: state.nodeId, orphaned: true },\n errors: [\n {\n code: 'ORPHANED',\n message: `Run has stale heartbeat (last: ${String(new Date(state.lastHeartbeat).toISOString())})`,\n },\n ],\n timestamp: Date.now(),\n }\n await stateManager.update(state.runId, state.nodeId, {\n status: 'failed',\n lastHeartbeat: Date.now(),\n response: failResponse,\n })\n }\n return orphaned\n }\n\n // ---------- runner handoff (Plan 019) ----------\n\n /**\n * When the response indicates the run paused for runner handoff, POST\n * `{ runId }` to the configured runner URL. On success, return the\n * response unchanged — state stays `paused` and the runner will flip\n * it to `done` (or `failed`) on its side. On POST failure, convert\n * the response to `failed` with `ERR_RUNNER_UNREACHABLE` so the\n * caller sees a terminal state instead of a silent hang.\n *\n * Called only from `start()` / `resumeAsync()`. Sync `run()` never\n * produces a `handoff_to_runner` pause (see `_internal.handoffToRunner`).\n */\n private async maybeHandoffToRunner(\n runId: string,\n nodeId: string,\n response: EngineResponse,\n ): Promise<EngineResponse> {\n if (response.status !== 'paused') return response\n if (response.meta.pauseReason !== 'handoff_to_runner') return response\n const runner = this.config.runner\n if (runner === undefined) {\n // handoffToRunner was false — the loop shouldn't have produced\n // this pause reason. Guard against it just in case.\n return response\n }\n const fetchFn = this.internals.fetch ?? globalThis.fetch.bind(globalThis)\n try {\n const res = await fetchFn(runner.url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${runner.secret}`,\n },\n body: JSON.stringify({ runId }),\n })\n if (!res.ok) {\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId },\n errors: [\n {\n code: 'ERR_RUNNER_UNREACHABLE',\n message: `Runner returned HTTP ${res.status}`,\n },\n ],\n timestamp: Date.now(),\n }\n }\n return response\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return {\n runId,\n status: 'failed',\n data: null,\n meta: { nodeId },\n errors: [\n {\n code: 'ERR_RUNNER_UNREACHABLE',\n message: `Runner handoff failed: ${msg}`,\n },\n ],\n timestamp: Date.now(),\n }\n }\n }\n\n // ---------- webhook helpers ----------\n\n private async maybeFireWebhook(\n stateManager: RunStateManager,\n runId: string,\n nodeId: string,\n response: EngineResponse,\n ): Promise<void> {\n const state = await stateManager.read(runId, nodeId)\n if (state === null || state.webhook === undefined) return\n const event: WebhookEvent =\n response.status === 'done' ? 'done' : response.status === 'paused' ? 'paused' : 'failed'\n if (!state.webhook.events.includes(event)) return\n await this.dispatchWebhookWithRetries(stateManager, runId, nodeId, event, response, 1)\n }\n\n private async dispatchWebhookWithRetries(\n stateManager: RunStateManager,\n runId: string,\n nodeId: string,\n event: WebhookEvent,\n payload: EngineResponse,\n startAttempt: number,\n ): Promise<void> {\n const state = await stateManager.read(runId, nodeId)\n if (state === null || state.webhook === undefined) return\n const hook = state.webhook\n\n let attempt = startAttempt\n while (attempt <= MAX_ATTEMPTS) {\n const delay = RETRY_DELAYS_MS[attempt - 1] ?? 0\n if (delay > 0) {\n await new Promise((r) => setTimeout(r, delay))\n }\n\n const result = await this.webhookDispatcher.deliver({\n url: hook.url,\n event,\n payload,\n ...(hook.secret !== undefined ? { secret: hook.secret } : {}),\n ...(hook.headers !== undefined ? { headers: hook.headers } : {}),\n attempt,\n })\n\n // Append delivery record to state\n const latest = await stateManager.read(runId, nodeId)\n if (latest !== null && latest.webhook !== undefined) {\n const updated: WebhookConfig = {\n ...latest.webhook,\n deliveries: [...latest.webhook.deliveries, result.delivery],\n }\n await stateManager.update(runId, nodeId, { webhook: updated })\n }\n\n if (!result.shouldRetry) return\n attempt += 1\n }\n }\n\n /**\n * Shut down engine-owned background resources — currently just the\n * `McpManager`'s connection pool. Long-running hosts (servers,\n * daemons) SHOULD call this before dropping their engine reference,\n * otherwise MCP subprocesses leak until the parent process exits.\n *\n * Idempotent. Safe to call multiple times.\n */\n async shutdown(): Promise<void> {\n await this.mcpManager.shutdownAll()\n createLogger(this.config.logging).info('engine.shutdown complete', {\n mcpConnectedCount: this.mcpManager.connectedCount,\n })\n }\n\n /**\n * Structured orchestration — decomposes a task into a plan, executes\n * each step with specialized agents (planner, researcher, implementer,\n * verifier, reviewer, finalizer), enforces retry policies, and reverts\n * failed implementations.\n *\n * Unlike `run()` (single agent, best effort), `orchestrate()` guarantees\n * a result: done (all steps passed), partial (some failed + reverted),\n * or failed (planning failed entirely).\n *\n * Requires `config.orchestrator.enabled = true` or the method throws.\n * The orchestrator calls `engine.run()` internally for each phase —\n * it's a state machine layer above the existing agent loop.\n *\n * Pure JS — works on both Node.js and Cloudflare Workers.\n */\n async orchestrate(\n options: import('../orchestrator/types.js').OrchestrateOptions,\n ): Promise<import('../orchestrator/types.js').OrchestratorResult> {\n if (!this.config.orchestrator.enabled) {\n throw new ConfigError('engine.orchestrate() requires config.orchestrator.enabled = true')\n }\n const { orchestrate: doOrchestrate } = await import('../orchestrator/orchestrate.js')\n const storage = await this.buildStorage()\n const log = createLogger(this.config.logging)\n return doOrchestrate(this, options, this.config.orchestrator, storage.workspace, log)\n }\n\n /**\n * Emit a terminal log line per run. `done` is info; `paused` is info;\n * `failed` is error (with the error message in `meta.error`).\n */\n private logRunEnd(log: Logger, runId: string, nodeId: string, result: RunResult): void {\n if (result.status === 'done') {\n log.info('engine.run done', {\n runId,\n nodeId,\n turns: result.turns,\n tokensUsed: result.tokensUsed,\n })\n return\n }\n if (result.status === 'paused') {\n log.info('engine.run paused', { runId, nodeId, reason: result.reason })\n return\n }\n log.error('engine.run failed', {\n runId,\n nodeId,\n error: result.error.message,\n errorName: result.error.name,\n })\n }\n\n /**\n * Collect the names of all tools that will be registered — used to\n * populate the system prompt's tool-specific instructions BEFORE\n * building the registry itself (the prompt goes into the registry's\n * Agent tool as the child system prompt, so the prompt must exist\n * first).\n */\n private collectToolNames(mcpTools: ReadonlyArray<Tool>): Set<string> {\n const names = new Set<string>()\n const builtins = [\n // Bash is conditional on canSpawnProcesses() — but for prompt\n // generation we include it anyway; the prompt should mention\n // Bash even if it won't be registered (the model will get an\n // \"unknown tool\" error if it tries, which is informative).\n 'Bash',\n 'Read',\n 'Write',\n 'Edit',\n 'Glob',\n 'Grep',\n 'WebFetch',\n 'WebSearch',\n 'Agent',\n 'SkillPage',\n 'Sleep',\n 'NotebookEdit',\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n 'Memorize',\n 'Recall',\n 'ToolSearch',\n ]\n const enabled = new Set(this.config.tools.enabled)\n const disabled = new Set(this.config.tools.disabled)\n const wantAll = enabled.has('*')\n for (const name of builtins) {\n if (disabled.has(name)) continue\n if (wantAll || enabled.has(name)) names.add(name)\n }\n // ApiCall is conditional (Plan 020) — only present when config.api\n // has services. Per-run override via RunOptions.api can add it too\n // but that's handled at registry build time; for prompt generation\n // we include it when the engine-level config advertises services.\n if ((this.config.api?.services.length ?? 0) > 0) {\n if (!disabled.has('ApiCall') && (wantAll || enabled.has('ApiCall'))) {\n names.add('ApiCall')\n }\n }\n // FetchData is conditional (Plan 021) — only present when offload\n // is enabled at engine level. Per-run override adds at registry\n // build time; prompt listing covers the engine-level case.\n if (this.config.compaction.toolResultOffload?.enabled === true) {\n if (!disabled.has('FetchData') && (wantAll || enabled.has('FetchData'))) {\n names.add('FetchData')\n }\n }\n // SearchKnowledge / ReadKnowledge are conditional (Plan 023) —\n // only present when knowledge is enabled at engine level. The\n // actual tool registration also depends on per-run folders /\n // external links, but for prompt listing the engine-level flag\n // is the right granularity.\n if (this.config.knowledge?.enabled === true) {\n if (!disabled.has('SearchKnowledge') && (wantAll || enabled.has('SearchKnowledge'))) {\n names.add('SearchKnowledge')\n }\n if (!disabled.has('ReadKnowledge') && (wantAll || enabled.has('ReadKnowledge'))) {\n names.add('ReadKnowledge')\n }\n }\n for (const tool of this.config.tools.custom as ReadonlyArray<Tool>) {\n names.add(tool.name)\n }\n for (const tool of mcpTools) {\n if (disabled.has(tool.name)) continue\n if (wantAll || enabled.has(tool.name)) names.add(tool.name)\n }\n return names\n }\n\n /**\n * Resolve the subagent catalogue the Agent tool will dispatch against.\n *\n * Merge semantics:\n * 1. Start with `config.agents.builtins` — each name becomes a\n * placeholder definition that inherits the parent's system prompt.\n * (The only builtin v0.1 knows about is `'general-purpose'`.)\n * 2. If `config.agents.customPath` is set, load any `.md` files from\n * that directory (relative to the workspace adapter) and append as\n * full `AgentDefinition` records with their own system prompts.\n * 3. Custom-loaded agents with the same name as a builtin REPLACE the\n * builtin — last-wins dedup happens inside `createAgentTool`.\n *\n * Throws `ConfigError` if the merged list is empty.\n */\n private async resolveAgents(storage: EngineStorage): Promise<AgentDefinition[]> {\n const agents: AgentDefinition[] = []\n for (const name of this.config.agents.builtins) {\n agents.push({\n name,\n description:\n name === 'general-purpose'\n ? 'Default general-purpose subagent. Inherits the parent system prompt.'\n : `Builtin subagent: ${name}`,\n })\n }\n if (this.config.agents.customPath !== undefined) {\n const loaded = await loadAgents(storage.workspace, this.config.agents.customPath)\n agents.push(...loaded)\n }\n // In coordinator mode, auto-register a 'worker' agent with\n // restricted tools and a focused system prompt.\n if (isCoordinatorMode(this.config)) {\n agents.push(buildWorkerAgent(this.config.coordinator))\n }\n if (agents.length === 0) {\n throw new ConfigError(\n 'config.agents: at least one builtin or custom agent is required (got empty builtins and no customPath)',\n )\n }\n return agents\n }\n\n /**\n * Pick the effective gate callback:\n * 1. `EngineInternals.gateBeforeTool` (test seam) — highest priority\n * 2. `config.hooks.gateBeforeTool` (user config) — the public path\n * 3. `undefined` (no gate) — default\n */\n private resolveGate(): GateBeforeTool | undefined {\n if (this.internals.gateBeforeTool !== undefined) return this.internals.gateBeforeTool\n if (this.config.hooks.gateBeforeTool !== undefined) {\n // The schema types `gateBeforeTool` as `Function`; we know the\n // shape matches GateBeforeTool at runtime.\n return this.config.hooks.gateBeforeTool as unknown as GateBeforeTool\n }\n return undefined\n }\n\n /**\n * Start the run-level timeout. Returns an AbortController signal if\n * `runTimeoutMs > 0`, otherwise returns an empty handle. The caller\n * MUST invoke `clear()` in a finally block to cancel the timer.\n */\n private startRunTimeout(): { signal: AbortSignal | undefined; clear: () => void } {\n const ms = this.config.execution.runTimeoutMs\n if (ms <= 0) return { signal: undefined, clear: () => {} }\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), ms)\n // `unref()` lets node exit if this timer is the only thing pending.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (typeof (timer as any).unref === 'function') (timer as any).unref()\n return {\n signal: controller.signal,\n clear: () => clearTimeout(timer),\n }\n }\n\n private async firePostRunHook(\n runId: string,\n nodeId: string,\n result: RunResult,\n ctx: RunContext,\n logPath?: string,\n ): Promise<void> {\n const usage = ctx.getTokensUsed()\n const event: PostRunEvent = {\n runId,\n nodeId,\n status: result.status,\n tokensUsed: {\n input: usage.input,\n output: usage.output,\n ...(usage.cacheCreationInput !== undefined\n ? { cacheCreationInput: usage.cacheCreationInput }\n : {}),\n ...(usage.cacheReadInput !== undefined ? { cacheReadInput: usage.cacheReadInput } : {}),\n },\n turnsUsed: ctx.getTurnCount(),\n ...(result.status === 'done' ? { output: result.output } : {}),\n ...(result.status === 'failed' ? { error: result.error } : {}),\n ...(result.status === 'done' ? { toolCallCount: result.turns } : {}),\n ...(logPath !== undefined ? { transcriptPath: logPath } : {}),\n }\n await dispatchHooks(this.config.hooks.postRun, event)\n }\n\n private async finalizeResult(\n loopResult: Awaited<ReturnType<typeof agentLoop>>,\n writer: TranscriptWriter,\n _logPath: string,\n jsonOptions?: { outputFormat?: 'text' | 'json'; outputSchema?: import('zod').ZodTypeAny },\n ): Promise<RunResult> {\n if (loopResult.status === 'done') {\n await writer.setStatus('done')\n\n // Structured output: parse + validate JSON\n let data: unknown\n if (jsonOptions?.outputFormat === 'json') {\n const parsed = tryParseJSON(loopResult.output)\n if (parsed.ok) {\n if (jsonOptions.outputSchema) {\n const validated = validateOutput(parsed.value, jsonOptions.outputSchema)\n data = validated.ok ? validated.data : undefined\n } else {\n data = parsed.value\n }\n }\n // If parsing failed, data stays undefined — caller checks result.data\n }\n\n return {\n status: 'done',\n output: loopResult.output,\n ...(data !== undefined ? { data } : {}),\n tokensUsed: loopResult.tokensUsed,\n turns: loopResult.turns,\n }\n }\n if (loopResult.status === 'paused') {\n await writer.setStatus('paused')\n return {\n status: 'paused',\n snapshot: loopResult.snapshot,\n reason: loopResult.reason,\n }\n }\n await writer.setStatus('failed')\n return {\n status: 'failed',\n error: loopResult.error,\n transcript: loopResult.transcript,\n }\n }\n\n /**\n * Pick the effective `SkillSource` for a run.\n *\n * - Per-run override (`options.skills`) → `InlineSkillSource`\n * - else `config.skills.autoload === true` → `StorageSkillSource`\n * - else → undefined (SkillPage tool not registered)\n */\n private resolveSkillSource(\n overrides: ReadonlyArray<import('../skills/source.js').SkillOverride> | undefined,\n storage: EngineStorage,\n ): SkillSource | undefined {\n if (overrides !== undefined) {\n return new InlineSkillSource(overrides, {\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n ...(this.config.skills.allowedHosts !== undefined\n ? { allowedHosts: this.config.skills.allowedHosts }\n : {}),\n })\n }\n if (this.config.skills.autoload) {\n return new StorageSkillSource({\n storage,\n ...(this.config.skills.path !== undefined ? { baseDir: this.config.skills.path } : {}),\n })\n }\n return undefined\n }\n\n /**\n * Plan 020 — resolve the effective ApiCall config for a run.\n *\n * Precedence (each field independently):\n * RunOptions.api.X > config.api.X\n *\n * If neither side provides any services, returns undefined so the\n * tool isn't registered at all. Env + resolveAuth + hooks flow\n * through untouched — they never hit the Zod schema.\n */\n /**\n * Plan 021 — resolve the effective tool-result offload config.\n *\n * Precedence (each field independently):\n * RunOptions.compaction.toolResultOffload.X >\n * config.compaction.toolResultOffload.X\n *\n * When neither side enables offload, returns undefined and no\n * `FetchData` tool is registered.\n */\n private resolveOffloadConfig(\n // Run + Resume share the same override shape, so we pick either.\n override: NonNullable<RunOptions['compaction']>['toolResultOffload'],\n ): import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1 | undefined {\n const base = this.config.compaction.toolResultOffload\n if (override === undefined && base === undefined) return undefined\n const enabled = override?.enabled ?? base?.enabled ?? false\n if (!enabled) return undefined\n const thresholdBytes = override?.thresholdBytes ?? base?.thresholdBytes ?? 2048\n const maxPreviewChars = override?.maxPreviewChars ?? base?.maxPreviewChars ?? 500\n const summarizer = override?.summarizer ?? base?.summarizer\n return {\n enabled: true,\n thresholdBytes,\n maxPreviewChars,\n ...(summarizer !== undefined ? { summarizer } : {}),\n }\n }\n\n /**\n * Plan 023 — resolve the effective runtime knowledge bundle for a\n * single run.\n *\n * Engine-level config (`config.knowledge`) carries the capability\n * flag + scalar caps. The actual folders + external links are\n * RUNTIME-only, supplied via `RunOptions.knowledge`. Returning\n * `undefined` means \"don't register the knowledge tools\" — callers\n * skip the bundle entirely.\n *\n * Three gates must all pass:\n * 1. `config.knowledge.enabled === true` (engine opt-in)\n * 2. `storage.knowledge !== undefined` (adapter was built)\n * 3. There IS something to look at — at least one folder OR\n * one external link supplied for this run.\n */\n private resolveKnowledgeRuntime(\n // RunOptions['knowledge'] === ResumeOptions['knowledge'] — same\n // shape on both sides (RunKnowledgeOptionsV1).\n override: RunOptions['knowledge'],\n storage: EngineStorage,\n ):\n | {\n readonly adapter: import('../storage/interface.js').StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxSearchResults: number\n readonly maxReadBytes: number\n }\n | undefined {\n if (this.config.knowledge?.enabled !== true) return undefined\n if (storage.knowledge === undefined) return undefined\n const folders = override?.folders ?? []\n const external = override?.external ?? []\n if (folders.length === 0 && external.length === 0) return undefined\n return {\n adapter: storage.knowledge,\n folders,\n external,\n maxSearchResults: this.config.knowledge.maxSearchResults,\n maxReadBytes: this.config.knowledge.maxReadBytes,\n }\n }\n\n private resolveApiConfig(\n override: RunOptions['api'] | ResumeOptions['api'],\n ): ResolvedApiConfig | undefined {\n const base = this.config.api\n if (override === undefined && base === undefined) return undefined\n const services = override?.services ?? base?.services\n if (services === undefined || services.length === 0) return undefined\n const env = override?.env ?? base?.env\n const resolveAuth = override?.resolveAuth ?? base?.resolveAuth\n const onRequest =\n (override as { onRequest?: ResolvedApiConfig['onRequest'] })?.onRequest ?? base?.onRequest\n const onResponse =\n (override as { onResponse?: ResolvedApiConfig['onResponse'] })?.onResponse ?? base?.onResponse\n return {\n services,\n ...(env !== undefined ? { env } : {}),\n ...(resolveAuth !== undefined ? { resolveAuth } : {}),\n ...(onRequest !== undefined ? { onRequest } : {}),\n ...(onResponse !== undefined ? { onResponse } : {}),\n ...(base?.maxResponseBytes !== undefined ? { maxResponseBytes: base.maxResponseBytes } : {}),\n }\n }\n\n /**\n * Build a throttled heartbeat callback for agentLoop's `onProgress` hook.\n *\n * Only writes to `state.json` if one already exists for this run\n * (i.e., the run was started via `engine.start()` or `resumeAsync()`).\n * Sync `engine.run()` callers without a pre-existing state file get a\n * no-op heartbeat.\n *\n * Throttled to at most one write per 500ms AND only when activity\n * changes, so R2 writes stay cheap even for long runs.\n */\n private buildHeartbeat(\n storage: EngineStorage,\n runId: string,\n nodeId: string,\n ): (p: import('./agentLoop.js').LoopProgress) => Promise<void> {\n const stateManager = new RunStateManager(storage.workspace)\n let lastWriteAt = 0\n let lastActivity: string | undefined\n let lastTool: string | undefined\n const MIN_INTERVAL_MS = 500\n return async (progress) => {\n const now = Date.now()\n const activityChanged =\n progress.currentActivity !== lastActivity || progress.lastTool !== lastTool\n if (!activityChanged && now - lastWriteAt < MIN_INTERVAL_MS) return\n lastWriteAt = now\n lastActivity = progress.currentActivity\n lastTool = progress.lastTool\n // stateManager.heartbeat is a no-op when state.json doesn't exist.\n try {\n await stateManager.heartbeat(runId, nodeId, {\n turns: progress.turns,\n tokensUsed: progress.tokensUsed,\n currentActivity: progress.currentActivity,\n ...(progress.lastTool !== undefined ? { lastTool: progress.lastTool } : {}),\n })\n } catch {\n /* heartbeat is best-effort */\n }\n }\n }\n\n /**\n * Build the engine's storage pair. Uses the `EngineInternals.buildStorage`\n * override when provided (for Workers / custom adapters), otherwise\n * defers to the standard `createEngineStorage()` factory.\n */\n private async buildStorage(): Promise<EngineStorage> {\n if (this.internals.buildStorage !== undefined) {\n return this.internals.buildStorage()\n }\n return createEngineStorage(this.config.storage, {\n withKnowledge: this.config.knowledge?.enabled === true,\n })\n }\n\n private buildClient(): ModelAdapter {\n return createModelAdapter(this.config.model, {\n ...(this.internals.fetch !== undefined ? { fetch: this.internals.fetch } : {}),\n })\n }\n}\n\ninterface BuildRegistryOptions {\n readonly config: ResolvedConfig\n readonly storage: EngineStorage\n readonly client: ModelAdapter\n readonly parentLogPath: string\n readonly parentAgentId: string | null\n readonly subagentRegistry: SubagentRegistry\n readonly system: string\n readonly agents: ReadonlyArray<AgentDefinition>\n readonly mcpTools: ReadonlyArray<Tool>\n readonly memory: import('../memory/memoryConfig.js').SmartMemory\n /**\n * Gate to propagate to subagents when\n * `config.hooks.propagateGateToSubagents === true`. Undefined\n * otherwise, even if the parent has a gate configured.\n */\n readonly subagentGate?: GateBeforeTool\n /**\n * SkillSource powering the `SkillPage` tool. When undefined the\n * tool is not registered. The engine constructs either a\n * `StorageSkillSource` (default when `config.skills.autoload`) or an\n * `InlineSkillSource` (when `RunOptions.skills` is set).\n */\n readonly skillSource?: import('../skills/source.js').SkillSource\n /**\n * Plan 020 — effective api config for this run. When defined AND\n * `services` is non-empty, the engine auto-registers the `ApiCall`\n * built-in tool. Env + resolveAuth flow through here.\n */\n readonly apiConfig?: ResolvedApiConfig\n /**\n * Optional fetch override. Threaded into tools that issue HTTP\n * calls (currently just `ApiCall`) so Workers / test harnesses\n * can inject their own implementation.\n */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Plan 021 — tool-result offload config. When enabled, the\n * engine auto-registers the `FetchData` built-in bound to the\n * parent's log path. Subagents rebuild their own `FetchData`\n * inside `runAgent` so each agent can only rehydrate its own\n * offloaded blobs.\n */\n readonly toolResultOffload?: import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n /**\n * Plan 023 — knowledge runtime bundle. When provided, the engine\n * auto-registers `SearchKnowledge` + `ReadKnowledge` on BOTH the\n * parent and child registries. Folders + externals are shared\n * across all agents in the run (no per-agent rebuild needed —\n * the index cache lives inside the tool factory closure and is\n * harmless to share).\n */\n readonly knowledge?: {\n readonly adapter: import('../storage/interface.js').StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxSearchResults: number\n readonly maxReadBytes: number\n }\n}\n\nfunction buildToolRegistry(options: BuildRegistryOptions): ToolRegistry {\n const {\n config,\n storage,\n client,\n parentLogPath,\n parentAgentId,\n subagentRegistry,\n system,\n agents,\n mcpTools,\n memory,\n subagentGate,\n } = options\n const registry = new ToolRegistry()\n const enabled = new Set(config.tools.enabled)\n const disabled = new Set(config.tools.disabled)\n const wantAll = enabled.has('*')\n\n const childRegistry = new ToolRegistry()\n // In coordinator mode:\n // - Workers get ONLY tools listed in workerTools (implementation tools)\n // - Coordinator gets ONLY delegation tools (Agent, Tasks, Memory, ToolSearch, Sleep, SkillPage)\n // - This is CODE-ENFORCED, not prompt-enforced — the coordinator physically\n // cannot call Read/Write/Edit/Bash because they're not in its registry.\n const isCoord = isCoordinatorMode(config)\n const workerToolSet = isCoord ? new Set(config.coordinator.workerTools) : null\n const COORDINATOR_TOOLS = new Set([\n 'Agent',\n 'SendMessage',\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n 'Memorize',\n 'Recall',\n 'ToolSearch',\n 'Sleep',\n 'SkillPage',\n 'WebSearch',\n ])\n\n // TaskStore — shared across all task tools within this run.\n const taskStore = new TaskStore({\n storage: storage.workspace,\n logPath: parentLogPath,\n })\n\n // FileTracker — shared between Read and Write for staleness detection.\n const fileTracker = new FileTracker()\n\n // Tools that require subprocess spawning (Bash, Grep-via-ripgrep)\n // are registered on every runtime. When the host can't spawn\n // (Workers without nodejs_compat, or nodejs_compat where spawn\n // probes fail), `withCapabilityCheck` swaps in a capability stub so\n // the tool stays in the catalogue: the model still sees it and can\n // decide whether to call it, and the engine can intercept the call\n // to hand off to a Node runner when `config.runner` is set\n // (Plan 019). Tools not flagged `requiresNode` pass through.\n const spawnAvailable = canSpawnProcesses()\n\n const candidates: Array<{ name: string; tool: Tool }> = [\n // Bash — requires child_process.spawn. Stubbed on Workers.\n { name: 'Bash', tool: withCapabilityCheck(createBashTool(), spawnAvailable) },\n {\n name: 'Read',\n tool: createFileReadTool({ storage: storage.workspace, tracker: fileTracker }),\n },\n {\n name: 'Write',\n tool: createFileWriteTool({ storage: storage.workspace, tracker: fileTracker }),\n },\n { name: 'Edit', tool: createFileEditTool(storage.workspace) },\n { name: 'Glob', tool: createGlobTool(storage.workspace) },\n { name: 'Grep', tool: createGrepTool(storage.workspace) },\n { name: 'WebFetch', tool: createWebFetchTool() },\n { name: 'WebSearch', tool: createWebSearchTool() },\n { name: 'Sleep', tool: createSleepTool() },\n { name: 'NotebookEdit', tool: createNotebookEditTool(storage.workspace) },\n { name: 'TaskCreate', tool: createTaskCreateTool(taskStore) },\n { name: 'TaskGet', tool: createTaskGetTool(taskStore) },\n { name: 'TaskList', tool: createTaskListTool(taskStore) },\n { name: 'TaskUpdate', tool: createTaskUpdateTool(taskStore) },\n { name: 'Memorize', tool: createMemorizeTool(memory) },\n { name: 'Recall', tool: createRecallTool(memory) },\n ]\n\n for (const c of candidates) {\n if (disabled.has(c.name)) continue\n if (wantAll || enabled.has(c.name)) {\n if (isCoord) {\n // Coordinator mode: split tools between coordinator and workers.\n // Coordinator gets only delegation/management tools.\n // Workers get only implementation tools from workerTools config.\n if (COORDINATOR_TOOLS.has(c.name)) {\n registry.register(c.tool)\n }\n if (workerToolSet!.has(c.name)) {\n childRegistry.register(c.tool)\n }\n } else {\n // Normal mode: parent gets everything, child gets everything minus Agent.\n registry.register(c.tool)\n childRegistry.register(c.tool)\n }\n }\n }\n\n // SkillPage tool — registered when a SkillSource is provided (either\n // the disk-backed default when skills.autoload is on, or the inline\n // override when RunOptions.skills was supplied). It's available to\n // BOTH parent and children since loading a skill page is a pure read\n // and doesn't recurse.\n if (options.skillSource !== undefined) {\n const skillTool = createSkillPageTool({ source: options.skillSource })\n if (!disabled.has('SkillPage') && (wantAll || enabled.has('SkillPage'))) {\n registry.register(skillTool)\n childRegistry.register(skillTool)\n }\n }\n\n // ApiCall tool (Plan 020) — registered when apiConfig has services.\n // Pure HTTP fetch, works identically on Workers and Node; no\n // requiresNode. Available to parent + children so subagents can\n // call external APIs too.\n if (options.apiConfig !== undefined && options.apiConfig.services.length > 0) {\n if (!disabled.has('ApiCall') && (wantAll || enabled.has('ApiCall'))) {\n const apiTool = createApiCallTool({\n services: options.apiConfig.services,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n ...(options.apiConfig.env !== undefined ? { env: options.apiConfig.env } : {}),\n ...(options.apiConfig.resolveAuth !== undefined\n ? { resolveAuth: options.apiConfig.resolveAuth }\n : {}),\n ...(options.apiConfig.onRequest !== undefined\n ? { onRequest: options.apiConfig.onRequest }\n : {}),\n ...(options.apiConfig.onResponse !== undefined\n ? { onResponse: options.apiConfig.onResponse }\n : {}),\n ...(options.apiConfig.maxResponseBytes !== undefined\n ? { maxResponseBytes: options.apiConfig.maxResponseBytes }\n : {}),\n })\n registry.register(apiTool)\n childRegistry.register(apiTool)\n }\n }\n\n // FetchData tool (Plan 021) — registered on the PARENT registry\n // only, bound to the parent's log path. Subagents reconstruct\n // their own FetchData bound to `childLogPath` inside `runAgent`\n // so each agent can only rehydrate its own offloaded blobs.\n if (options.toolResultOffload?.enabled === true) {\n if (!disabled.has('FetchData') && (wantAll || enabled.has('FetchData'))) {\n const fetchDataTool = createFetchDataTool({\n storage: storage.workspace,\n logPath: options.parentLogPath,\n })\n registry.register(fetchDataTool)\n // NOTE: intentionally NOT registered on childRegistry — the\n // subagent runner builds its own child-scoped instance.\n }\n }\n\n // SearchKnowledge + ReadKnowledge tools (Plan 023) — registered\n // on BOTH parent and child registries. Unlike FetchData these\n // tools are stateless w.r.t. log paths: the knowledge adapter is\n // tenant-scoped and shared, and the per-call index/file caches\n // live in the factory closure (cheap to share across agents in\n // one run). External link `headers` close over the factory and\n // never reach any persisted surface — see externalLinkSecrets test.\n if (options.knowledge !== undefined) {\n const k = options.knowledge\n if (!disabled.has('SearchKnowledge') && (wantAll || enabled.has('SearchKnowledge'))) {\n const searchTool = createSearchKnowledgeTool({\n adapter: k.adapter,\n folders: k.folders,\n external: k.external,\n maxSearchResults: k.maxSearchResults,\n })\n registry.register(searchTool)\n childRegistry.register(searchTool)\n }\n if (!disabled.has('ReadKnowledge') && (wantAll || enabled.has('ReadKnowledge'))) {\n const readTool = createReadKnowledgeTool({\n adapter: k.adapter,\n folders: k.folders,\n external: k.external,\n maxReadBytes: k.maxReadBytes,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n })\n registry.register(readTool)\n childRegistry.register(readTool)\n }\n }\n\n // The Agent tool is registered ONLY on the parent registry.\n const agentTool = createAgentTool({\n storage: storage.workspace,\n client,\n childRegistry,\n parentLogPath,\n parentAgentId,\n subagentRegistry,\n system,\n maxTurns: config.execution.maxTurns,\n contextLimit: 200_000,\n turnTimeoutMs: config.execution.turnTimeoutMs,\n flushPolicy: config.transcript.flushPolicy,\n idleFlushMs: config.transcript.idleFlushMs,\n agents,\n coordinatorMode: isCoordinatorMode(config),\n ...(subagentGate !== undefined ? { gateBeforeTool: subagentGate } : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n })\n if (!disabled.has('Agent') && (wantAll || enabled.has('Agent'))) {\n registry.register(agentTool)\n }\n\n // SendMessage tool — registered on parent only (like Agent).\n // Enables inter-agent communication within coordinator workflows.\n const sendMessageTool = createSendMessageTool({ registry: subagentRegistry })\n if (!disabled.has('SendMessage') && (wantAll || enabled.has('SendMessage'))) {\n registry.register(sendMessageTool)\n }\n\n // Custom tools — registered as-is on both parent and child registries.\n for (const custom of config.tools.custom) {\n registry.register(custom as Tool)\n childRegistry.register(custom as Tool)\n }\n\n // MCP-sourced tools — already adapted by McpManager, already prefixed\n // `mcp__{server}__{tool}`. Registered on both parent and child so\n // subagents can also dispatch to external tool servers.\n for (const tool of mcpTools) {\n if (disabled.has(tool.name)) continue\n if (wantAll || enabled.has(tool.name)) {\n registry.register(tool)\n childRegistry.register(tool)\n }\n }\n\n // ToolSearch — needs the populated registry as input, so it's\n // registered after all other tools. Available to both parent and child.\n if (!disabled.has('ToolSearch') && (wantAll || enabled.has('ToolSearch'))) {\n const toolSearchTool = createToolSearchTool(registry)\n registry.register(toolSearchTool)\n childRegistry.register(createToolSearchTool(childRegistry))\n }\n\n return registry\n}\n","/**\n * Model adapter factory — routes config to the right adapter.\n *\n * Same pattern as storage/factory.ts:\n * createEngineStorage(config.storage) → StorageAdapter\n * createModelAdapter(config.model) → ModelAdapter\n */\n\nimport type { ResolvedModelConfig } from '../config/types.js'\nimport { selectProvider } from '../api/providerSelector.js'\nimport type { ModelAdapter } from './adapter.js'\nimport { AnthropicAdapter } from './anthropicAdapter.js'\nimport { AISdkAdapter } from './aiSdkAdapter.js'\n\nexport interface CreateModelAdapterOptions {\n /** Custom fetch for the Anthropic adapter (OpenRouter auth override). */\n readonly fetch?: typeof globalThis.fetch | undefined\n}\n\n/**\n * Create a ModelAdapter from the resolved model config.\n *\n * Routing:\n * - 'anthropic' (no sdk override) → AnthropicAdapter (@anthropic-ai/sdk)\n * - 'proxy' → AnthropicAdapter with baseURL\n * - 'openai', 'google', 'openai-compatible' → AISdkAdapter\n * - 'anthropic' + sdk: 'ai-sdk' → AISdkAdapter with @ai-sdk/anthropic\n */\nexport function createModelAdapter(\n config: ResolvedModelConfig,\n options: CreateModelAdapterOptions = {},\n): ModelAdapter {\n const provider = config.provider\n const sdk = (config as { sdk?: string }).sdk\n\n // Legacy path: Anthropic SDK (default for 'anthropic' and 'proxy')\n if ((provider === 'anthropic' && sdk !== 'ai-sdk') || provider === 'proxy') {\n const plan = selectProvider(config)\n return new AnthropicAdapter({\n plan,\n ...(options.fetch !== undefined ? { fetch: options.fetch } : {}),\n })\n }\n\n // AI SDK path: everything else\n return new AISdkAdapter({\n provider: provider === 'anthropic' ? 'anthropic' : provider,\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxRetries: config.maxRetries,\n })\n}\n","/**\n * providerSelector — translate a `ResolvedModelConfig` into a typed\n * `ProviderPlan` describing what API client to construct and how.\n *\n * The plan is a thin, validated intermediate between user config and the\n * actual SDK construction so that:\n * 1. Invalid combinations (proxy provider without baseURL, anthropic\n * without apiKey) are rejected at this layer, not at runtime inside\n * the SDK's message send\n * 2. Deferred backends (Bedrock, Vertex, Foundry) can be flagged here\n * with a clear `NotImplementedError` pointing at the v0.2 milestone\n * 3. Tests can exercise selection logic independently of actual client\n * construction\n */\n\nimport type { ResolvedModelConfig } from '../config/types.js'\nimport { ConfigError, NotImplementedError } from '../engine/errors.js'\n\nexport interface AnthropicProviderPlan {\n readonly kind: 'anthropic'\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL: string | undefined\n readonly maxTokens: number\n readonly temperature: number\n readonly maxRetries: number\n}\n\nexport interface ProxyProviderPlan {\n readonly kind: 'proxy'\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL: string\n readonly maxTokens: number\n readonly temperature: number\n readonly maxRetries: number\n}\n\nexport type ProviderPlan = AnthropicProviderPlan | ProxyProviderPlan\n\nexport function selectProvider(config: ResolvedModelConfig): ProviderPlan {\n switch (config.provider) {\n case 'anthropic':\n if (config.apiKey.length === 0) {\n throw new ConfigError('anthropic provider requires a non-empty apiKey')\n }\n return {\n kind: 'anthropic',\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n maxRetries: config.maxRetries,\n }\n\n case 'proxy':\n if (config.baseURL === undefined || config.baseURL.length === 0) {\n throw new ConfigError('proxy provider requires a non-empty baseURL')\n }\n return {\n kind: 'proxy',\n modelId: config.modelId,\n apiKey: config.apiKey,\n baseURL: config.baseURL,\n maxTokens: config.maxTokens,\n temperature: config.temperature,\n maxRetries: config.maxRetries,\n }\n\n case 'bedrock':\n throw new NotImplementedError('bedrock provider', 'v0.2')\n\n case 'vertex':\n throw new NotImplementedError('vertex provider', 'v0.2')\n\n default:\n // New providers (openai, google, openai-compatible) go through\n // the AI SDK adapter, not selectProvider. If we get here, the\n // factory routed incorrectly.\n throw new ConfigError(\n `selectProvider: \"${config.provider}\" should use the AI SDK adapter, not the Anthropic SDK`,\n )\n }\n}\n","/**\n * Error taxonomy for la-machina-engine.\n *\n * Every thrown error must be a subclass of `EngineError`, so callers can\n * `instanceof` discriminate at the library boundary. Phase 1 defines only\n * the errors needed for config resolution and unimplemented methods.\n * Later phases extend this hierarchy (see plan 002 §4 Phase 4).\n */\n\nexport class EngineError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = this.constructor.name\n this.code = code\n }\n}\n\n/**\n * Thrown when config is invalid or incomplete. Raised by `initEngine()` when\n * `apiKey` cannot be resolved, or when schema validation fails.\n */\nexport class ConfigError extends EngineError {\n constructor(message: string) {\n super('ERR_CONFIG', message)\n }\n}\n\n/**\n * Thrown when a method is called in a phase where its implementation has\n * not yet landed. Used by `engine.run()` and `engine.resume()` during\n * Phases 1–6 before the loop is wired, and by provider selectors for\n * backends deferred to v0.2 (Bedrock, Vertex, Foundry).\n */\nexport class NotImplementedError extends EngineError {\n constructor(feature: string, target: string) {\n super('ERR_NOT_IMPLEMENTED', `${feature} is not implemented until ${target}`)\n }\n}\n\n// ---------- API errors (Phase 4) ----------\n\n/**\n * Thrown when the provider rejects a request with HTTP 401/403 (missing\n * or invalid API key). Callers should not retry.\n */\nexport class AuthError extends EngineError {\n constructor(message: string) {\n super('ERR_AUTH', message)\n }\n}\n\n/**\n * Thrown when the provider returns HTTP 429 (rate limited). Callers\n * should back off and retry. `retryAfterMs` reflects the provider's\n * hint when available, otherwise null.\n */\nexport class RateLimitError extends EngineError {\n readonly retryAfterMs: number | null\n\n constructor(message: string, retryAfterMs: number | null = null) {\n super('ERR_RATE_LIMIT', message)\n this.retryAfterMs = retryAfterMs\n }\n}\n\n/**\n * Thrown when a streaming response can't be parsed into a normalized\n * event — typically malformed SSE or a JSON parse failure in a delta.\n * This is a hard error; the stream is not recoverable.\n */\nexport class StreamParseError extends EngineError {\n constructor(message: string) {\n super('ERR_STREAM_PARSE', message)\n }\n}\n\n/**\n * Thrown when a streaming response ends without a terminal event\n * (`message_stop`). The caller cannot know whether the assistant\n * actually finished — almost always safer to fail the run and retry.\n */\nexport class StreamIncompleteError extends EngineError {\n constructor(message: string) {\n super('ERR_STREAM_INCOMPLETE', message)\n }\n}\n\n/**\n * Generic provider-side API error — non-auth, non-rate-limit failures\n * like 500s, network drops, and unrecognized shapes. `status` is the\n * HTTP status code when available, otherwise null.\n */\nexport class ApiError extends EngineError {\n readonly status: number | null\n\n constructor(message: string, status: number | null = null) {\n super('ERR_API', message)\n this.status = status\n }\n}\n\n/**\n * Thrown when a run exceeds `execution.runTimeoutMs`. The agent loop is\n * aborted at the next checkpoint (top of the turn loop or after a tool\n * dispatch). The transcript so far is preserved.\n */\nexport class RunTimeoutError extends EngineError {\n readonly timeoutMs: number\n\n constructor(timeoutMs: number) {\n super('ERR_RUN_TIMEOUT', `Run exceeded runTimeoutMs=${timeoutMs}`)\n this.timeoutMs = timeoutMs\n }\n}\n\n/**\n * Thrown from inside the Agent tool when a subagent's loop paused due to\n * a gate denial. The parent's agentLoop catches this and surfaces it as\n * its own `paused` result, carrying the child's snapshot for future\n * resume support.\n *\n * Only thrown when `hooks.propagateGateToSubagents: true` is set on the\n * parent engine config. Without that flag, subagents can't use the\n * parent's gate and this error never appears.\n */\nexport class SubagentPausedError extends EngineError {\n readonly childSnapshot: import('./types.js').RunSnapshot\n readonly parentToolUseId: string\n readonly subagentType: string\n\n constructor(params: {\n childSnapshot: import('./types.js').RunSnapshot\n parentToolUseId: string\n subagentType: string\n }) {\n super(\n 'ERR_SUBAGENT_PAUSED',\n `Subagent \"${params.subagentType}\" paused at tool \"${params.childSnapshot.pendingToolCall?.toolName ?? 'unknown'}\"`,\n )\n this.childSnapshot = params.childSnapshot\n this.parentToolUseId = params.parentToolUseId\n this.subagentType = params.subagentType\n }\n}\n","/**\n * AnthropicAdapter — wraps the existing @anthropic-ai/sdk client as a\n * ModelAdapter. Default provider.\n */\n\nimport { AnthropicClient, type AnthropicClientOptions } from '../api/anthropicClient.js'\nimport type { ModelAdapter, StreamRequest } from './adapter.js'\nimport type { NormalizedEvent } from '../api/streaming.js'\n\nexport class AnthropicAdapter implements ModelAdapter {\n private readonly client: AnthropicClient\n\n constructor(options: AnthropicClientOptions) {\n this.client = new AnthropicClient(options)\n }\n\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n yield* this.client.streamMessage(request as any)\n }\n}\n","/**\n * AnthropicClient — thin wrapper around `@anthropic-ai/sdk`.\n *\n * Responsibilities:\n * 1. Construct an `Anthropic` instance from a `ProviderPlan` (anthropic\n * first-party or proxy). Passes a custom `fetch` when supplied so\n * tests can drive the client with a scripted fetch without any real\n * network I/O.\n * 2. Expose `streamMessage(request)` as an async generator of\n * `NormalizedEvent`, with Anthropic SDK stream events passed through\n * `normalizeStream` on the way out.\n * 3. Translate SDK-level errors into the engine's typed error taxonomy\n * (`AuthError`, `RateLimitError`, `ApiError`, etc.) so callers can\n * discriminate without instanceof-checking third-party classes.\n *\n * The client is stateless — each `streamMessage` call is independent.\n * Callers should reuse a single `AnthropicClient` per run; the\n * underlying SDK already pools HTTP connections internally.\n */\n\nimport Anthropic, {\n APIError,\n AuthenticationError as SdkAuthenticationError,\n PermissionDeniedError as SdkPermissionDeniedError,\n RateLimitError as SdkRateLimitError,\n} from '@anthropic-ai/sdk'\nimport type {\n MessageCreateParamsStreaming,\n MessageStreamEvent,\n Tool,\n} from '@anthropic-ai/sdk/resources/messages'\nimport { ApiError, AuthError, EngineError, RateLimitError } from '../engine/errors.js'\nimport { computeBetaHeaders } from './betaHeaders.js'\nimport type { ProviderPlan } from './providerSelector.js'\nimport { normalizeStream, type NormalizedEvent } from './streaming.js'\n\nexport interface StreamRequest {\n readonly messages: MessageCreateParamsStreaming['messages']\n readonly system?: MessageCreateParamsStreaming['system']\n readonly tools?: Tool[]\n readonly maxTokens?: number\n readonly temperature?: number\n}\n\nexport interface AnthropicClientOptions {\n readonly plan: ProviderPlan\n /** Custom fetch for tests. Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport class AnthropicClient {\n private readonly plan: ProviderPlan\n private readonly sdk: Anthropic\n\n constructor(options: AnthropicClientOptions) {\n this.plan = options.plan\n\n const baseURL = this.plan.kind === 'proxy' ? this.plan.baseURL : this.plan.baseURL\n\n const sdkOptions: ConstructorParameters<typeof Anthropic>[0] = {\n apiKey: this.plan.apiKey,\n // SDK handles retry with exponential backoff on 429/500.\n // Default: 2 retries. Configurable via config.model.maxRetries.\n maxRetries: this.plan.maxRetries,\n }\n if (baseURL !== undefined) sdkOptions.baseURL = baseURL\n if (options.fetch !== undefined) sdkOptions.fetch = options.fetch\n\n this.sdk = new Anthropic(sdkOptions)\n }\n\n /**\n * Stream a message and yield normalized events. The caller should\n * consume the iterator to completion or abort via AbortSignal upstream.\n */\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n const betas = computeBetaHeaders(\n this.plan.kind === 'proxy' ? this.plan.baseURL : this.plan.baseURL,\n this.plan.modelId,\n )\n\n const params: MessageCreateParamsStreaming = {\n model: this.plan.modelId,\n max_tokens: request.maxTokens ?? this.plan.maxTokens,\n temperature: request.temperature ?? this.plan.temperature,\n messages: request.messages,\n stream: true,\n ...(request.system !== undefined ? { system: request.system } : {}),\n ...(request.tools !== undefined ? { tools: request.tools } : {}),\n }\n\n const requestOptions: { headers?: Record<string, string> } = {}\n if (betas.length > 0) {\n requestOptions.headers = { 'anthropic-beta': betas.join(',') }\n }\n\n let stream: AsyncIterable<MessageStreamEvent>\n try {\n stream = this.sdk.messages.stream(params, requestOptions)\n } catch (err) {\n throw mapSdkError(err)\n }\n\n try {\n yield* normalizeStream(wrapSdkErrors(stream))\n } catch (err) {\n if (err instanceof EngineError) throw err\n throw mapSdkError(err)\n }\n }\n}\n\n/**\n * Wrap an SDK stream in an async iterable that translates SDK errors\n * into engine errors as they occur during iteration.\n */\nasync function* wrapSdkErrors(\n source: AsyncIterable<MessageStreamEvent>,\n): AsyncGenerator<MessageStreamEvent, void, void> {\n try {\n for await (const event of source) yield event\n } catch (err) {\n throw mapSdkError(err)\n }\n}\n\nfunction mapSdkError(err: unknown): Error {\n if (err instanceof EngineError) return err\n if (err instanceof SdkAuthenticationError || err instanceof SdkPermissionDeniedError) {\n return new AuthError(err.message)\n }\n if (err instanceof SdkRateLimitError) {\n const retryAfterMs = parseRetryAfter(err.headers)\n return new RateLimitError(err.message, retryAfterMs)\n }\n if (err instanceof APIError) {\n const status = typeof err.status === 'number' ? err.status : null\n return new ApiError(err.message, status)\n }\n if (err instanceof Error) {\n return new ApiError(err.message, null)\n }\n return new ApiError(String(err), null)\n}\n\nfunction parseRetryAfter(headers: unknown): number | null {\n if (headers === null || typeof headers !== 'object') return null\n const h = headers as { get?: (key: string) => string | null; 'retry-after'?: unknown }\n let raw: string | null | undefined\n if (typeof h.get === 'function') {\n raw = h.get('retry-after')\n } else if (typeof h['retry-after'] === 'string') {\n raw = h['retry-after']\n }\n if (raw === null || raw === undefined || raw === '') return null\n const seconds = Number(raw)\n if (Number.isFinite(seconds)) return Math.round(seconds * 1000)\n return null\n}\n","/**\n * Beta headers — Anthropic-specific `anthropic-beta` header values.\n *\n * Each header toggles an opt-in feature on the Anthropic API (1M context\n * window, interleaved thinking, tool use enhancements, etc.). They are\n * recognized ONLY by `api.anthropic.com`. Sending them to a third-party\n * proxy (OpenRouter, LiteLLM, a custom gateway) returns HTTP 400.\n *\n * This module preserves La-Machina's behavior from commit 6efec3b:\n *\n * - First-party base URL → include the engine's default beta set.\n * - Non-first-party base URL → strip all defaults; only honor explicit\n * `ANTHROPIC_BETAS=...` user opt-in.\n *\n * The \"default beta set\" is deliberately small. The engine ships with:\n * - `claude-code-20250219` — the main feature flag\n *\n * Additional betas (1M context, interleaved thinking, etc.) can be added\n * via `ANTHROPIC_BETAS` env var merging. We avoid hard-coding beta values\n * that are model-specific or experiment-gated in La-Machina — those\n * decisions belong to the caller.\n */\n\nconst DEFAULT_BETAS = ['claude-code-20250219']\n\n/**\n * Returns true if the given base URL points at the first-party Anthropic\n * API (or is unset). Any other host — including a URL that happens to\n * contain \"anthropic\" as a substring — returns false.\n *\n * Matches La-Machina's `isFirstPartyAnthropicBaseUrl` minus the\n * ant-internal staging host (we have no USER_TYPE concept).\n */\nexport function isFirstPartyBaseUrl(baseURL: string | undefined): boolean {\n if (!baseURL) return true\n let host: string\n try {\n host = new URL(baseURL).host\n } catch {\n return false\n }\n return host === 'api.anthropic.com'\n}\n\n/**\n * Compute the `anthropic-beta` header values for a given base URL + model.\n *\n * `_modelId` is reserved for future model-specific betas (1M context,\n * interleaved thinking) but is unused in v0.1. The engine's caller can\n * opt in via `ANTHROPIC_BETAS` env var, which merges into the default set\n * in first-party mode and REPLACES it in proxy mode.\n */\nexport function computeBetaHeaders(baseURL: string | undefined, _modelId: string): string[] {\n const userOptIn = parseEnvBetas()\n\n if (!isFirstPartyBaseUrl(baseURL)) {\n return userOptIn\n }\n\n // First-party mode: merge defaults with any user opt-in.\n const seen = new Set<string>()\n const result: string[] = []\n for (const beta of [...DEFAULT_BETAS, ...userOptIn]) {\n if (!seen.has(beta)) {\n seen.add(beta)\n result.push(beta)\n }\n }\n return result\n}\n\nfunction parseEnvBetas(): string[] {\n const raw = process.env.ANTHROPIC_BETAS\n if (raw === undefined || raw === '') return []\n return raw\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0)\n}\n","/**\n * streaming — normalize raw Anthropic stream events into a small,\n * well-shaped union that the engine's agent loop can consume.\n *\n * The Anthropic SDK emits a discriminated union of six raw events per\n * stream:\n * message_start — metadata and initial usage\n * content_block_start — begin a text or tool_use block\n * content_block_delta — partial text or input_json chunk\n * content_block_stop — end of a block\n * message_delta — stop_reason + final output_tokens\n * message_stop — terminal event\n *\n * This module collects deltas into complete blocks and emits a cleaner\n * union: `text` / `tool_use` / `message_stop`. Tool_use input JSON is\n * assembled and parsed once at content_block_stop so downstream code\n * sees a typed object rather than raw partial JSON.\n *\n * Errors:\n * - Malformed tool_use JSON → `StreamParseError`\n * - Stream ends without `message_stop` → `StreamIncompleteError`\n */\n\nimport type { MessageStreamEvent } from '@anthropic-ai/sdk/resources/messages'\nimport { StreamIncompleteError, StreamParseError } from '../engine/errors.js'\n\nexport interface TokenUsage {\n readonly input: number\n readonly output: number\n readonly cacheCreationInput?: number | undefined\n readonly cacheReadInput?: number | undefined\n}\n\n/**\n * Common Anthropic stop reasons. The `(string & {})` pattern preserves\n * autocomplete for the documented values while still allowing arbitrary\n * strings from third-party proxies that may use other vocabularies.\n */\nexport type StopReason =\n | 'end_turn'\n | 'tool_use'\n | 'max_tokens'\n | 'stop_sequence'\n | 'refusal'\n | 'pause_turn'\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n | (string & Record<never, never>)\n\nexport type NormalizedEvent =\n | {\n readonly type: 'text'\n readonly index: number\n readonly text: string\n }\n | {\n readonly type: 'tool_use'\n readonly index: number\n readonly id: string\n readonly name: string\n readonly input: unknown\n }\n | {\n readonly type: 'thinking'\n readonly index: number\n readonly thinking: string\n }\n | {\n readonly type: 'message_stop'\n readonly stopReason: StopReason\n readonly usage: TokenUsage\n }\n\ninterface InFlightBlock {\n readonly index: number\n readonly kind: 'text' | 'tool_use' | 'thinking'\n textBuffer: string\n toolUseId: string\n toolUseName: string\n inputJsonBuffer: string\n}\n\ninterface StreamState {\n blocks: Map<number, InFlightBlock>\n inputTokens: number\n outputTokens: number\n cacheCreationInput?: number\n cacheReadInput?: number\n stopReason: StopReason | null\n sawStop: boolean\n}\n\n/**\n * Consume an async iterable of raw Anthropic stream events and yield\n * normalized events. Throws on malformed or incomplete streams.\n */\nexport async function* normalizeStream(\n source: AsyncIterable<MessageStreamEvent>,\n): AsyncGenerator<NormalizedEvent, void, void> {\n const state: StreamState = {\n blocks: new Map(),\n inputTokens: 0,\n outputTokens: 0,\n stopReason: null,\n sawStop: false,\n }\n\n for await (const event of source) {\n const emitted = handleEvent(event, state)\n if (emitted) yield emitted\n }\n\n if (!state.sawStop) {\n throw new StreamIncompleteError(\n 'Stream ended without a message_stop event; assistant output is partial',\n )\n }\n\n // After the final message_stop we emit our own terminal event with the\n // aggregated stop reason and usage so the caller has a single place to\n // read them.\n yield {\n type: 'message_stop',\n stopReason: state.stopReason ?? 'end_turn',\n usage: buildUsage(state),\n }\n}\n\nfunction handleEvent(event: MessageStreamEvent, state: StreamState): NormalizedEvent | null {\n switch (event.type) {\n case 'message_start': {\n const usage = event.message.usage\n state.inputTokens = usage.input_tokens\n state.outputTokens = usage.output_tokens\n if (typeof usage.cache_creation_input_tokens === 'number') {\n state.cacheCreationInput = usage.cache_creation_input_tokens\n }\n if (typeof usage.cache_read_input_tokens === 'number') {\n state.cacheReadInput = usage.cache_read_input_tokens\n }\n return null\n }\n\n case 'content_block_start': {\n const block = event.content_block\n if (block.type === 'text') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'text',\n textBuffer: block.text,\n toolUseId: '',\n toolUseName: '',\n inputJsonBuffer: '',\n })\n } else if (block.type === 'tool_use') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'tool_use',\n textBuffer: '',\n toolUseId: block.id,\n toolUseName: block.name,\n inputJsonBuffer: '',\n })\n }\n // Thinking blocks — preserve for extended thinking support.\n if (block.type === 'thinking') {\n state.blocks.set(event.index, {\n index: event.index,\n kind: 'thinking',\n textBuffer: (block as { thinking?: string }).thinking ?? '',\n toolUseId: '',\n toolUseName: '',\n inputJsonBuffer: '',\n })\n }\n // Other block types (server_tool_use, etc.) silently ignored.\n return null\n }\n\n case 'content_block_delta': {\n const block = state.blocks.get(event.index)\n if (!block) return null\n const delta = event.delta\n if (delta.type === 'text_delta' && block.kind === 'text') {\n block.textBuffer += delta.text\n } else if (delta.type === 'input_json_delta' && block.kind === 'tool_use') {\n block.inputJsonBuffer += delta.partial_json\n } else if (delta.type === 'thinking_delta' && block.kind === 'thinking') {\n block.textBuffer += (delta as { thinking?: string }).thinking ?? ''\n }\n return null\n }\n\n case 'content_block_stop': {\n const block = state.blocks.get(event.index)\n if (!block) return null\n state.blocks.delete(event.index)\n if (block.kind === 'text') {\n return { type: 'text', index: block.index, text: block.textBuffer }\n }\n if (block.kind === 'thinking') {\n return { type: 'thinking', index: block.index, thinking: block.textBuffer }\n }\n // tool_use — parse the accumulated JSON input\n let input: unknown = {}\n if (block.inputJsonBuffer.length > 0) {\n try {\n input = JSON.parse(block.inputJsonBuffer)\n } catch (err) {\n throw new StreamParseError(\n `Failed to parse tool_use input JSON for \"${block.toolUseName}\": ${(err as Error).message}`,\n )\n }\n }\n return {\n type: 'tool_use',\n index: block.index,\n id: block.toolUseId,\n name: block.toolUseName,\n input,\n }\n }\n\n case 'message_delta': {\n if (event.delta.stop_reason) {\n state.stopReason = event.delta.stop_reason\n }\n if (typeof event.usage.output_tokens === 'number') {\n state.outputTokens = event.usage.output_tokens\n }\n return null\n }\n\n case 'message_stop': {\n state.sawStop = true\n return null\n }\n }\n}\n\nfunction buildUsage(state: StreamState): TokenUsage {\n const usage: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n } = {\n input: state.inputTokens,\n output: state.outputTokens,\n }\n if (state.cacheCreationInput !== undefined) {\n usage.cacheCreationInput = state.cacheCreationInput\n }\n if (state.cacheReadInput !== undefined) {\n usage.cacheReadInput = state.cacheReadInput\n }\n return usage\n}\n","/**\n * AISdkAdapter — ModelAdapter using the Vercel AI SDK for 75+ providers.\n *\n * Properly converts Anthropic-format messages to AI SDK v4 ModelMessage\n * format, including tool_use/tool_result round-trips. The key is that\n * AI SDK v4 requires tool result output as { type: 'text', value: '...' }\n * (not a plain string or generic object).\n */\n\nimport { streamText, type LanguageModel } from 'ai'\nimport type { ModelAdapter, StreamRequest } from './adapter.js'\nimport type { NormalizedEvent, StopReason } from '../api/streaming.js'\nimport { toAISdkMessages } from './messageConverter.js'\nimport { toAISdkTools } from './toolConverter.js'\n\n// Static imports for the four supported AI-SDK providers. All four\n// are declared as REQUIRED dependencies in package.json so consumers\n// don't need to install them separately. Static (vs. dynamic\n// `await import(pkg)`) is mandatory for environments without a\n// runtime module resolver — notably Cloudflare Workers, where\n// esbuild bundles the consumer and can only follow static imports.\n//\n// Trade-off: every la-machina consumer carries the bundle cost of\n// all four adapters. ~few hundred KB total; acceptable today,\n// trivially code-splittable per-provider later if it matters.\nimport { createAnthropic } from '@ai-sdk/anthropic'\nimport { createOpenAI } from '@ai-sdk/openai'\nimport { createGoogleGenerativeAI } from '@ai-sdk/google'\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible'\n\nexport interface AISdkAdapterOptions {\n readonly provider: string\n readonly modelId: string\n readonly apiKey: string\n readonly baseURL?: string | undefined\n readonly maxRetries?: number | undefined\n}\n\nexport class AISdkAdapter implements ModelAdapter {\n private readonly options: AISdkAdapterOptions\n private model: LanguageModel | null = null\n\n constructor(options: AISdkAdapterOptions) {\n this.options = options\n }\n\n async *streamMessage(request: StreamRequest): AsyncGenerator<NormalizedEvent, void, void> {\n const model = await this.getModel()\n const messages = toAISdkMessages(request.messages as unknown as Record<string, unknown>[])\n const tools = toAISdkTools(\n request.tools as unknown as readonly Record<string, unknown>[] | undefined,\n )\n\n const result = streamText({\n model,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n messages: messages as any,\n ...(request.system !== undefined ? { system: request.system } : {}),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tools: tools as any,\n ...(request.maxTokens !== undefined ? { maxOutputTokens: request.maxTokens } : {}),\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n maxRetries: this.options.maxRetries ?? 2,\n })\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for await (const event of result.fullStream as AsyncIterable<any>) {\n switch (event.type) {\n case 'text-delta':\n yield {\n type: 'text' as const,\n index: 0,\n text: (event.text ?? event.textDelta ?? '') as string,\n }\n break\n case 'tool-call':\n yield {\n type: 'tool_use' as const,\n index: 0,\n id: (event.toolCallId ?? '') as string,\n name: (event.toolName ?? '') as string,\n // AI SDK v4: tool args are in `event.input` (not `event.args`)\n input: event.input ?? event.args ?? {},\n }\n break\n case 'finish': {\n const usage = event.totalUsage ?? event.usage ?? {}\n yield {\n type: 'message_stop' as const,\n stopReason: mapFinishReason(event.finishReason),\n usage: {\n input: usage.inputTokens ?? usage.promptTokens ?? 0,\n output: usage.outputTokens ?? usage.completionTokens ?? 0,\n },\n }\n break\n }\n }\n }\n }\n\n private async getModel(): Promise<LanguageModel> {\n if (this.model !== null) return this.model\n const { provider, modelId, apiKey, baseURL } = this.options\n switch (provider) {\n case 'anthropic':\n this.model = createAnthropic({ apiKey })(modelId)\n break\n case 'openai':\n this.model = createOpenAI({ apiKey, ...(baseURL ? { baseURL } : {}) })(modelId)\n break\n case 'google':\n this.model = createGoogleGenerativeAI({ apiKey })(modelId)\n break\n case 'openai-compatible':\n this.model = createOpenAICompatible({ name: 'custom', apiKey, baseURL: baseURL ?? '' })(\n modelId,\n )\n break\n default:\n throw new Error(`AI SDK: unsupported provider \"${provider}\".`)\n }\n return this.model\n }\n}\n\nfunction mapFinishReason(reason: string | undefined | null): StopReason {\n switch (reason) {\n case 'stop':\n return 'end_turn'\n case 'tool-calls':\n return 'tool_use'\n case 'length':\n return 'max_tokens'\n default:\n return 'end_turn'\n }\n}\n","/**\n * Convert Anthropic-format messages → AI SDK v4 ModelMessage format.\n *\n * Key: AI SDK v4 tool results require:\n * { type: 'tool-result', toolCallId, toolName, output: { type: 'text', value: '...' } }\n *\n * The Anthropic format puts toolName only in the assistant's tool_use\n * block. AI SDK v4 requires it in both places. We map toolCallId →\n * toolName during conversion.\n */\n\nexport function toAISdkMessages(messages: readonly Record<string, unknown>[]): unknown[] {\n const out: unknown[] = []\n const toolNames = new Map<string, string>()\n\n for (const msg of messages) {\n const role = msg.role as string\n const content = msg.content\n\n if (role === 'user') {\n if (typeof content === 'string') {\n out.push({ role: 'user', content })\n continue\n }\n if (!Array.isArray(content)) continue\n\n const textParts: unknown[] = []\n const toolResults: unknown[] = []\n\n for (const block of content as Record<string, unknown>[]) {\n if (block.type === 'tool_result') {\n const id = block.tool_use_id as string\n const resultText =\n typeof block.content === 'string' ? block.content : JSON.stringify(block.content ?? '')\n toolResults.push({\n type: 'tool-result',\n toolCallId: id,\n toolName: toolNames.get(id) ?? 'unknown',\n output: { type: 'text', value: resultText },\n })\n } else if (block.type === 'text') {\n textParts.push({ type: 'text', text: block.text as string })\n }\n }\n\n // Order matters — AI SDK validates tool_call ↔ tool_result pairing\n // in prompt order. A `tool` message closes the pairing; a `user`\n // message must come AFTER all pending tool_results are resolved,\n // or the validator throws `MissingToolResultsError`.\n //\n // When a single Anthropic user message carries both a tool_result\n // and a follow-up text (the engine's synthetic-retry injection\n // pattern, Plan 019), we split into `tool` FIRST, then `user`.\n if (toolResults.length > 0) out.push({ role: 'tool', content: toolResults })\n if (textParts.length > 0) out.push({ role: 'user', content: textParts })\n } else if (role === 'assistant') {\n if (typeof content === 'string') {\n out.push({ role: 'assistant', content })\n continue\n }\n if (!Array.isArray(content)) {\n out.push({ role: 'assistant', content: '' })\n continue\n }\n\n const parts: unknown[] = []\n for (const block of content as Record<string, unknown>[]) {\n if (block.type === 'text') {\n parts.push({ type: 'text', text: block.text as string })\n } else if (block.type === 'tool_use') {\n const id = block.id as string\n const name = block.name as string\n toolNames.set(id, name)\n parts.push({\n type: 'tool-call',\n toolCallId: id,\n toolName: name,\n args: block.input ?? {},\n })\n }\n }\n out.push({ role: 'assistant', content: parts })\n }\n }\n\n return out\n}\n","/**\n * Convert engine tool definitions to AI SDK tool format.\n *\n * Handles both ModelToolDefinition (inputSchema) and Anthropic-format\n * tools (input_schema) since the agentLoop's toAnthropicTool() produces\n * the latter.\n */\n\nimport { jsonSchema } from 'ai'\n\nexport function toAISdkTools(\n tools: readonly Record<string, unknown>[] | undefined,\n): Record<string, { description: string; parameters: unknown }> | undefined {\n if (!tools || tools.length === 0) return undefined\n\n const out: Record<string, { description: string; parameters: unknown }> = {}\n\n for (const tool of tools) {\n const name = tool.name as string\n const description = (tool.description ?? '') as string\n // Handle both inputSchema (ModelToolDefinition) and input_schema (Anthropic format).\n const schema = (tool.inputSchema ?? tool.input_schema ?? { type: 'object' }) as Record<\n string,\n unknown\n >\n\n out[name] = {\n description,\n parameters: jsonSchema(schema as Parameters<typeof jsonSchema>[0]),\n }\n }\n\n return out\n}\n","/**\n * Runtime detection — determines whether the engine is running in\n * Node.js or a restricted runtime (Cloudflare Workers, etc.)\n *\n * Detection strategy:\n * - Node.js has `process.versions.node` set to a version string\n * - Workers have `process` (polyfilled) but `process.versions` is\n * undefined or `process.versions.node` is undefined\n * - As a fallback, probe whether child_process.spawn is functional\n */\n\nexport type RuntimeKind = 'node' | 'worker'\n\nlet cached: RuntimeKind | null = null\n\n/**\n * Detect the runtime. Result is cached after first call.\n */\nexport function detectRuntime(): RuntimeKind {\n if (cached !== null) return cached\n cached = isNodeRuntime() ? 'node' : 'worker'\n return cached\n}\n\nfunction isNodeRuntime(): boolean {\n // Primary check: Node.js always has process.versions.node\n if (\n typeof globalThis.process !== 'undefined' &&\n globalThis.process.versions != null &&\n typeof globalThis.process.versions.node === 'string'\n ) {\n return true\n }\n return false\n}\n\n/**\n * Whether subprocess spawning (Bash, ripgrep, MCP stdio) is available.\n */\nexport function canSpawnProcesses(): boolean {\n return detectRuntime() === 'node'\n}\n\n/**\n * Whether process lifecycle hooks (process.on('exit')) are available.\n */\nexport function hasProcessLifecycle(): boolean {\n return (\n typeof process !== 'undefined' &&\n typeof process.on === 'function' &&\n typeof process.removeListener === 'function' &&\n detectRuntime() === 'node'\n )\n}\n","/**\n * Capability stub — replaces a Node-only tool with a placeholder that\n * returns a structured `isError` result when invoked in a runtime that\n * can't execute it (e.g. Cloudflare Workers for Bash / stdio MCP).\n *\n * The stub preserves the original tool's name and description so the\n * model still sees the tool in its toolset and can decide whether to\n * call it. When called, the stub returns a clear message naming the\n * tool and pointing at the runner-handoff escape hatch (Plan 019).\n *\n * In async runs with `config.runner` configured, the agent loop\n * intercepts stub invocations BEFORE they execute and pauses the run\n * with `pauseReason: 'handoff_to_runner'` so a Node-side runner can\n * resume it. In sync runs (or async runs with no runner configured),\n * the stub's `execute` actually runs and the model adapts its answer.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from './contract.js'\n\n/** Accept any input shape — the stub errors regardless. */\nconst anyInput = z.unknown()\n\n/**\n * Build a stub tool that mirrors `original.name` and `original.description`\n * but returns an `isError` result when invoked. Used by the engine when\n * a tool declares `requiresNode: true` and `canSpawnProcesses()` is false.\n */\nexport function capabilityStub(original: Pick<Tool, 'name' | 'description'>): Tool {\n return defineTool({\n name: original.name,\n description: original.description,\n inputSchema: anyInput,\n isCapabilityStub: true,\n execute: async () => ({\n isError: true,\n content:\n `Tool \"${original.name}\" requires Node runtime and cannot execute ` +\n `in this environment. To use this tool, run async via engine.start() ` +\n `with config.runner configured so the run can hand off to a Node ` +\n `runner. See README §\"Runner contract\" for setup.`,\n metadata: { capabilityMissing: original.name },\n }),\n })\n}\n\n/**\n * Convenience: given a tool, return the real tool when the runtime can\n * execute it, otherwise a capability stub standing in for it. Callers\n * that already know the spawn-availability flag (e.g. engine.ts which\n * caches it) pass it directly instead of re-probing.\n */\nexport function withCapabilityCheck(tool: Tool, spawnAvailable: boolean): Tool {\n if (tool.requiresNode === true && !spawnAvailable) {\n return capabilityStub(tool)\n }\n return tool\n}\n","/**\n * SubagentRegistry — tracks parent→child relationships across a single\n * `engine.run()`. Mints unique `agentId`s, computes spawn depth, and\n * enforces `maxDepth` so a runaway loop can't recursively spawn forever.\n *\n * The registry's lifetime is one engine run. A fresh instance is built\n * inside `engine.run()` and shared with every Agent tool invocation\n * during that run, including children that themselves spawn grandchildren.\n *\n * Tracking is in-memory only. We don't persist parent→child relationships\n * to the transcript here — that's the runner's job, which writes\n * `subagent_spawn` and `subagent_done` entries to the parent's transcript.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\n\nexport interface SubagentRegistryOptions {\n /** Maximum spawn depth. Depth 1 = a direct child of the root run. */\n readonly maxDepth: number\n}\n\nexport interface SpawnResult {\n readonly agentId: string\n readonly depth: number\n}\n\n/** Result from a background agent, stored on completion. */\nexport interface BackgroundAgentResult {\n readonly agentId: string\n readonly output: string\n readonly isError: boolean\n readonly description?: string\n}\n\ninterface RegisteredAgent {\n readonly parentId: string | null\n readonly depth: number\n name?: string\n status: 'running' | 'stopped' | 'completed'\n pendingMessages: string[]\n backgroundResult?: BackgroundAgentResult\n isBackground?: boolean\n /** Tracked Promise for background agents — enables draining before pause. */\n backgroundPromise?: Promise<void>\n}\n\n/** Serialized form for persistence alongside transcripts. */\nexport interface SerializedAgent {\n readonly agentId: string\n readonly parentId: string | null\n readonly depth: number\n readonly name?: string\n readonly status: 'running' | 'stopped' | 'completed'\n}\n\nexport class SubagentRegistry {\n private readonly maxDepth: number\n private readonly agents = new Map<string, RegisteredAgent>()\n\n constructor(options: SubagentRegistryOptions) {\n if (!Number.isInteger(options.maxDepth) || options.maxDepth < 1) {\n throw new Error('SubagentRegistry: maxDepth must be a positive integer')\n }\n this.maxDepth = options.maxDepth\n }\n\n /**\n * Mint a new subagent under `parentAgentId` (null = direct child of\n * the root run). Throws if the resulting depth would exceed `maxDepth`.\n */\n spawn(parentAgentId: string | null): SpawnResult {\n const parentDepth = parentAgentId === null ? 0 : this.requireAgent(parentAgentId).depth\n const depth = parentDepth + 1\n if (depth > this.maxDepth) {\n throw new Error(`Subagent depth limit exceeded: ${depth} > maxDepth ${this.maxDepth}`)\n }\n const agentId = `agent_${randomUUID()}`\n this.agents.set(agentId, {\n parentId: parentAgentId,\n depth,\n status: 'running',\n pendingMessages: [],\n })\n return { agentId, depth }\n }\n\n getDepth(agentId: string): number {\n return this.requireAgent(agentId).depth\n }\n\n getParent(agentId: string): string | null {\n return this.requireAgent(agentId).parentId\n }\n\n count(): number {\n return this.agents.size\n }\n\n // ---------- name registry ----------\n\n /** Set a human-readable name for routing (e.g. subagent_type or task description). */\n setName(agentId: string, name: string): void {\n this.requireAgent(agentId).name = name\n }\n\n /** Find an agent by its human-readable name. Returns the first match. */\n findByName(name: string): string | undefined {\n for (const [id, entry] of this.agents) {\n if (entry.name === name) return id\n }\n return undefined\n }\n\n // ---------- status ----------\n\n setStatus(agentId: string, status: 'running' | 'stopped' | 'completed'): void {\n this.requireAgent(agentId).status = status\n }\n\n getStatus(agentId: string): 'running' | 'stopped' | 'completed' {\n return this.requireAgent(agentId).status\n }\n\n // ---------- message queue (for SendMessage) ----------\n\n /** Queue a message for a running agent. */\n queueMessage(agentId: string, message: string): void {\n this.requireAgent(agentId).pendingMessages.push(message)\n }\n\n /** Drain all pending messages. Returns empty array if none. */\n drainMessages(agentId: string): string[] {\n const agent = this.requireAgent(agentId)\n const msgs = agent.pendingMessages.splice(0)\n return msgs\n }\n\n // ---------- background agents ----------\n\n /** Mark an agent as background (fire-and-forget). */\n setBackground(agentId: string): void {\n this.requireAgent(agentId).isBackground = true\n }\n\n /** Track a background agent's Promise for drain-before-pause. */\n setBackgroundPromise(agentId: string, promise: Promise<void>): void {\n this.requireAgent(agentId).backgroundPromise = promise\n }\n\n /** Store a background agent's result on completion. */\n setBackgroundResult(agentId: string, result: BackgroundAgentResult): void {\n this.requireAgent(agentId).backgroundResult = result\n }\n\n /**\n * Drain all completed background agent results. Returns them and\n * clears the stored results so they're only delivered once.\n * Called at the top of each turn in agentLoop.\n */\n drainCompletedBackgroundResults(): BackgroundAgentResult[] {\n const results: BackgroundAgentResult[] = []\n for (const [, entry] of this.agents) {\n if (entry.isBackground && entry.backgroundResult) {\n results.push(entry.backgroundResult)\n delete entry.backgroundResult\n }\n }\n return results\n }\n\n /**\n * Wait for all running background agents to complete (with timeout).\n * Called before pause to drain in-flight work. Returns results from\n * agents that finished within the timeout.\n */\n async awaitBackgroundAgents(timeoutMs = 10_000): Promise<BackgroundAgentResult[]> {\n const pending: Promise<void>[] = []\n for (const [, entry] of this.agents) {\n if (entry.isBackground && entry.status === 'running' && entry.backgroundPromise) {\n pending.push(entry.backgroundPromise)\n }\n }\n if (pending.length === 0) return this.drainCompletedBackgroundResults()\n\n // Race all pending against a timeout\n await Promise.race([\n Promise.allSettled(pending),\n new Promise<void>((r) => setTimeout(r, timeoutMs)),\n ])\n\n return this.drainCompletedBackgroundResults()\n }\n\n // ---------- persistence ----------\n\n /** Serialize all agents for sidecar persistence. */\n toJSON(): SerializedAgent[] {\n const out: SerializedAgent[] = []\n for (const [agentId, entry] of this.agents) {\n out.push({\n agentId,\n parentId: entry.parentId,\n depth: entry.depth,\n ...(entry.name !== undefined ? { name: entry.name } : {}),\n status: entry.status,\n })\n }\n return out\n }\n\n /** Rebuild registry from serialized data (e.g. on resume). */\n static fromJSON(data: SerializedAgent[], maxDepth: number): SubagentRegistry {\n const reg = new SubagentRegistry({ maxDepth })\n for (const entry of data) {\n reg.agents.set(entry.agentId, {\n parentId: entry.parentId,\n depth: entry.depth,\n ...(entry.name !== undefined ? { name: entry.name } : {}),\n status: entry.status,\n pendingMessages: [],\n })\n }\n return reg\n }\n\n private requireAgent(agentId: string): RegisteredAgent {\n const a = this.agents.get(agentId)\n if (!a) throw new Error(`SubagentRegistry: unknown agentId \"${agentId}\"`)\n return a\n }\n}\n","/**\n * Cross-runtime UUID v4 generator.\n *\n * Uses `crypto.randomUUID()` which is available in:\n * - Node.js 19+ (global `crypto`)\n * - Cloudflare Workers (Web Crypto API)\n * - Deno, Bun, modern browsers\n *\n * Falls back to `node:crypto` for older Node.js versions.\n * Never crashes on Workers — no top-level `node:crypto` import.\n */\n\nlet _randomUUID: () => string\n\nif (typeof globalThis.crypto?.randomUUID === 'function') {\n // Web Crypto API — works everywhere (Node 19+, Workers, Deno, Bun)\n _randomUUID = () => globalThis.crypto.randomUUID()\n} else {\n // Fallback for older Node.js — lazy import\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeCrypto = require('node:crypto') as { randomUUID: () => string }\n _randomUUID = nodeCrypto.randomUUID\n } catch {\n // Last resort — manual UUID v4\n _randomUUID = () => {\n const bytes = new Uint8Array(16)\n // Use whatever crypto is available\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 16; i++) bytes[i] = Math.floor(Math.random() * 256)\n }\n // Set version (4) and variant (10xx)\n bytes[6] = (bytes[6]! & 0x0f) | 0x40\n bytes[8] = (bytes[8]! & 0x3f) | 0x80\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`\n }\n }\n}\n\nexport const randomUUID = _randomUUID\n","/**\n * Agent tool — lets the parent assistant spawn a child agent.\n *\n * The Agent tool is a closure factory that captures the parent's\n * subsystems (storage, API client, registry, subagent registry,\n * config) at engine.run() time. When the parent calls it via the\n * usual tool dispatch mechanism, the closure runs `runAgent` to drive\n * a child loop and returns the child's final answer as the\n * tool_result content.\n *\n * Depth and uniqueness are enforced via `SubagentRegistry`. If the\n * spawn would exceed `maxSubagentDepth`, the tool returns an error\n * result instead of throwing — the parent assistant can read the\n * error and adapt.\n *\n * The factory's `parentAgentId` parameter is null at the top level\n * (root run) and set to the parent's agentId for nested invocations.\n */\n\nimport { z } from 'zod'\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { SubagentRegistry } from '../subagent/registry.js'\nimport { runAgent, type RunAgentResult } from '../subagent/runner.js'\nimport { isInForkChild, buildForkedMessages } from '../subagent/fork.js'\nimport type { FlushPolicy } from '../transcript/writer.js'\nimport { SubagentPausedError } from '../engine/errors.js'\nimport type { GateBeforeTool } from '../engine/agentLoop.js'\nimport { defineTool, type Tool, type ToolRegistry, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n description: z.string().min(1),\n subagent_type: z.string().optional(),\n run_in_background: z.boolean().optional(),\n})\n\n/**\n * A subagent definition the parent can dispatch to via `Agent({ subagent_type })`.\n *\n * `systemPrompt` overrides the parent's system prompt when the child runs.\n * Leave it undefined to inherit the parent's prompt — which is what the\n * `'general-purpose'` builtin does.\n */\nexport interface AgentDefinition {\n readonly name: string\n readonly description: string\n readonly systemPrompt?: string\n /**\n * When true, marks this agent as safe for parallel execution\n * alongside other readOnly agents. The Agent tool uses this via\n * `isConcurrencySafe` so the batch dispatcher can run multiple\n * research agents concurrently. Default: false.\n */\n readonly readOnly?: boolean\n}\n\nexport interface AgentToolOptions {\n /** Storage adapter the child writes its transcript through. */\n readonly storage: StorageAdapter\n /** API client the child uses (shared with parent). */\n readonly client: ModelAdapter\n /**\n * Registry passed to the child. Typically the parent's full\n * registry minus the Agent tool itself in v0.1, OR the same\n * registry to allow nested spawning (depth-bounded).\n */\n readonly childRegistry: ToolRegistry\n /** Parent's transcript log path: \"projects/{runId}/nodes/{nodeId}\". */\n readonly parentLogPath: string\n /** Parent's agentId, or null if this is at the root run. */\n readonly parentAgentId: string | null\n /** The shared SubagentRegistry for this run. */\n readonly subagentRegistry: SubagentRegistry\n /** System prompt the child sees. */\n readonly system: string\n /** Per-child execution caps. */\n readonly maxTurns: number\n readonly contextLimit: number\n readonly turnTimeoutMs: number\n /** Transcript flush configuration mirrors the parent's. */\n readonly flushPolicy: FlushPolicy\n readonly idleFlushMs: number\n /** Whether the parent is in coordinator mode — controls result format. */\n readonly coordinatorMode?: boolean\n /**\n * Parent's current message history — needed for fork path.\n * When `subagent_type` is omitted and fork is enabled, the child\n * inherits these messages as context.\n */\n readonly parentMessages?: () => readonly MessageParam[]\n /** Enable fork behavior when subagent_type is omitted. Default: true. */\n readonly enableFork?: boolean\n /**\n * Available subagent definitions. The tool's description surfaces this\n * list to the model, and `execute()` rejects `subagent_type` values\n * not in this set. An empty array throws at construction time.\n */\n readonly agents: ReadonlyArray<AgentDefinition>\n /**\n * When provided, the parent's gate is passed down to every subagent's\n * inner loop. A gate denial inside the child then throws\n * `SubagentPausedError`, which the parent's agentLoop catches and\n * surfaces as its own `paused` result. Only set by engine.ts when\n * `config.hooks.propagateGateToSubagents === true`.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /**\n * Plan 021 — when set, every subagent spawned by this tool inherits\n * offload behaviour and rebuilds its own FetchData bound to the\n * child's log path.\n */\n readonly toolResultOffload?: import('../engine/toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n}\n\nexport function createAgentTool(options: AgentToolOptions): Tool<typeof inputSchema> {\n if (options.agents.length === 0) {\n throw new Error(\n 'createAgentTool: at least one agent definition is required (check config.agents.builtins + agents.customPath)',\n )\n }\n // Dedup by name; later entries win (customPath agents override builtins).\n const byName = new Map<string, AgentDefinition>()\n for (const a of options.agents) byName.set(a.name, a)\n const agentList = Array.from(byName.values())\n const defaultAgent = agentList[0]!\n\n // Surface available agents to the model via the tool description.\n const agentCatalogue = agentList.map((a) => ` - ${a.name}: ${a.description}`).join('\\n')\n const description =\n `Spawn a subagent to handle a focused task. Returns the subagent's final answer.\\n` +\n `Available subagent_type values:\\n${agentCatalogue}\\n` +\n `If omitted, defaults to \"${defaultAgent.name}\".`\n\n return defineTool({\n name: 'Agent',\n description,\n inputSchema,\n isConcurrencySafe: (input: unknown) => {\n const typed = input as { subagent_type?: string } | undefined\n const typeName = typed?.subagent_type ?? defaultAgent.name\n const agentDef = byName.get(typeName)\n return agentDef?.readOnly === true\n },\n execute: async ({\n description: taskDescription,\n subagent_type,\n run_in_background,\n }): Promise<ToolResult> => {\n // Fork path — when subagent_type is omitted and fork is enabled,\n // child inherits parent's full message context. Ported from\n // La-Machina's forkSubagent.ts.\n const forkEnabled = options.enableFork !== false\n const parentMsgs = options.parentMessages?.() ?? []\n if (\n subagent_type === undefined &&\n forkEnabled &&\n !options.coordinatorMode &&\n parentMsgs.length > 0 &&\n !isInForkChild(parentMsgs)\n ) {\n let spawn: ReturnType<SubagentRegistry['spawn']>\n try {\n spawn = options.subagentRegistry.spawn(options.parentAgentId)\n } catch (err) {\n return { content: `Cannot spawn fork: ${(err as Error).message}`, isError: true }\n }\n options.subagentRegistry.setName(spawn.agentId, `fork-${taskDescription.slice(0, 40)}`)\n\n // Get last assistant content for placeholder building\n const lastAssistant = [...parentMsgs].reverse().find((m) => m.role === 'assistant')\n const assistantContent = lastAssistant\n ? Array.isArray(lastAssistant.content)\n ? lastAssistant.content\n : []\n : []\n const forkedMsgs = buildForkedMessages(taskDescription, assistantContent)\n\n const result = await runAgent({\n agentId: spawn.agentId,\n description: taskDescription,\n storage: options.storage,\n client: options.client,\n registry: options.childRegistry,\n parentLogPath: options.parentLogPath,\n system: options.system, // inherit parent's system prompt\n maxTurns: options.maxTurns,\n contextLimit: options.contextLimit,\n turnTimeoutMs: options.turnTimeoutMs,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n // Fork: prepend parent messages + forked messages\n prependMessages: [...parentMsgs, ...forkedMsgs],\n ...(options.gateBeforeTool !== undefined\n ? { gateBeforeTool: options.gateBeforeTool }\n : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n })\n\n // Fork path doesn't have a tool_use_id (no subagent_type). Pass\n // the fork agentId as a stand-in so the pause-propagation error\n // still carries identity for observability.\n handlePausedResult(result, spawn.agentId, 'fork')\n const t = result as Extract<RunAgentResult, { kind: 'terminal' }>\n options.subagentRegistry.setStatus(spawn.agentId, t.isError ? 'stopped' : 'completed')\n return {\n content: t.output,\n ...(t.isError ? { isError: true } : {}),\n metadata: {\n agentId: spawn.agentId,\n fork: true,\n depth: spawn.depth,\n turns: t.turns,\n tokensUsed: t.tokensUsed,\n },\n }\n }\n\n // Normal agent path\n const typeName = subagent_type ?? defaultAgent.name\n const agentDef = byName.get(typeName)\n if (!agentDef) {\n return {\n content: `Unknown subagent_type \"${typeName}\". Available types: ${agentList.map((a) => a.name).join(', ')}.`,\n isError: true,\n }\n }\n\n let spawn: ReturnType<SubagentRegistry['spawn']>\n try {\n spawn = options.subagentRegistry.spawn(options.parentAgentId)\n } catch (err) {\n return {\n content: `Cannot spawn subagent: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Register the agent's name for SendMessage routing\n options.subagentRegistry.setName(spawn.agentId, typeName || taskDescription.slice(0, 60))\n\n const childSystem = agentDef.systemPrompt ?? options.system\n\n const runOpts = {\n agentId: spawn.agentId,\n description: taskDescription,\n storage: options.storage,\n client: options.client,\n registry: options.childRegistry,\n parentLogPath: options.parentLogPath,\n system: childSystem,\n maxTurns: options.maxTurns,\n contextLimit: options.contextLimit,\n turnTimeoutMs: options.turnTimeoutMs,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n ...(options.gateBeforeTool !== undefined ? { gateBeforeTool: options.gateBeforeTool } : {}),\n ...(options.toolResultOffload !== undefined\n ? { toolResultOffload: options.toolResultOffload }\n : {}),\n }\n\n // Background path — fire-and-forget, return immediately.\n // Ported from La-Machina's async_launched pattern.\n const shouldRunAsync = run_in_background === true || options.coordinatorMode === true\n if (shouldRunAsync) {\n options.subagentRegistry.setBackground(spawn.agentId)\n\n // Fire-and-forget — don't await. Result stored in registry.\n // Promise tracked for drain-before-pause. Background agents do\n // NOT participate in gate propagation — their pause would be\n // invisible to the parent anyway (parent already moved on).\n const bgPromise = runAgent(runOpts)\n .then((result) => {\n // Background agents that \"pause\" are treated as stopped —\n // there's nobody waiting to observe the pause.\n if (result.kind !== 'terminal') {\n options.subagentRegistry.setStatus(spawn.agentId, 'stopped')\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: `Background agent paused mid-execution (pause not supported for async).`,\n isError: true,\n description: taskDescription,\n })\n return\n }\n options.subagentRegistry.setStatus(\n spawn.agentId,\n result.isError ? 'stopped' : 'completed',\n )\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: result.output,\n isError: result.isError,\n description: taskDescription,\n })\n })\n .catch((err) => {\n options.subagentRegistry.setStatus(spawn.agentId, 'stopped')\n options.subagentRegistry.setBackgroundResult(spawn.agentId, {\n agentId: spawn.agentId,\n output: `Agent crashed: ${(err as Error).message}`,\n isError: true,\n description: taskDescription,\n })\n })\n options.subagentRegistry.setBackgroundPromise(spawn.agentId, bgPromise)\n\n return {\n content:\n `Async agent launched.\\nagentId: ${spawn.agentId}\\n` +\n `The agent is working in the background. You will be notified when it completes.\\n` +\n `Use SendMessage with to: '${spawn.agentId}' to communicate with this agent.`,\n metadata: {\n agentId: spawn.agentId,\n subagent_type: typeName,\n status: 'async_launched',\n depth: spawn.depth,\n },\n }\n }\n\n // Synchronous path — block until child finishes\n const result = await runAgent(runOpts)\n\n // Gate propagation: a paused child bubbles up as a throw.\n // toolUseId is not directly accessible here; encode identity as\n // `${spawn.agentId}/${typeName}` so the parent snapshot can\n // surface which subagent blocked.\n handlePausedResult(result, spawn.agentId, typeName)\n const t = result as Extract<RunAgentResult, { kind: 'terminal' }>\n\n // Update registry status\n options.subagentRegistry.setStatus(spawn.agentId, t.isError ? 'stopped' : 'completed')\n\n // In coordinator mode, wrap the result in <task-notification> XML\n // so the coordinator can reliably parse status/summary/result.\n // Ported from La-Machina's coordinatorMode.ts.\n const content = options.coordinatorMode\n ? formatTaskNotification(spawn.agentId, taskDescription, t)\n : t.output\n\n return {\n content,\n ...(t.isError ? { isError: true } : {}),\n metadata: {\n agentId: t.agentId,\n subagent_type: typeName,\n depth: spawn.depth,\n turns: t.turns,\n tokensUsed: t.tokensUsed,\n },\n }\n },\n })\n}\n\nfunction formatTaskNotification(\n agentId: string,\n description: string,\n result: { output: string; isError?: boolean; turns: number; tokensUsed: unknown },\n): string {\n const status = result.isError ? 'failed' : 'completed'\n const summary = result.isError\n ? `Agent \"${description}\" failed`\n : `Agent \"${description}\" completed`\n return [\n '<task-notification>',\n `<task-id>${agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>${summary}</summary>`,\n `<result>${result.output}</result>`,\n `<usage>`,\n ` <turns>${result.turns}</turns>`,\n `</usage>`,\n '</task-notification>',\n ].join('\\n')\n}\n\n/**\n * Throw SubagentPausedError when `result.kind === 'paused'` so the\n * parent's agentLoop catches it and produces its own `paused` result.\n * No-op for terminal results.\n */\nfunction handlePausedResult(result: RunAgentResult, agentId: string, subagentType: string): void {\n if (result.kind === 'paused') {\n throw new SubagentPausedError({\n childSnapshot: result.childSnapshot,\n parentToolUseId: agentId,\n subagentType,\n })\n }\n}\n","/**\n * runAgent — headless execution of a child agent.\n *\n * Builds an isolated `RunContext` and `TranscriptWriter` for the child,\n * dispatches `agentLoop`, and returns the child's final output as a\n * string suitable for the parent's `tool_result` block.\n *\n * Isolation guarantees:\n * - The child's transcript shards live under\n * `{parent-log-path}/subagents/{agentId}/`, completely separate from\n * the parent's transcript files.\n * - The child has its own `RunContext`, so its message history, turn\n * counter, and token usage are independent.\n * - The child shares the parent's storage adapter, API client, and\n * tool registry — those are stateless.\n *\n * The function never throws. Errors become `{ output, isError: true }`\n * results that the Agent tool surfaces to the parent as a tool_result\n * with `isError: true`.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport { agentLoop } from '../engine/agentLoop.js'\nimport { RunContext } from '../engine/runContext.js'\nimport { ToolExecutor } from '../engine/toolRuntime.js'\nimport type { ToolExecutorHooks } from '../engine/toolRuntime.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { Tool, ToolRegistry } from '../tools/contract.js'\nimport { TranscriptWriter, type FlushPolicy } from '../transcript/writer.js'\n\nexport interface RunAgentOptions {\n readonly agentId: string\n readonly description: string\n readonly storage: StorageAdapter\n readonly client: ModelAdapter\n readonly registry: ToolRegistry\n readonly parentLogPath: string\n readonly system: string\n readonly maxTurns: number\n readonly contextLimit: number\n readonly turnTimeoutMs: number\n readonly flushPolicy: FlushPolicy\n readonly idleFlushMs: number\n readonly hooks?: ToolExecutorHooks\n /**\n * Messages to prepend to the child's context before the task message.\n * Used by fork subagent to pass parent's full conversation history.\n */\n readonly prependMessages?: readonly MessageParam[]\n /**\n * Optional gate callback propagated from the parent engine. When the\n * child's agentLoop is about to dispatch a tool, this runs first. A\n * denial pauses the child, surfaced to the parent via the paused\n * RunAgentResult variant.\n */\n readonly gateBeforeTool?: import('../engine/agentLoop.js').GateBeforeTool\n /**\n * Plan 021 — when set, the child inherits offload behaviour AND\n * gets its own `FetchData` registered on the shared registry\n * scoped to the child's log path. The parent's `FetchData` (if\n * any) is replaced for the duration of this subagent run so the\n * child can't read the parent's offloaded refs.\n */\n readonly toolResultOffload?: import('../engine/toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n}\n\nexport type RunAgentResult =\n | {\n readonly kind: 'terminal'\n readonly agentId: string\n readonly output: string\n readonly isError: boolean\n readonly turns: number\n readonly tokensUsed: { input: number; output: number }\n }\n | {\n readonly kind: 'paused'\n readonly agentId: string\n readonly childSnapshot: import('../engine/types.js').RunSnapshot\n readonly turns: number\n readonly tokensUsed: { input: number; output: number }\n }\n\nexport async function runAgent(options: RunAgentOptions): Promise<RunAgentResult> {\n const childLogPath = `${options.parentLogPath}/subagents/${options.agentId}`\n\n // Plan 021 — when offload is enabled, swap in a child-scoped\n // FetchData so the child can only rehydrate its OWN offloaded\n // refs. We unregister any parent-scoped FetchData first (the\n // parent registry may have one) and restore it in `finally`.\n let restorePrevFetchData: (() => void) | null = null\n if (options.toolResultOffload !== undefined && options.toolResultOffload.enabled) {\n const { createFetchDataTool } = await import('../tools/fetchData.js')\n const existing = options.registry.get('FetchData')\n options.registry.unregister('FetchData')\n options.registry.register(\n createFetchDataTool({ storage: options.storage, logPath: childLogPath }),\n )\n restorePrevFetchData = () => {\n options.registry.unregister('FetchData')\n if (existing !== undefined) options.registry.register(existing)\n }\n }\n\n const writer = new TranscriptWriter({\n storage: options.storage,\n logPath: childLogPath,\n flushPolicy: options.flushPolicy,\n idleFlushMs: options.idleFlushMs,\n })\n\n const ctx = new RunContext({\n runId: options.agentId,\n nodeId: options.agentId,\n writer,\n maxTurns: options.maxTurns,\n })\n\n const executor = new ToolExecutor({\n registry: options.registry,\n timeoutMs: options.turnTimeoutMs,\n ...(options.hooks !== undefined ? { hooks: options.hooks } : {}),\n })\n\n try {\n await writer.setStatus('running')\n\n // Fork path: prepend parent's message history so the child\n // sees the full conversation context before its task.\n if (options.prependMessages && options.prependMessages.length > 0) {\n ctx.rehydrate({\n messages: options.prependMessages,\n turnCount: 0,\n tokensUsed: { input: 0, output: 0 },\n lastUuid: null,\n })\n }\n\n await ctx.addUserMessage(options.description)\n\n const tools: Tool[] = options.registry.list()\n const result = await agentLoop({\n context: ctx,\n client: options.client,\n executor,\n tools,\n system: options.system,\n contextLimit: options.contextLimit,\n registry: options.registry,\n // Propagate parent's gate + storage into the child loop when set.\n // Without `storage`, a gate denial would fail the child instead of\n // pausing it, so both must travel together.\n ...(options.gateBeforeTool !== undefined\n ? { gateBeforeTool: options.gateBeforeTool, storage: options.storage }\n : {}),\n // Plan 021 — the child needs its own storage + offload config\n // so its own large tool results get offloaded into\n // `childLogPath/toolResults/...`, not the parent's folder.\n ...(options.toolResultOffload !== undefined\n ? {\n storage: options.storage,\n toolResultOffload: options.toolResultOffload,\n offloadLogPath: childLogPath,\n }\n : {}),\n })\n\n if (result.status === 'done') {\n await writer.setStatus('done')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: result.output,\n isError: false,\n turns: result.turns,\n tokensUsed: { input: result.tokensUsed.input, output: result.tokensUsed.output },\n }\n }\n\n if (result.status === 'paused') {\n await writer.setStatus('paused')\n return {\n kind: 'paused',\n agentId: options.agentId,\n childSnapshot: result.snapshot,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n }\n\n await writer.setStatus('failed')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: `Subagent failed: ${result.error.message}`,\n isError: true,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n } catch (err) {\n await writer.setStatus('failed')\n return {\n kind: 'terminal',\n agentId: options.agentId,\n output: `Subagent crashed: ${(err as Error).message}`,\n isError: true,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }\n } finally {\n // Write agent metadata sidecar for registry persistence on resume\n try {\n await options.storage.writeFile(\n `${childLogPath}/agent-meta.json`,\n JSON.stringify({\n agentId: options.agentId,\n parentLogPath: options.parentLogPath,\n turns: ctx.getTurnCount(),\n tokensUsed: { input: ctx.getTokensUsed().input, output: ctx.getTokensUsed().output },\n }),\n )\n } catch {\n // Best-effort — don't let metadata write failure crash the run\n }\n await writer.close()\n // Plan 021 — restore any parent-scoped FetchData we replaced\n // for the duration of this subagent's run.\n restorePrevFetchData?.()\n }\n}\n","/**\n * agentLoop — the heart of the engine. Drives turns until the run\n * completes, fails, or hits a limit.\n *\n * Per turn:\n * 1. Bail out if `ctx.shouldContinue()` is false (max turns).\n * 2. Optionally compact messages if the context window is full.\n * 3. Convert our `Tool[]` registry shape into Anthropic's `Tool[]`\n * JSON-schema shape.\n * 4. Call `client.streamMessage(...)`. Consume the normalized event\n * stream into:\n * - text blocks (joined into the assistant's text reply)\n * - tool_use blocks (dispatched after the stream ends)\n * - the terminal `message_stop` event (stop reason + usage)\n * 5. Append the assembled assistant message to context (which writes\n * a transcript entry).\n * 6. If there are tool calls: dispatch each through the executor,\n * append each tool_result to context, and loop.\n * 7. If `stopReason === 'end_turn'` and there were no tool calls:\n * finish the run with status `'done'`.\n *\n * Errors during streaming or unhandled stop reasons surface as\n * `{ status: 'failed' }` results — the loop never throws.\n */\n\nimport type { Tool as AnthropicTool, ContentBlockParam } from '@anthropic-ai/sdk/resources/messages'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { ModelAdapter, NormalizedEvent, StopReason } from '../model/adapter.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { writeSnapshot } from '../transcript/snapshot.js'\nimport { maybeOffloadToolResult } from './toolResultOffload.js'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { dispatchHooks } from '../hooks/dispatch.js'\nimport type { PostTurnHook, PreTurnHook, StopHook, StopHookResult } from '../hooks/types.js'\nimport {\n ApiError,\n EngineError,\n RateLimitError,\n RunTimeoutError,\n SubagentPausedError,\n} from './errors.js'\nimport { normalizeMessages } from './normalizeMessages.js'\nimport { compactIfNeeded } from '../compact/compactor.js'\nimport type { ResolvedCompactionConfig } from '../compact/types.js'\nimport type { RunContext } from './runContext.js'\nimport type { ToolExecutor } from './toolRuntime.js'\nimport { StreamingToolExecutor } from './streamingExecutor.js'\nimport type { Tool } from '../tools/contract.js'\nimport type { ToolRegistry } from '../tools/contract.js'\nimport type { PauseReason, RunSnapshot, TranscriptLocation } from './types.js'\n\n/**\n * Result of `gateBeforeTool` callback. `allow: true` runs the tool;\n * `allow: false` pauses the run with the given reason. The pending\n * tool call is captured in the snapshot.\n */\nexport interface GateDecision {\n readonly allow: boolean\n readonly reason?: string\n}\n\nexport type GateBeforeTool = (\n toolName: string,\n input: unknown,\n) => GateDecision | Promise<GateDecision>\n\nexport interface AgentLoopOptions {\n readonly context: RunContext\n readonly client: ModelAdapter\n readonly executor: ToolExecutor\n readonly tools: ReadonlyArray<Tool>\n readonly system: string\n readonly contextLimit: number\n readonly compactionConfig?: ResolvedCompactionConfig | undefined\n readonly transcriptLocation?: TranscriptLocation\n /**\n * Optional storage adapter for writing the snapshot.json sidecar\n * when the loop pauses. Required if pause is wanted; if omitted,\n * gateBeforeTool denies will surface as failed runs instead.\n */\n readonly storage?: StorageAdapter\n /**\n * Pre-tool gate. Called before EVERY tool dispatch. Return\n * `{ allow: false }` to pause the run with the pending tool\n * captured in the snapshot. Default = always allow.\n */\n readonly gateBeforeTool?: GateBeforeTool\n /** Hooks fired before each turn's API call. */\n readonly preTurnHooks?: ReadonlyArray<PreTurnHook>\n /** Hooks fired after each turn's tool dispatch completes. */\n readonly postTurnHooks?: ReadonlyArray<PostTurnHook>\n /**\n * Optional abort signal for run-level timeout. When aborted, the loop\n * returns `failed(RunTimeoutError)` at the next checkpoint (top of the\n * turn loop or after a tool dispatch).\n */\n readonly runSignal?: AbortSignal\n /** Run-level timeout in milliseconds — carried for error messages. */\n readonly runTimeoutMs?: number\n /** Tool registry for concurrency-safety lookup during batch dispatch. */\n readonly registry?: ToolRegistry\n /** Max concurrent tool executions for safe batches. Default: 10. */\n readonly maxToolConcurrency?: number\n /**\n * Subagent registry — when set, completed background agents are\n * drained at the start of each turn and their results injected as\n * `<task-notification>` user messages.\n */\n readonly subagentRegistry?: import('../subagent/registry.js').SubagentRegistry\n /**\n * Token budget. When total tokens (input + output) exceed this,\n * the run stops gracefully. Ported from La-Machina's task_budget.\n */\n readonly tokenBudget?: number\n /**\n * Stop hooks — fire after each turn. Can return `{ preventContinuation: true }`\n * to stop the run gracefully. Ported from La-Machina's executeStopHooks().\n */\n readonly stopHooks?: ReadonlyArray<StopHook>\n /**\n * Progress callback fired at turn boundaries. Receives a `LoopProgress`\n * snapshot with current activity, turn count, tokens, and last tool\n * name. Used by `engine.start()` to keep `state.json` warm so\n * `getStatus()` returns non-zero progress during long runs.\n *\n * Errors from the callback are swallowed — progress reporting is\n * best-effort and must not break the loop.\n */\n readonly onProgress?: (progress: LoopProgress) => Promise<void> | void\n /**\n * Plan 019 — when true, the loop pauses with reason\n * `'handoff_to_runner'` as soon as a capability-stubbed tool is about\n * to be dispatched, so the async wrapper (`engine.start()` /\n * `resumeAsync()`) can POST `{ runId }` to the configured runner.\n *\n * Sync runs (`engine.run()`) never set this flag — stubs execute\n * normally and the model adapts its answer to the missing capability.\n */\n readonly handoffToRunner?: boolean\n /**\n * Plan 021 — when set, tool results exceeding `thresholdBytes`\n * are written to `{transcript.path}/toolResults/{toolUseId}.json`\n * and replaced in the message context with a short summary that\n * includes the ref. The model rehydrates via `FetchData({ ref })`.\n * Absent / `enabled: false` → all tool results pass through\n * verbatim as before.\n */\n readonly toolResultOffload?: import('./toolResultOffload.types.js').ResolvedToolResultOffloadConfigV1\n /**\n * Plan 021 — log path where offloaded tool results should be\n * written (`{offloadLogPath}/toolResults/{toolUseId}.json`). When\n * omitted, defaults to the transcript's `path`. Subagent runners\n * pass their `childLogPath` here because subagent transcripts\n * and snapshots live at different paths today.\n */\n readonly offloadLogPath?: string\n}\n\n/**\n * Progress payload fired by `onProgress` at turn boundaries. Maps\n * directly to `RunStateManager.RunProgress` on the engine side.\n */\nexport interface LoopProgress {\n /** Current turn index (1-based). */\n readonly turns: number\n /** Cumulative token usage across all turns so far. */\n readonly tokensUsed: TokenUsage\n /** What the loop is doing right now. */\n readonly currentActivity: 'idle' | 'streaming' | 'tool_dispatch' | 'compacting'\n /** Most recent tool name (when `currentActivity === 'tool_dispatch'`). */\n readonly lastTool?: string\n}\n\nexport type AgentLoopResult =\n | {\n readonly status: 'done'\n readonly output: string\n readonly tokensUsed: TokenUsage\n readonly turns: number\n }\n | {\n readonly status: 'paused'\n readonly snapshot: RunSnapshot\n readonly reason: PauseReason\n }\n | {\n readonly status: 'failed'\n readonly error: Error\n readonly transcript: TranscriptLocation\n }\n\nconst DEFAULT_COMPACTION: ResolvedCompactionConfig = {\n strategy: 'drop-middle',\n threshold: 0.85,\n keepLast: 6,\n summaryMaxTokens: 4096,\n microcompact: false,\n microcompactAgeMs: 300_000,\n}\n\nexport async function agentLoop(options: AgentLoopOptions): Promise<AgentLoopResult> {\n const { context: ctx, client, executor, tools, system, contextLimit } = options\n const compactionConfig = options.compactionConfig ?? DEFAULT_COMPACTION\n const transcript = options.transcriptLocation ?? {\n path: `projects/${ctx.runId}/nodes/${ctx.nodeId}`,\n lastShardIndex: 0,\n }\n\n const anthropicTools = tools.map(toAnthropicTool)\n let lastAssistantText = ''\n\n // Reactive recovery state — ported from La-Machina's query.ts.\n // On max_tokens, three-stage recovery:\n // 1. Escalate cap (8K → 64K) and retry same turn\n // 2. Inject recovery message and re-query (up to 3 attempts)\n // 3. Fail after exhaustion\n const MAX_OUTPUT_TOKENS_RECOVERY_LIMIT = 3\n const ESCALATED_MAX_TOKENS = 64_000\n let recoveryCount = 0\n let maxTokensEscalated = false\n let escalatedMaxTokens: number | undefined\n let compactedThisTurn = false\n\n // API retry state — application-level backoff for 429/500/529.\n const MAX_API_RETRIES = 3\n const BASE_BACKOFF_MS = 1000\n let apiRetryCount = 0\n let consecutive529 = 0\n const MAX_CONSECUTIVE_529 = 5\n\n const fireProgress = async (\n activity: LoopProgress['currentActivity'],\n lastTool?: string,\n ): Promise<void> => {\n if (options.onProgress === undefined) return\n try {\n await options.onProgress({\n turns: ctx.getTurnCount(),\n tokensUsed: ctx.getTokensUsed(),\n currentActivity: activity,\n ...(lastTool !== undefined ? { lastTool } : {}),\n })\n } catch {\n // Progress reporting is best-effort — never break the loop.\n }\n }\n\n for (;;) {\n compactedThisTurn = false\n if (options.runSignal?.aborted === true) {\n return failed(new RunTimeoutError(options.runTimeoutMs ?? 0), transcript)\n }\n if (!ctx.shouldContinue()) {\n return failed(new EngineError('ERR_MAX_TURNS', 'Run exceeded max turns'), transcript)\n }\n\n // Token budget enforcement — stop gracefully when budget exhausted.\n if (options.tokenBudget !== undefined) {\n const used = ctx.getTokensUsed()\n if (used.input + used.output >= options.tokenBudget) {\n return {\n status: 'done',\n output: lastAssistantText || '[Token budget exhausted]',\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n }\n\n // Drain completed background agents — inject their results as\n // task-notification messages so the model sees them.\n if (options.subagentRegistry) {\n const bgResults = options.subagentRegistry.drainCompletedBackgroundResults()\n for (const bg of bgResults) {\n const status = bg.isError ? 'failed' : 'completed'\n const notification = [\n '<task-notification>',\n `<task-id>${bg.agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>Background agent \"${bg.description ?? bg.agentId}\" ${status}</summary>`,\n `<result>${bg.output}</result>`,\n '</task-notification>',\n ].join('\\n')\n await ctx.addUserMessage(notification)\n }\n }\n\n // preTurn hooks\n if (options.preTurnHooks && options.preTurnHooks.length > 0) {\n await dispatchHooks(options.preTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount(),\n messageCount: ctx.getMessages().length,\n })\n }\n\n // Compact if needed — uses the configurable compaction system.\n let messages = ctx.getMessages()\n // Fire a 'compacting' progress signal only when compaction will actually\n // run; otherwise callers see noise for no-op turns.\n const mightCompact =\n ctx.getTokensUsed().input + ctx.getTokensUsed().output >\n contextLimit * compactionConfig.threshold\n if (mightCompact) await fireProgress('compacting')\n const compactResult = await compactIfNeeded({\n messages,\n usage: ctx.getTokensUsed(),\n contextLimit,\n config: compactionConfig,\n client,\n system,\n })\n if (compactResult.compacted) {\n messages = compactResult.messages\n }\n\n // Streaming — fire progress BEFORE we open the SSE so clients can\n // see \"streaming…\" activity during the longest wait of a turn.\n await fireProgress('streaming')\n\n // Stream this turn\n const textBlocks: string[] = []\n const thinkingBlocks: string[] = []\n const toolCalls: Array<{ id: string; name: string; input: unknown }> = []\n let stopReason: StopReason | null = null\n let turnUsage: TokenUsage = { input: 0, output: 0 }\n\n // Normalize messages before API call — merge consecutive same-role,\n // strip empty blocks. Prevents API 400 errors from malformed sequences.\n const normalizedMessages = normalizeMessages(\n messages as import('@anthropic-ai/sdk/resources/messages').MessageParam[],\n )\n\n try {\n for await (const event of client.streamMessage({\n messages: normalizedMessages as never,\n system,\n tools: anthropicTools as never,\n ...(escalatedMaxTokens !== undefined ? { maxTokens: escalatedMaxTokens } : {}),\n })) {\n const handled = consumeEvent(event)\n if (handled.text !== undefined) textBlocks.push(handled.text)\n if (handled.thinking !== undefined) thinkingBlocks.push(handled.thinking)\n if (handled.toolCall) toolCalls.push(handled.toolCall)\n if (handled.stop) {\n stopReason = handled.stop.reason\n turnUsage = handled.stop.usage\n }\n }\n } catch (err) {\n // 413 prompt-too-long recovery — emergency compact and retry once.\n // Ported from La-Machina's query.ts (lines 1067-1182).\n if (isPromptTooLong(err) && !compactedThisTurn) {\n compactedThisTurn = true\n const emergency = await compactIfNeeded({\n messages: messages as import('@anthropic-ai/sdk/resources/messages').MessageParam[],\n usage: ctx.getTokensUsed(),\n contextLimit: Math.floor(contextLimit * 0.6), // force below threshold\n config: { ...compactionConfig, threshold: 0, keepLast: 4 },\n client,\n system,\n })\n if (emergency.compacted) {\n // Replace context messages with compacted version and retry\n ctx.rehydrate({\n messages: emergency.messages,\n turnCount: ctx.getTurnCount(),\n tokensUsed: ctx.getTokensUsed(),\n lastUuid: ctx.getLastUuid(),\n })\n continue\n }\n }\n\n // Retryable error backoff (429/500/529) — exponential with Retry-After respect.\n if (isRetryable(err) && apiRetryCount < MAX_API_RETRIES) {\n apiRetryCount++\n\n // 529 overload counter — fail fast if API is persistently overloaded\n if (is529Overloaded(err)) {\n consecutive529++\n if (consecutive529 >= MAX_CONSECUTIVE_529) {\n return failed(\n new EngineError(\n 'ERR_API_OVERLOADED',\n `API overloaded (529) ${MAX_CONSECUTIVE_529} consecutive times`,\n ),\n transcript,\n )\n }\n } else {\n consecutive529 = 0\n }\n\n // Backoff: respect Retry-After header, otherwise exponential\n const retryAfter =\n err instanceof RateLimitError && err.retryAfterMs\n ? err.retryAfterMs\n : BASE_BACKOFF_MS * Math.pow(2, apiRetryCount - 1)\n const delay = Math.min(retryAfter, 30_000) // cap at 30s\n await new Promise((r) => setTimeout(r, delay))\n continue // retry the turn\n }\n\n return failed(toError(err), transcript)\n }\n\n ctx.addTokenUsage(turnUsage)\n\n // Build the assistant message and append it to context.\n // Thinking blocks come first (preserved for reasoning chain continuity),\n // then text, then tool_use — same order as La-Machina.\n const assistantContent: ContentBlockParam[] = []\n for (const thinking of thinkingBlocks) {\n if (thinking.length > 0) {\n assistantContent.push({ type: 'thinking', thinking } as unknown as ContentBlockParam)\n }\n }\n for (const text of textBlocks) {\n if (text.length > 0) assistantContent.push({ type: 'text', text })\n }\n for (const tc of toolCalls) {\n assistantContent.push({\n type: 'tool_use',\n id: tc.id,\n name: tc.name,\n input: (tc.input ?? {}) as Record<string, unknown>,\n })\n }\n if (assistantContent.length > 0) {\n await ctx.addAssistantMessage(assistantContent)\n } else if (stopReason !== null) {\n // Empty assistant response — model returned message_stop with no\n // content. Append a synthetic empty text block to prevent transcript\n // gaps and stale lastAssistantText. Ported from La-Machina.\n await ctx.addAssistantMessage([{ type: 'text', text: '' }])\n }\n\n lastAssistantText = textBlocks.join('').trim() || lastAssistantText\n\n // Tool dispatch — batch consecutive concurrency-safe tools for parallel execution\n if (toolCalls.length > 0) {\n // Duplicate tool_use ID detection — model bug, prevent double execution\n const seenIds = new Set<string>()\n const dedupedCalls = toolCalls.filter((call) => {\n if (seenIds.has(call.id)) return false\n seenIds.add(call.id)\n return true\n })\n const toolCallsToDispatch = dedupedCalls\n\n // Gate check: ALL tools must pass gate before any execution\n for (const call of toolCallsToDispatch) {\n if (options.gateBeforeTool) {\n const decision = await options.gateBeforeTool(call.name, call.input)\n if (!decision.allow) {\n const paused = await pauseHere({\n ctx,\n transcript,\n reason: 'gate_required',\n pendingToolCall: {\n toolName: call.name,\n toolUseId: call.id,\n input: call.input,\n calledAt: new Date().toISOString(),\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n return paused\n }\n }\n }\n\n // Plan 019 — runner handoff. When an async wrapper set\n // `handoffToRunner: true`, we pause before dispatching the first\n // capability-stubbed tool in the batch so a Node-side runner can\n // resume the run in its own process. Sync runs leave the flag\n // false and fall through to regular dispatch (the stub executes\n // and returns an isError result the model adapts to).\n if (options.handoffToRunner === true) {\n for (const call of toolCallsToDispatch) {\n const tool = options.registry?.get(call.name)\n if (tool?.isCapabilityStub === true) {\n const paused = await pauseHere({\n ctx,\n transcript,\n reason: 'handoff_to_runner',\n pendingToolCall: {\n toolName: call.name,\n toolUseId: call.id,\n input: call.input,\n calledAt: new Date().toISOString(),\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n return paused\n }\n }\n }\n\n // Tool dispatch — fire progress once before the batch starts,\n // carrying the name of the first tool so `getStatus` shows\n // something like \"tool_dispatch / Read\".\n const firstTool = toolCallsToDispatch[0]?.name\n await fireProgress('tool_dispatch', firstTool)\n\n // StreamingToolExecutor handles concurrency, ordering, and Bash\n // error cascading — ported 1:1 from La-Machina's StreamingToolExecutor.\n const streamExec = new StreamingToolExecutor(executor)\n for (const call of toolCallsToDispatch) {\n const tool = options.registry?.get(call.name)\n const safe = tool?.isConcurrencySafe?.(call.input) ?? false\n streamExec.addTool(call.id, call.name, call.input, safe)\n }\n try {\n for await (const { id, result } of streamExec.results()) {\n // Plan 019 — capability-stub invocations surface a\n // `metadata.capabilityMissing` field; record it so\n // `engine.toResponse()` can emit `meta.capabilitiesMissing`.\n const missing = result.metadata?.capabilityMissing\n if (typeof missing === 'string') {\n ctx.recordCapabilityMissing(missing)\n }\n\n // Plan 021 — offload large tool results. Helper is a\n // pass-through no-op when disabled / below threshold / on\n // error results.\n const call = toolCallsToDispatch.find((c) => c.id === id)\n let contentForTranscript: string\n if (options.toolResultOffload !== undefined && options.storage !== undefined) {\n try {\n contentForTranscript = await maybeOffloadToolResult({\n offloadConfig: options.toolResultOffload,\n storage: options.storage,\n logPath: options.offloadLogPath ?? transcript.path,\n toolUseId: id,\n toolName: call?.name ?? 'unknown',\n toolInput: call?.input,\n rawContent: result.content,\n rawIsError: result.isError === true,\n })\n } catch (err) {\n // Storage write failed mid-offload. Don't silently\n // drop the data — surface the failure to the model so\n // it knows the last tool call's output is unreadable.\n const msg = err instanceof Error ? err.message : String(err)\n contentForTranscript = `[tool-result offload failed: ${msg}] ${result.content.slice(0, 500)}`\n }\n } else {\n contentForTranscript = result.content\n }\n\n await ctx.addToolResult(\n id,\n truncateToolResult(contentForTranscript),\n result.isError === true,\n )\n }\n } catch (err) {\n // Gate propagation — a subagent's own gate denial throws\n // SubagentPausedError. Surface it as the parent's own pause\n // pointing at the Agent tool_use that spawned the child.\n if (err instanceof SubagentPausedError) {\n const parentCall = toolCallsToDispatch.find((c) => c.name === 'Agent')\n const pendingTool =\n parentCall !== undefined\n ? {\n toolName: parentCall.name,\n toolUseId: parentCall.id,\n input: parentCall.input,\n calledAt: new Date().toISOString(),\n }\n : undefined\n return pauseHere({\n ctx,\n transcript,\n reason: 'subagent_gate_required',\n ...(pendingTool !== undefined ? { pendingToolCall: pendingTool } : {}),\n pendingSubagent: {\n subagentType: err.subagentType,\n parentToolUseId: err.parentToolUseId,\n childSnapshot: err.childSnapshot,\n },\n storage: options.storage,\n subagentRegistry: options.subagentRegistry,\n })\n }\n throw err\n }\n\n // Successful tool dispatch — reset recovery state\n recoveryCount = 0\n maxTokensEscalated = false\n escalatedMaxTokens = undefined\n apiRetryCount = 0\n consecutive529 = 0\n\n await ctx.endTurn()\n // Turn-end progress — clients see turns count advance + activity idle.\n await fireProgress('idle')\n if (options.postTurnHooks && options.postTurnHooks.length > 0) {\n await dispatchHooks(options.postTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n })\n }\n\n // Stop hooks — can prevent continuation after tool dispatch\n if (options.stopHooks && options.stopHooks.length > 0) {\n const stopResult = await runStopHooks(options.stopHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n lastAssistantText,\n toolsCalled: toolCallsToDispatch.map((c) => c.name),\n status: 'tool_use',\n })\n if (stopResult?.preventContinuation) {\n return {\n status: 'done',\n output: lastAssistantText || '[Stopped by stop hook]',\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n }\n\n continue\n }\n\n // No tool calls — terminal turn\n await ctx.endTurn()\n if (options.postTurnHooks && options.postTurnHooks.length > 0) {\n await dispatchHooks(options.postTurnHooks, {\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n turnIndex: ctx.getTurnCount() - 1,\n tokensUsed: turnUsage,\n })\n }\n if (stopReason === 'end_turn' || stopReason === 'stop_sequence' || stopReason === null) {\n // Successful turn — reset recovery state\n recoveryCount = 0\n maxTokensEscalated = false\n escalatedMaxTokens = undefined\n apiRetryCount = 0\n consecutive529 = 0\n // Final heartbeat before returning — heartbeat consumers get a\n // clean \"idle\" marker on terminal state.\n await fireProgress('idle')\n return {\n status: 'done',\n output: lastAssistantText,\n tokensUsed: ctx.getTokensUsed(),\n turns: ctx.getTurnCount(),\n }\n }\n if (stopReason === 'max_tokens') {\n // Stage 1: Escalate max_tokens cap (8K → 64K) and retry\n if (!maxTokensEscalated) {\n maxTokensEscalated = true\n escalatedMaxTokens = ESCALATED_MAX_TOKENS\n continue // re-stream with higher cap — assistant message already appended\n }\n\n // Stage 2: Inject recovery message and re-query (up to 3 attempts)\n if (recoveryCount < MAX_OUTPUT_TOKENS_RECOVERY_LIMIT) {\n recoveryCount++\n escalatedMaxTokens = undefined // reset escalation for next attempt\n await ctx.addUserMessage(\n 'Output token limit hit. Resume directly — no apology, no recap of what you were doing. ' +\n 'Pick up mid-thought if that is where the cut happened. Break remaining work into smaller pieces.',\n )\n continue // re-query with recovery directive\n }\n\n // Stage 3: Exhaustion — fail after 3 attempts\n return failed(\n new EngineError(\n 'ERR_MAX_TOKENS',\n `max_tokens recovery exhausted after ${MAX_OUTPUT_TOKENS_RECOVERY_LIMIT} attempts`,\n ),\n transcript,\n )\n }\n // Any other stop reason without tool calls\n return failed(\n new EngineError('ERR_UNEXPECTED_STOP', `Unexpected stop reason: ${stopReason}`),\n transcript,\n )\n }\n}\n\ninterface ConsumedEvent {\n text?: string\n thinking?: string\n toolCall?: { id: string; name: string; input: unknown }\n stop?: { reason: StopReason; usage: TokenUsage }\n}\n\nfunction consumeEvent(event: NormalizedEvent): ConsumedEvent {\n if (event.type === 'text') return { text: event.text }\n if (event.type === 'thinking') return { thinking: event.thinking }\n if (event.type === 'tool_use') {\n return { toolCall: { id: event.id, name: event.name, input: event.input } }\n }\n return { stop: { reason: event.stopReason, usage: event.usage } }\n}\n\nfunction toAnthropicTool(tool: Tool): AnthropicTool {\n // MCP-adapted tools carry their native JSON Schema directly; prefer\n // that over running the Zod passthrough schema through zodToJsonSchema,\n // which would produce `{}`.\n if (tool.anthropicSchemaOverride !== undefined) {\n return {\n name: tool.name,\n description: tool.description,\n input_schema: tool.anthropicSchemaOverride as AnthropicTool['input_schema'],\n }\n }\n // zod-to-json-schema's signature accepts ZodSchema; our Tool generic\n // uses ZodTypeAny which is a structural superset, so we cast through\n // unknown rather than chase a more elaborate generic.\n const schema = zodToJsonSchema(tool.inputSchema as Parameters<typeof zodToJsonSchema>[0], {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n }) as Record<string, unknown>\n // Anthropic expects { type, properties, required } directly — strip\n // schema metadata that would otherwise confuse the API.\n const { $schema: _schema, ...inputSchema } = schema\n return {\n name: tool.name,\n description: tool.description,\n input_schema: inputSchema as AnthropicTool['input_schema'],\n }\n}\n\n// ---------- tool batching ----------\n\ninterface ToolBatch {\n concurrent: boolean\n calls: Array<{ id: string; name: string; input: unknown }>\n}\n\n/**\n * Partition tool calls into batches: consecutive concurrency-safe tools\n * are grouped together for parallel execution; each unsafe tool becomes\n * its own serial batch. Mirrors La-Machina's toolOrchestration.ts pattern.\n */\nexport function partitionToolCalls(\n calls: ReadonlyArray<{ id: string; name: string; input: unknown }>,\n registry?: ToolRegistry,\n): ToolBatch[] {\n const batches: ToolBatch[] = []\n for (const call of calls) {\n const tool = registry?.get(call.name)\n const safe = tool?.isConcurrencySafe?.(call.input) ?? false\n const last = batches[batches.length - 1]\n if (safe && last?.concurrent) {\n last.calls.push(call)\n } else {\n batches.push({ concurrent: safe, calls: [call] })\n }\n }\n return batches\n}\n\n// ---------- stop hooks ----------\n\n/**\n * Run stop hooks sequentially. If any returns `{ preventContinuation: true }`,\n * stop processing and return the result. Errors are isolated — a throwing\n * hook does not prevent other hooks from running.\n * Ported from La-Machina's executeStopHooks().\n */\nasync function runStopHooks(\n hooks: ReadonlyArray<StopHook>,\n event: import('../hooks/types.js').StopHookEvent,\n): Promise<StopHookResult | null> {\n for (const hook of hooks) {\n try {\n const result = await hook(event)\n if (result?.preventContinuation) return result\n } catch {\n // Hook errors are isolated — never abort the run\n }\n }\n return null\n}\n\n// ---------- retryable error detection ----------\n\n/** Check if an error is retryable (429 rate limit, 500 server error, 529 overloaded). */\nfunction isRetryable(err: unknown): boolean {\n if (err instanceof RateLimitError) return true\n if (err instanceof ApiError) {\n const s = err.status\n if (s === 429 || s === 500 || s === 502 || s === 503 || s === 529) return true\n }\n if (!(err instanceof Error)) return false\n const msg = err.message.toLowerCase()\n return (\n msg.includes('429') ||\n msg.includes('rate_limit') ||\n msg.includes('rate limit') ||\n msg.includes('500') ||\n msg.includes('overloaded') ||\n msg.includes('529') ||\n msg.includes('server error') ||\n msg.includes('service unavailable') ||\n msg.includes('network') ||\n msg.includes('connection') ||\n msg.includes('timeout') ||\n msg.includes('econnreset') ||\n msg.includes('socket hang up')\n )\n}\n\n/** Check if error is specifically a 529 overloaded response. */\nfunction is529Overloaded(err: unknown): boolean {\n if (err instanceof ApiError && err.status === 529) return true\n if (!(err instanceof Error)) return false\n return err.message.includes('529') || err.message.toLowerCase().includes('overloaded')\n}\n\n// ---------- 413 detection ----------\n\n/**\n * Detect prompt-too-long errors (HTTP 413 or API-level message).\n * Ported from La-Machina's isPromptTooLongMessage().\n */\nfunction isPromptTooLong(err: unknown): boolean {\n if (!(err instanceof Error)) return false\n const msg = err.message.toLowerCase()\n return (\n msg.includes('prompt is too long') ||\n msg.includes('request too large') ||\n msg.includes('413') ||\n msg.includes('too many tokens')\n )\n}\n\n// ---------- tool result truncation ----------\n\n/**\n * Cap tool result size to prevent exceeding API per-message limits.\n * Ported from La-Machina's toolResultStorage.ts budget enforcement.\n */\nconst MAX_TOOL_RESULT_CHARS = 100_000\n\nexport function truncateToolResult(content: string): string {\n if (content.length <= MAX_TOOL_RESULT_CHARS) return content\n return (\n content.slice(0, MAX_TOOL_RESULT_CHARS) +\n `\\n\\n[TRUNCATED — showing first ${MAX_TOOL_RESULT_CHARS.toLocaleString()} chars of ${content.length.toLocaleString()} total]`\n )\n}\n\n// ---------- helpers ----------\n\nfunction failed(error: Error, transcript: TranscriptLocation): AgentLoopResult {\n return { status: 'failed', error, transcript }\n}\n\nfunction toError(err: unknown): Error {\n if (err instanceof Error) return err\n return new Error(String(err))\n}\n\ninterface PauseHereOptions {\n readonly ctx: RunContext\n readonly transcript: TranscriptLocation\n readonly reason: PauseReason\n readonly pendingToolCall?: RunSnapshot['pendingToolCall'] | undefined\n readonly pendingSubagent?: RunSnapshot['pendingSubagent'] | undefined\n readonly storage?: StorageAdapter | undefined\n readonly subagentRegistry?: import('../subagent/registry.js').SubagentRegistry | undefined\n}\n\nasync function pauseHere(options: PauseHereOptions): Promise<AgentLoopResult> {\n const { ctx, transcript, reason, pendingToolCall, pendingSubagent, storage } = options\n\n // Drain running background agents before pausing — wait up to 10s for\n // in-flight work to complete so their results aren't lost. Results are\n // injected as task-notification messages into the context.\n if (options.subagentRegistry) {\n const bgResults = await options.subagentRegistry.awaitBackgroundAgents(10_000)\n for (const bg of bgResults) {\n const status = bg.isError ? 'failed' : 'completed'\n const notification = [\n '<task-notification>',\n `<task-id>${bg.agentId}</task-id>`,\n `<status>${status}</status>`,\n `<summary>Background agent \"${bg.description ?? bg.agentId}\" ${status}</summary>`,\n `<result>${bg.output}</result>`,\n '</task-notification>',\n ].join('\\n')\n await ctx.addUserMessage(notification)\n }\n }\n\n // Flush any buffered transcript entries BEFORE writing the snapshot.\n // Without this, entries written this turn (the user message, the\n // assistant tool_use call) would still be in memory and never reach\n // disk — resume would replay an incomplete history.\n await ctx.flushTranscript()\n\n const usage = ctx.getTokensUsed()\n const tokensUsed: RunSnapshot['tokensUsedSoFar'] = {\n input: usage.input,\n output: usage.output,\n ...(usage.cacheCreationInput !== undefined\n ? { cacheCreationInput: usage.cacheCreationInput }\n : {}),\n ...(usage.cacheReadInput !== undefined ? { cacheReadInput: usage.cacheReadInput } : {}),\n }\n const snapshot: RunSnapshot = {\n version: 1,\n status: 'paused',\n runId: ctx.runId,\n nodeId: ctx.nodeId,\n pausedAt: new Date().toISOString(),\n pauseReason: reason,\n messageCount: ctx.getMessages().length,\n lastShardIndex: transcript.lastShardIndex,\n lastMessageUuid: ctx.getLastUuid() ?? '00000000-0000-4000-8000-000000000000',\n ...(pendingToolCall ? { pendingToolCall } : {}),\n ...(pendingSubagent ? { pendingSubagent } : {}),\n tokensUsedSoFar: tokensUsed,\n turnsUsed: ctx.getTurnCount(),\n }\n if (storage) {\n await writeSnapshot(storage, transcript.path, snapshot)\n }\n return { status: 'paused', snapshot, reason }\n}\n","/**\n * RunSnapshot — JSON sidecar capturing the state of a paused run.\n *\n * Lives at `{logPath}/snapshot.json`. Written when the agent loop\n * decides to pause (gate required, max turns, explicit signal); read\n * by `engine.resume()` to rebuild the run state and continue.\n *\n * The snapshot is intentionally small — it does NOT contain the full\n * conversation history. The transcript shards are the source of\n * truth for messages; the snapshot just points at where to pick up\n * (lastShardIndex) and what was about to happen (pendingToolCall).\n *\n * Schema validation is strict on read: a corrupted or version-\n * mismatched snapshot is a hard error, not a silent fallback. Resume\n * state must be trustworthy.\n */\n\nimport { z } from 'zod'\nimport type { RunSnapshot } from '../engine/types.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nconst SNAPSHOT_FILENAME = 'snapshot.json'\n\nconst TokenUsageSchema = z\n .object({\n input: z.number().int().nonnegative(),\n output: z.number().int().nonnegative(),\n cacheCreationInput: z.number().int().nonnegative().optional(),\n cacheReadInput: z.number().int().nonnegative().optional(),\n })\n .strict()\n\nconst PendingToolCallSchema = z\n .object({\n toolName: z.string().min(1),\n toolUseId: z.string().min(1),\n input: z.unknown(),\n calledAt: z.string().datetime({ offset: true }),\n })\n .strict()\n\n// Lazy — RunSnapshot can embed another RunSnapshot inside\n// pendingSubagent.childSnapshot. Use z.lazy to let the schema reference itself.\nconst PendingSubagentSchema = z.lazy(() =>\n z\n .object({\n subagentType: z.string().min(1),\n parentToolUseId: z.string().min(1),\n childSnapshot: RunSnapshotSchema,\n })\n .strict(),\n)\n\nconst RunSnapshotSchema: z.ZodType<unknown> = z.lazy(() =>\n z\n .object({\n version: z.literal(1),\n status: z.literal('paused'),\n runId: z.string().min(1),\n nodeId: z.string().min(1),\n pausedAt: z.string().datetime({ offset: true }),\n pauseReason: z.enum([\n 'gate_required',\n 'subagent_gate_required',\n 'handoff_to_runner',\n 'max_turns',\n 'explicit',\n 'timeout',\n ]),\n messageCount: z.number().int().nonnegative(),\n lastShardIndex: z.number().int().nonnegative(),\n lastMessageUuid: z.string().uuid(),\n pendingToolCall: PendingToolCallSchema.optional(),\n pendingSubagent: PendingSubagentSchema.optional(),\n tokensUsedSoFar: TokenUsageSchema,\n turnsUsed: z.number().int().nonnegative(),\n })\n .strict(),\n)\n\nfunction snapshotPath(logPath: string): string {\n return `${logPath}/${SNAPSHOT_FILENAME}`\n}\n\n/**\n * Read and validate the snapshot at `{logPath}/snapshot.json`.\n * Returns null if the file does not exist; throws on corruption,\n * schema violation, or unknown version.\n */\nexport async function readSnapshot(\n storage: StorageAdapter,\n logPath: string,\n): Promise<RunSnapshot | null> {\n const raw = await storage.readFile(snapshotPath(logPath))\n if (raw === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (err) {\n throw new Error(\n `readSnapshot: invalid JSON at ${snapshotPath(logPath)}: ${(err as Error).message}`,\n )\n }\n\n // Surface a clearer error for version mismatch BEFORE schema parse\n // so callers can branch on it specifically (future versions will need\n // a migration shim here).\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'version' in parsed &&\n (parsed as { version: unknown }).version !== 1\n ) {\n throw new Error(\n `readSnapshot: unsupported snapshot version ${String(\n (parsed as { version: unknown }).version,\n )}; engine v0.1 only supports version 1`,\n )\n }\n\n const result = RunSnapshotSchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(\n `readSnapshot: schema violation at ${snapshotPath(logPath)}: ${result.error.message}`,\n )\n }\n return result.data as RunSnapshot\n}\n\n/**\n * Validate + atomically write the snapshot. Throws if the snapshot\n * fails schema validation BEFORE the write so we never persist a\n * malformed payload.\n */\nexport async function writeSnapshot(\n storage: StorageAdapter,\n logPath: string,\n snapshot: RunSnapshot,\n): Promise<void> {\n const validated = RunSnapshotSchema.parse(snapshot)\n await storage.writeFile(snapshotPath(logPath), JSON.stringify(validated, null, 2))\n}\n","/**\n * Offload helper — called from `agentLoop` immediately after a tool\n * result streams back, before `ctx.addToolResult` writes the content\n * into the transcript / message context (Plan 021 §4).\n *\n * Behavior:\n * - Offload disabled, content below threshold, or `isError: true`\n * → pass content through unchanged. (Errors MUST stay inline;\n * the model needs the error text verbatim to adapt.)\n * - Content above threshold → write full payload to\n * `{logPath}/toolResults/{toolUseId}.json` via the workspace\n * adapter, then build a short summary string (default or\n * user-supplied) and return that instead.\n *\n * The summary — not the raw content — is what lands in the\n * transcript. Rehydrate therefore reconstructs the same reduced\n * message history on resume. A new `FetchData` tool (built alongside)\n * reads the blob back when the model needs the full payload.\n */\n\nimport { defaultToolResultSummarizer } from './toolResultSummarizer.js'\nimport type { ResolvedToolResultOffloadConfigV1 } from './toolResultOffload.types.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface MaybeOffloadInput {\n readonly offloadConfig: ResolvedToolResultOffloadConfigV1 | undefined\n readonly storage: StorageAdapter\n readonly logPath: string\n readonly toolUseId: string\n readonly toolName: string\n readonly toolInput: unknown\n readonly rawContent: string\n readonly rawIsError: boolean\n}\n\n/**\n * Returns the content that should be written to the transcript:\n * either the raw content (when offload is off / below threshold /\n * error) or a summary string carrying the ref.\n *\n * Writes to storage as a side effect when offload fires. Storage\n * failures bubble up so the caller can surface them to the model\n * as a tool_result error rather than silently dropping the data.\n */\nexport async function maybeOffloadToolResult(input: MaybeOffloadInput): Promise<string> {\n const {\n offloadConfig,\n storage,\n logPath,\n toolUseId,\n toolName,\n toolInput,\n rawContent,\n rawIsError,\n } = input\n\n if (offloadConfig === undefined || offloadConfig.enabled !== true) {\n return rawContent\n }\n if (rawIsError) {\n // Errors always stay inline.\n return rawContent\n }\n if (toolName === 'FetchData') {\n // Never offload FetchData's own output — it's what the model\n // asked for after the original offload, and re-offloading would\n // replace the rehydrated content with another ref, trapping\n // the model in a hydrate loop.\n return rawContent\n }\n\n const rawBytes = byteLength(rawContent)\n if (rawBytes <= offloadConfig.thresholdBytes) {\n return rawContent\n }\n\n // Over threshold — offload.\n const path = `${logPath}/toolResults/${toolUseId}.json`\n await storage.writeFile(path, rawContent)\n\n const summarizer = offloadConfig.summarizer ?? defaultToolResultSummarizer\n const summary = await summarizer({\n toolName,\n toolInput,\n rawContent,\n rawBytes,\n ref: toolUseId,\n maxPreviewChars: offloadConfig.maxPreviewChars,\n })\n\n // Safety net — if a caller's custom summarizer forgot the ref,\n // append it so the model can still rehydrate. Better than silent\n // loss of access to the full payload.\n if (!summary.includes(toolUseId)) {\n return `${summary}\\n[offloaded — ref=${toolUseId}, use FetchData to read the full content]`\n }\n return summary\n}\n\nfunction byteLength(s: string): number {\n return new TextEncoder().encode(s).byteLength\n}\n","/**\n * Default deterministic summarizer for offloaded tool results\n * (Plan 021 §2).\n *\n * No LLM calls. Shape-aware for JSON arrays and top-level JSON\n * objects; falls back to first-N-chars for arbitrary text. The\n * returned string ALWAYS includes the `ref` token so the model\n * knows to call `FetchData({ ref })` when it needs the raw content.\n *\n * Users who want richer summarization (semantic summaries, tool-\n * specific extractors) can plug their own `ToolResultSummarizerV1`\n * via `config.compaction.toolResultOffload.summarizer`. An LLM-based\n * summarizer is on the roadmap — see Plan 021 \"Deferred with\n * triggers\" and the README.\n */\n\nimport type {\n ToolResultSummarizerCtxV1,\n ToolResultSummarizerV1,\n} from './toolResultOffload.types.js'\n\nconst MAX_ITEM_PREVIEW_CHARS = 150\nconst MAX_TOP_LEVEL_KEYS = 8\n\nexport const defaultToolResultSummarizer: ToolResultSummarizerV1 = (ctx) => {\n return summarize(ctx)\n}\n\nfunction summarize(ctx: ToolResultSummarizerCtxV1): string {\n const { toolName, rawContent, rawBytes, ref, maxPreviewChars } = ctx\n\n const parsed = tryParseJSON(rawContent)\n if (parsed.ok) {\n if (Array.isArray(parsed.value)) {\n return summarizeArray(toolName, parsed.value, ref, rawBytes)\n }\n if (parsed.value !== null && typeof parsed.value === 'object') {\n return summarizeObject(toolName, parsed.value as Record<string, unknown>, ref, rawBytes)\n }\n }\n\n // Arbitrary text path.\n const preview = rawContent.slice(0, maxPreviewChars)\n const truncated = rawContent.length > maxPreviewChars ? '…' : ''\n return (\n `[${toolName}] ${formatBytes(rawBytes)} offloaded.\\n` +\n (preview.length > 0 ? `Preview: ${preview}${truncated}\\n` : '') +\n `Use FetchData with ref=\"${ref}\" to read the full content.`\n )\n}\n\nfunction summarizeArray(toolName: string, arr: unknown[], ref: string, bytes: number): string {\n const count = arr.length\n const firstHint = arr.length > 0 ? compactPreview(arr[0]) : ''\n const hintLine = firstHint ? `First item preview: ${firstHint}\\n` : ''\n return (\n `[${toolName}] Array of ${count} item${count === 1 ? '' : 's'} (${formatBytes(bytes)}).\\n` +\n hintLine +\n `Use FetchData with ref=\"${ref}\" to read the full array.`\n )\n}\n\nfunction summarizeObject(\n toolName: string,\n obj: Record<string, unknown>,\n ref: string,\n bytes: number,\n): string {\n const keys = Object.keys(obj)\n const shown = keys.slice(0, MAX_TOP_LEVEL_KEYS)\n const overflow = keys.length > MAX_TOP_LEVEL_KEYS ? ` (+${keys.length - shown.length} more)` : ''\n const parts = shown.map((k) => `${k}=${compactPreview(obj[k])}`).join(', ')\n return (\n `[${toolName}] Object (${formatBytes(bytes)}). Keys: ${parts}${overflow}\\n` +\n `Use FetchData with ref=\"${ref}\" to read the full object.`\n )\n}\n\n/** One-line preview of any JSON value, capped at MAX_ITEM_PREVIEW_CHARS. */\nfunction compactPreview(value: unknown): string {\n let str: string\n if (value === null) {\n str = 'null'\n } else if (typeof value === 'string') {\n str = JSON.stringify(value) // quoted, so escaped newlines are visible\n } else if (Array.isArray(value)) {\n str = `[${value.length} item${value.length === 1 ? '' : 's'}]`\n } else if (typeof value === 'object') {\n const keys = Object.keys(value)\n str = `{${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', …' : ''}}`\n } else {\n str = String(value)\n }\n if (str.length > MAX_ITEM_PREVIEW_CHARS) {\n return str.slice(0, MAX_ITEM_PREVIEW_CHARS) + '…'\n }\n return str\n}\n\nfunction tryParseJSON(text: string): { ok: true; value: unknown } | { ok: false } {\n // Strip BOM if present — JSON.parse rejects it.\n const trimmed = text.replace(/^\\uFEFF/, '').trim()\n if (trimmed.length === 0) return { ok: false }\n // Cheap early reject — only attempt parse if it starts like JSON.\n const first = trimmed[0]\n if (first !== '{' && first !== '[' && first !== '\"') return { ok: false }\n try {\n return { ok: true, value: JSON.parse(trimmed) as unknown }\n } catch {\n return { ok: false }\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n","/**\n * dispatchHooks — fire every hook in a list, in registration order,\n * sequentially. Awaits async hooks. Isolates errors so a thrown hook\n * never propagates to the agent loop or engine.run() caller.\n *\n * The function takes a tuple of `(hookList, event)` and returns a\n * Promise that resolves once every hook has been awaited (or thrown\n * and been swallowed). Empty lists are silent no-ops.\n *\n * Hook errors are deliberately silent in v0.1 — they're caught and\n * dropped. Phase 11.5 / v0.2 may surface them via the logger sink so\n * caller-side observability tools can see misbehaving hooks. For now\n * the contract is \"hooks are best-effort, never load-bearing.\"\n */\n\ntype AnyHook<E> = (event: E) => void | Promise<void>\n\nexport async function dispatchHooks<E>(hooks: ReadonlyArray<AnyHook<E>>, event: E): Promise<void> {\n for (const hook of hooks) {\n try {\n const result = hook(event)\n if (result instanceof Promise) {\n await result.catch(() => undefined)\n }\n } catch {\n // Hook errors are isolated.\n }\n }\n}\n","/**\n * normalizeMessages — clean message arrays before sending to the API.\n *\n * Ported from La-Machina's normalizeMessagesForAPI(). The Anthropic\n * Messages API requires strict alternating user/assistant messages,\n * non-empty content blocks, and no consecutive same-role messages.\n *\n * This function:\n * 1. Strips internal blocks (advisor, signature, tool_reference, caller)\n * 2. Strips empty/whitespace-only text blocks and thinking blocks\n * 3. Drops messages with no content after filtering\n * 4. Merges consecutive same-role messages into one\n * 5. Ensures first message is user and strict alternation\n * 6. Validates tool_use ↔ tool_result pairing (injects synthetic results for orphans)\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ContentBlockParam, MessageParam } from '@anthropic-ai/sdk/resources/messages'\n\n// ---------- internal block patterns ----------\n\n/**\n * Regex patterns for internal blocks that should be stripped before API.\n * Ported from La-Machina's stripAdvisorBlocks, stripSignatureBlocks,\n * stripToolReferenceBlocks, stripCallerField.\n */\nconst INTERNAL_BLOCK_PATTERNS = [\n /<advisor>[\\s\\S]*?<\\/advisor>/g,\n /<tool_reference>[\\s\\S]*?<\\/tool_reference>/g,\n /<git_signature>[\\s\\S]*?<\\/git_signature>/g,\n /<caller>[\\s\\S]*?<\\/caller>/g,\n]\n\nfunction stripInternalBlocks(text: string): string {\n let result = text\n for (const pattern of INTERNAL_BLOCK_PATTERNS) {\n // Reset regex state (global flag)\n pattern.lastIndex = 0\n result = result.replace(pattern, '')\n }\n return result.trim()\n}\n\n// ---------- main normalization ----------\n\nexport function normalizeMessages(messages: readonly MessageParam[]): MessageParam[] {\n const result: MessageParam[] = []\n\n for (const msg of messages) {\n // Normalize content to array form\n let content: ContentBlockParam[]\n if (typeof msg.content === 'string') {\n const stripped = stripInternalBlocks(msg.content)\n if (stripped.length === 0) continue\n content = [{ type: 'text', text: stripped }]\n } else if (Array.isArray(msg.content)) {\n // Filter and clean each block\n content = msg.content\n .map((b) => {\n if (b.type === 'text') {\n const stripped = stripInternalBlocks((b as { type: 'text'; text: string }).text)\n if (stripped.length === 0) return null\n return { ...b, text: stripped } as ContentBlockParam\n }\n // Strip thinking blocks — preserved in transcript but not sent to API\n if ((b as { type: string }).type === 'thinking') return null\n if ((b as { type: string }).type === 'redacted_thinking') return null\n return b\n })\n .filter((b): b is ContentBlockParam => b !== null)\n\n if (content.length === 0) continue\n } else {\n continue\n }\n\n // Merge consecutive same-role messages\n const prev = result[result.length - 1]\n if (prev !== undefined && prev.role === msg.role) {\n const prevContent = Array.isArray(prev.content)\n ? prev.content\n : [{ type: 'text' as const, text: prev.content }]\n result[result.length - 1] = {\n role: msg.role,\n content: [...prevContent, ...content],\n }\n continue\n }\n\n result.push({ role: msg.role, content })\n }\n\n // Ensure first message is from user (API requirement)\n if (result.length > 0 && result[0]!.role !== 'user') {\n result.unshift({\n role: 'user',\n content: [{ type: 'text', text: '[system: conversation start]' }],\n })\n }\n\n // Ensure strict alternation\n const fixed: MessageParam[] = []\n for (const msg of result) {\n const prev = fixed[fixed.length - 1]\n if (prev && prev.role === msg.role) {\n const fillerRole = msg.role === 'user' ? 'assistant' : 'user'\n fixed.push({\n role: fillerRole,\n content: [{ type: 'text', text: '[continued]' }],\n })\n }\n fixed.push(msg)\n }\n\n // Tool result pairing — ensure every tool_use has a matching tool_result.\n // Ported from La-Machina's ensureToolResultPairing().\n return ensureToolResultPairing(fixed)\n}\n\n// ---------- tool result pairing ----------\n\n/**\n * Scan messages for orphaned tool_use blocks (no matching tool_result)\n * and inject synthetic error results. Prevents API 400 errors from\n * incomplete tool call sequences.\n */\nfunction ensureToolResultPairing(messages: MessageParam[]): MessageParam[] {\n const pendingToolUseIds = new Set<string>()\n\n for (const msg of messages) {\n if (!Array.isArray(msg.content)) continue\n for (const b of msg.content) {\n const block = b as { type: string; id?: string; tool_use_id?: string }\n if (block.type === 'tool_use' && block.id) {\n pendingToolUseIds.add(block.id)\n }\n if (block.type === 'tool_result' && block.tool_use_id) {\n pendingToolUseIds.delete(block.tool_use_id)\n }\n }\n }\n\n // All paired — no fix needed\n if (pendingToolUseIds.size === 0) return messages\n\n // Inject synthetic error results for orphaned tool_use blocks\n const syntheticResults: ContentBlockParam[] = [...pendingToolUseIds].map((id) => ({\n type: 'tool_result' as const,\n tool_use_id: id,\n content: '[Tool result missing — execution was interrupted]',\n is_error: true,\n }))\n\n // Append as a user message (tool_results must be in user messages)\n messages.push({ role: 'user', content: syntheticResults })\n\n return messages\n}\n","/**\n * Compactor — the top-level compaction orchestrator.\n *\n * Decides WHEN to compact (token threshold) and HOW (strategy selection).\n *\n * Called by the agent loop at the top of each turn. Returns either the\n * original messages (no compaction needed) or compacted messages with a\n * result describing what happened.\n *\n * Strategy selection in 'auto' mode:\n * 1. If `microcompact` is enabled, run it first (cheap, no LLM call).\n * 2. If tokens still over threshold, try `summarize` (LLM-driven).\n * 3. If summarize fails or is unavailable, fall back to `drop-middle`.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { TokenUsage } from '../api/streaming.js'\nimport { dropMiddle } from './dropMiddle.js'\nimport { microcompact } from './microcompact.js'\nimport { summarizeCompact } from './summarize.js'\nimport type { CompactionResult, ResolvedCompactionConfig } from './types.js'\n\nexport interface CompactIfNeededOptions {\n readonly messages: readonly MessageParam[]\n readonly usage: TokenUsage\n readonly contextLimit: number\n readonly config: ResolvedCompactionConfig\n readonly client: ModelAdapter\n readonly system: string\n}\n\nexport async function compactIfNeeded(\n options: CompactIfNeededOptions,\n): Promise<{ compacted: boolean; result: CompactionResult | null; messages: MessageParam[] }> {\n const { messages, usage, contextLimit, config, client, system } = options\n\n // Check if compaction is needed.\n const used =\n usage.input + usage.output + (usage.cacheReadInput ?? 0) + (usage.cacheCreationInput ?? 0)\n const ratio = used / contextLimit\n\n if (ratio <= config.threshold) {\n // Below threshold — no compaction needed.\n // But if microcompact is enabled, still run it opportunistically\n // to keep old tool results trimmed.\n if (config.microcompact && messages.length > config.keepLast + 4) {\n const mcResult = microcompact({\n messages,\n keepRecent: config.keepLast,\n })\n if (mcResult.dropped > 0) {\n return { compacted: true, result: mcResult, messages: mcResult.messages }\n }\n }\n return { compacted: false, result: null, messages: [...messages] }\n }\n\n // Above threshold — compact using the configured strategy.\n const result = await executeStrategy(messages, config, client, system)\n return { compacted: true, result, messages: result.messages }\n}\n\nasync function executeStrategy(\n messages: readonly MessageParam[],\n config: ResolvedCompactionConfig,\n client: ModelAdapter,\n system: string,\n): Promise<CompactionResult> {\n // Run microcompact first if enabled (cheap, might bring us under).\n let workingMessages = [...messages]\n if (config.microcompact) {\n const mcResult = microcompact({\n messages: workingMessages,\n keepRecent: config.keepLast,\n })\n workingMessages = mcResult.messages\n }\n\n switch (config.strategy) {\n case 'drop-middle':\n return dropMiddle(workingMessages, config.keepLast)\n\n case 'summarize':\n return summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n\n case 'session-memory':\n // Session memory compaction would extract facts to persistent memory.\n // For v0.2, we fall through to summarize — session-memory is a v0.3\n // refinement that needs tighter integration with the Hippocampus.\n return summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n\n case 'auto':\n default:\n // Auto: try summarize, fall back to drop-middle on failure.\n try {\n return await summarizeCompact({\n messages: workingMessages,\n config,\n client,\n system,\n })\n } catch {\n return dropMiddle(workingMessages, config.keepLast)\n }\n }\n}\n","/**\n * Drop-middle compaction — the v0.1 strategy, kept as a fallback.\n *\n * Drops everything between the first user message and the last K\n * messages, replacing the gap with a placeholder marker.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { CompactionResult } from './types.js'\n\nexport function dropMiddle(messages: readonly MessageParam[], keepLast: number): CompactionResult {\n const firstUserIndex = messages.findIndex((m) => m.role === 'user')\n if (firstUserIndex === -1) {\n return { messages: [...messages], strategy: 'drop-middle', dropped: 0 }\n }\n\n const tailStart = Math.max(messages.length - keepLast, firstUserIndex + 1)\n const tail = messages.slice(tailStart)\n const middleStart = firstUserIndex + 1\n const droppedCount = Math.max(0, tailStart - middleStart)\n\n if (droppedCount === 0) {\n return { messages: [...messages], strategy: 'drop-middle', dropped: 0 }\n }\n\n const marker: MessageParam = {\n role: 'user',\n content: [\n {\n type: 'text',\n text: `[compacted: ${droppedCount} earlier message${droppedCount === 1 ? '' : 's'} dropped to fit the context window. Key findings and decisions from those messages may be lost — re-derive if needed.]`,\n },\n ],\n }\n\n return {\n messages: [messages[firstUserIndex] as MessageParam, marker, ...tail],\n strategy: 'drop-middle',\n dropped: droppedCount,\n }\n}\n","/**\n * Microcompaction — time-based clearing of old tool results.\n *\n * Does NOT call the LLM. Simply replaces the content of tool_result\n * messages older than `microcompactAgeMs` with a placeholder string.\n * The message structure is preserved (role, tool_use_id, etc.) so the\n * API's tool_use ↔ tool_result pairing stays valid.\n *\n * Ported from La-Machina's microCompact.ts. The engine's version is\n * simpler because we don't have the API cache_edits mechanism —\n * we mutate messages in-place before passing them to the next turn.\n *\n * Compactable tools (safe to clear old results): Read, Grep, Glob,\n * WebFetch, WebSearch, Bash (stdout-only outputs). We do NOT clear\n * tool results from Write, Edit, Agent, TaskCreate, Memorize, etc.\n * because their results may contain confirmation IDs or state the\n * model needs to reference later.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { CompactionResult } from './types.js'\n\nconst CLEARED_MARKER = '[Old tool result content cleared to save context space]'\n\n/** Tools whose results are safe to clear after they age out. */\nexport const COMPACTABLE_TOOLS = new Set([\n 'Read',\n 'Grep',\n 'Glob',\n 'WebFetch',\n 'WebSearch',\n 'Bash',\n 'ToolSearch',\n])\n\nexport interface MicrocompactOptions {\n readonly messages: readonly MessageParam[]\n /** How many recent messages to never touch. */\n readonly keepRecent: number\n /** Tool names from the registry — only compact known tools. */\n readonly knownToolNames?: ReadonlySet<string>\n}\n\nexport function microcompact(options: MicrocompactOptions): CompactionResult {\n const { messages, keepRecent } = options\n if (messages.length <= keepRecent) {\n return { messages: [...messages], strategy: 'microcompact', dropped: 0 }\n }\n\n const cutoff = messages.length - keepRecent\n let cleared = 0\n const out: MessageParam[] = []\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i]!\n if (i >= cutoff || msg.role !== 'user') {\n out.push(msg)\n continue\n }\n\n // Tool results are user messages with content blocks that have\n // type: 'tool_result'. Check if any blocks are compactable.\n if (!Array.isArray(msg.content)) {\n out.push(msg)\n continue\n }\n\n // Tool results are user messages with content blocks. We check each\n // block for tool_result type and clear large content in old blocks.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const blocks = msg.content as any[]\n let modified = false\n const newBlocks = blocks.map((block: any) => {\n if (block.type !== 'tool_result') return block\n const content = block.content\n if (typeof content === 'string' && content !== CLEARED_MARKER && content.length > 100) {\n modified = true\n cleared++\n return { ...block, content: CLEARED_MARKER }\n }\n if (Array.isArray(content)) {\n const hasLargeText = content.some(\n (c: any) => c?.type === 'text' && typeof c.text === 'string' && c.text.length > 100,\n )\n if (hasLargeText) {\n modified = true\n cleared++\n return { ...block, content: CLEARED_MARKER }\n }\n }\n return block\n })\n\n out.push(modified ? { ...msg, content: newBlocks } : msg)\n }\n\n return { messages: out, strategy: 'microcompact', dropped: cleared }\n}\n","/**\n * LLM-driven summarization compaction.\n *\n * Sends the middle messages to the model with a summarization prompt.\n * Replaces the dropped messages with the LLM-generated summary as a\n * synthetic user message. The model retains semantic understanding\n * without the raw token cost.\n *\n * The summarizer uses the same API client as the main run — sharing\n * the connection and (when applicable) the prompt cache.\n */\n\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/messages'\nimport type { ModelAdapter } from '../model/adapter.js'\nimport type { CompactionResult, ResolvedCompactionConfig } from './types.js'\nimport { buildSummarizationPrompt } from './prompt.js'\n\nexport interface SummarizeOptions {\n readonly messages: readonly MessageParam[]\n readonly config: ResolvedCompactionConfig\n readonly client: ModelAdapter\n readonly system: string\n}\n\nexport async function summarizeCompact(options: SummarizeOptions): Promise<CompactionResult> {\n const { messages, config, client, system } = options\n\n const firstUserIndex = messages.findIndex((m) => m.role === 'user')\n if (firstUserIndex === -1) {\n return { messages: [...messages], strategy: 'summarize', dropped: 0 }\n }\n\n const tailStart = Math.max(messages.length - config.keepLast, firstUserIndex + 1)\n const tail = messages.slice(tailStart)\n const middle = messages.slice(firstUserIndex + 1, tailStart)\n const droppedCount = middle.length\n\n if (droppedCount === 0) {\n return { messages: [...messages], strategy: 'summarize', dropped: 0 }\n }\n\n // Build the summarization request: include the first user message +\n // the middle messages as conversation history, then ask for a summary.\n const summaryMessages: MessageParam[] = [\n messages[firstUserIndex] as MessageParam,\n ...middle,\n {\n role: 'user',\n content: buildSummarizationPrompt(droppedCount),\n },\n ]\n\n let summaryText: string\n try {\n summaryText = await generateSummary(client, system, summaryMessages, config.summaryMaxTokens)\n } catch {\n // If summarization fails (API error, timeout, etc.), fall back to\n // drop-middle so the run can continue. Log at warn level.\n const marker: MessageParam = {\n role: 'user',\n content: `[compacted: ${droppedCount} messages dropped — summarization failed, using drop-middle fallback]`,\n }\n return {\n messages: [messages[firstUserIndex] as MessageParam, marker, ...tail],\n strategy: 'summarize',\n dropped: droppedCount,\n }\n }\n\n const summaryMarker: MessageParam = {\n role: 'user',\n content: `[Context summary — ${droppedCount} earlier messages compacted into this summary]\\n\\n${summaryText}`,\n }\n\n return {\n messages: [messages[firstUserIndex] as MessageParam, summaryMarker, ...tail],\n strategy: 'summarize',\n dropped: droppedCount,\n summaryLength: summaryText.length,\n }\n}\n\nasync function generateSummary(\n client: ModelAdapter,\n system: string,\n messages: MessageParam[],\n maxTokens: number,\n): Promise<string> {\n const pieces: string[] = []\n\n for await (const event of client.streamMessage({\n messages,\n system,\n maxTokens,\n temperature: 0,\n })) {\n if (event.type === 'text') {\n pieces.push(event.text)\n }\n }\n\n const raw = pieces.join('')\n if (raw.length === 0) {\n throw new Error('Summarization returned empty response')\n }\n\n // Strip <analysis> blocks if present (La-Machina convention —\n // the model uses it as scratchpad before the real summary).\n const cleaned = raw\n .replace(/<analysis>[\\s\\S]*?<\\/analysis>/gi, '')\n .replace(/<\\/?summary>/gi, '')\n .trim()\n\n return cleaned.length > 0 ? cleaned : raw\n}\n","/**\n * Summarization prompt — ported from La-Machina's compact/prompt.ts.\n *\n * 100+ lines of structured instructions that guide the LLM to produce\n * high-quality conversation summaries that preserve:\n * - File paths, line numbers, code snippets\n * - Errors and how they were resolved\n * - Decision rationale and pending tasks\n * - User messages (non-tool results)\n *\n * The <analysis> block is a scratchpad the model uses to plan the\n * summary before writing it — stripped post-processing.\n */\n\nexport function buildSummarizationPrompt(droppedCount: number): string {\n return `CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.\n- Do NOT use Read, Bash, Grep, Glob, Edit, Write, or ANY other tool.\n- You already have all the context you need in the conversation above.\n- Tool calls will be REJECTED and will waste your only turn — you will fail the task.\n- Your entire response must be plain text: an <analysis> block followed by a <summary> block.\n\nYour task is to create a detailed summary of the conversation so far.\n${droppedCount} messages from the middle of the conversation are being compacted to fit the context window.\n\nYour summary should include the following sections:\n\n1. **Primary Request and Intent**\n What the user originally asked for and what they're trying to achieve.\n\n2. **Key Technical Concepts**\n Important architectural decisions, patterns, or constraints discovered.\n\n3. **Files and Code Sections**\n Every file that was read, modified, or created — with FULL file paths.\n Include key code snippets verbatim (not paraphrased) when they are\n central to understanding the changes made.\n\n4. **Errors and Fixes**\n Every error encountered, its root cause, and how it was resolved.\n Include the actual error messages.\n\n5. **Problem Solving**\n Approaches tried, why they failed or succeeded, and the reasoning\n behind the current approach.\n\n6. **All User Messages**\n Reproduce every user message (not tool results) from the conversation\n in chronological order, preserving the user's exact words or a close\n paraphrase. These are the primary requirements.\n\n7. **Pending Tasks**\n Anything that was planned but not yet completed. Include specific\n next steps.\n\n8. **Current Work**\n What was being worked on when this summary was generated. Include\n the last assistant action and its result.\n\n9. **Optional Next Step**\n If the conversation suggests a clear next action, state it with\n direct quotes from recent messages.\n\nWrite your response in this format:\n\n<analysis>\n[Your internal reasoning about what to include — this is your scratchpad.\nThink about what information is load-bearing vs what can be safely dropped.\nThis block will be stripped before the summary is used.]\n</analysis>\n\n<summary>\n[Your structured summary following the 9 sections above.\nBe thorough — anything not in this summary will be permanently lost.\nInclude specific file paths, variable names, error messages, and code\nsnippets. Prefer exact quotes over paraphrasing.]\n</summary>\n\nREMINDER: Do NOT call any tools. Respond with plain text only — an <analysis> block followed by a <summary> block.`\n}\n","/**\n * StreamingToolExecutor — stateful tool queue with ordered result yielding,\n * concurrency control, and sibling error cascading.\n *\n * Ported 1:1 from La-Machina's StreamingToolExecutor.ts. Key behaviors:\n *\n * - Tools are enqueued via `addTool()` and executed as they become eligible\n * - `canExecute()` enforces: concurrent-safe tools run in parallel; unsafe\n * tools run alone (exclusive access)\n * - Results are yielded in **original enqueue order** regardless of\n * completion order (preserves tool_result ordering for the API)\n * - On **Bash error**, `siblingAbortController.abort()` cancels all queued\n * siblings with synthetic error results. Only Bash cascades — Read/Grep/\n * WebFetch errors are independent.\n * - All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ToolResult } from '../tools/contract.js'\nimport type { ToolExecutor } from './toolRuntime.js'\n\nexport type ToolStatus = 'queued' | 'executing' | 'completed'\n\ninterface TrackedTool {\n readonly id: string\n readonly name: string\n readonly input: unknown\n readonly isConcurrencySafe: boolean\n status: ToolStatus\n result?: ToolResult\n promise?: Promise<void>\n resolve?: () => void\n}\n\nexport class StreamingToolExecutor {\n private readonly tools: TrackedTool[] = []\n private readonly executor: ToolExecutor\n private readonly siblingAbort = new AbortController()\n private bashErrorDesc: string | null = null\n\n constructor(executor: ToolExecutor) {\n this.executor = executor\n }\n\n /**\n * Enqueue a tool call. Eligible tools start executing immediately.\n */\n addTool(id: string, name: string, input: unknown, isConcurrencySafe: boolean): void {\n this.tools.push({ id, name, input, status: 'queued', isConcurrencySafe })\n this.processQueue()\n }\n\n /**\n * Yield results in original enqueue order. Waits for each tool to\n * complete before yielding — guarantees the API sees tool_result\n * blocks in the same order as the tool_use blocks.\n */\n async *results(): AsyncGenerator<{ id: string; result: ToolResult }> {\n for (const tool of this.tools) {\n // Wait for this tool to finish (may already be done)\n if (tool.promise) await tool.promise\n // Subagent pause — rethrow the stashed error so the parent\n // agentLoop's try/catch can surface it as a `paused` result.\n // eslint-disable-next-line @typescript-eslint/only-throw-error\n const sp = (tool as TrackedTool & { subagentPausedError?: unknown }).subagentPausedError\n if (sp !== undefined) throw sp as Error\n yield { id: tool.id, result: tool.result! }\n }\n }\n\n // ---------- internal ----------\n\n /**\n * Can this tool start now? Mirrors La-Machina's canExecuteTool():\n * - If nothing is executing → yes\n * - If only concurrent-safe tools are executing AND this tool is safe → yes\n * - Otherwise → no (wait for exclusive access)\n */\n private canExecute(isConcurrencySafe: boolean): boolean {\n const executing = this.tools.filter((t) => t.status === 'executing')\n return (\n executing.length === 0 || (isConcurrencySafe && executing.every((t) => t.isConcurrencySafe))\n )\n }\n\n /**\n * Walk the queue and start any eligible tools. Called after enqueue\n * and after each tool completes (to unblock the next batch).\n */\n private processQueue(): void {\n for (const tool of this.tools) {\n if (tool.status !== 'queued') continue\n\n // Sibling already aborted → mark cancelled immediately\n if (this.siblingAbort.signal.aborted) {\n tool.status = 'completed'\n tool.result = {\n content: `Cancelled: parallel tool call \"${this.bashErrorDesc ?? 'bash'}\" errored`,\n isError: true,\n }\n // Create a resolved promise so results() doesn't block\n tool.promise = Promise.resolve()\n continue\n }\n\n if (this.canExecute(tool.isConcurrencySafe)) {\n this.startTool(tool)\n } else if (!tool.isConcurrencySafe) {\n // Don't skip past an exclusive tool — it must run before anything after it\n break\n }\n }\n }\n\n private startTool(tool: TrackedTool): void {\n tool.status = 'executing'\n\n // Create a promise that external code (results()) can await.\n // The resolve function is called when execution completes.\n let resolvePromise: () => void\n tool.promise = new Promise<void>((r) => {\n resolvePromise = r\n })\n\n // Fire and let processQueue() handle what comes next.\n // `void` — intentional fire-and-forget; completion is observed via\n // `tool.promise` which results() awaits.\n void this.executeTool(tool).then(() => {\n resolvePromise()\n })\n }\n\n private async executeTool(tool: TrackedTool): Promise<void> {\n try {\n tool.result = await this.executor.execute(tool.name, tool.input)\n } catch (err) {\n // Subagent pause propagation — surface the error through the\n // result channel so consumers see it as a throw when they iterate\n // `results()`. We attach a sentinel so consumer code can pick it\n // up and re-throw outside the executor boundary.\n if (isSubagentPausedError(err)) {\n tool.result = {\n content: '__SUBAGENT_PAUSED__',\n isError: true,\n }\n ;(tool as TrackedTool & { subagentPausedError?: unknown }).subagentPausedError = err\n } else {\n tool.result = {\n content: `Tool crashed: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n }\n\n tool.status = 'completed'\n\n // Bash error cascading — only Bash errors cancel siblings.\n // Bash commands often have implicit dependency chains (mkdir → write).\n // Read/WebFetch/etc. are independent — one failure shouldn't nuke the rest.\n if (tool.result.isError && tool.name === 'Bash') {\n const cmd = (tool.input as { command?: string } | undefined)?.command\n this.bashErrorDesc = cmd ? cmd.slice(0, 60) : 'bash'\n this.siblingAbort.abort('sibling_error')\n }\n\n // Unblock next queued tools\n this.processQueue()\n }\n}\n\nfunction isSubagentPausedError(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as { code?: unknown; childSnapshot?: unknown }\n return e.code === 'ERR_SUBAGENT_PAUSED' && e.childSnapshot !== undefined\n}\n","/**\n * RunContext — per-run state for the agent loop.\n *\n * Holds the conversation history (in Anthropic Messages API shape), the\n * turn counter, accumulated token usage, and a reference to the\n * `TranscriptWriter` that persists every state transition.\n *\n * Every method that mutates state ALSO writes a transcript entry, so\n * the writer is the single source of truth for \"what happened during\n * this run.\" The agent loop never touches the writer directly — it\n * only goes through `RunContext`.\n *\n * UUID chaining: each transcript entry's `parentUuid` points at the\n * previous entry's `uuid`, forming a linked list. The first entry has\n * `parentUuid: null`. This lets the reader reconstruct order even\n * when shards arrive out of band.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\nimport type {\n ContentBlockParam,\n MessageParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { TokenUsage } from '../api/streaming.js'\nimport type { EpisodicMemory } from '../memory/episodes.js'\nimport type { Entry } from '../transcript/entries.js'\nimport type { TranscriptWriter } from '../transcript/writer.js'\n\nexport interface RunContextOptions {\n readonly runId: string\n readonly nodeId: string\n readonly writer: TranscriptWriter\n readonly maxTurns: number\n readonly clock?: () => Date\n /**\n * Optional episodic memory. When set, every message mutation logs\n * a corresponding episode line. When omitted, episodic logging is\n * disabled (used by tests that don't care about the log).\n */\n readonly episodes?: EpisodicMemory\n}\n\nexport class RunContext {\n readonly runId: string\n readonly nodeId: string\n private readonly writer: TranscriptWriter\n private readonly maxTurns: number\n private readonly clock: () => Date\n private readonly episodes: EpisodicMemory | null\n\n private readonly messages: MessageParam[] = []\n private turnCount = 0\n private tokensUsed: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n } = { input: 0, output: 0 }\n\n private lastUuid: string | null = null\n\n /**\n * Plan 019 — names of tools whose capability-stub returned an\n * `isError` result during this run. Aggregated and surfaced on the\n * response's `meta.capabilitiesMissing` (deduped, insertion-ordered).\n */\n private readonly capabilitiesMissing = new Set<string>()\n\n constructor(options: RunContextOptions) {\n this.runId = options.runId\n this.nodeId = options.nodeId\n this.writer = options.writer\n this.maxTurns = options.maxTurns\n this.clock = options.clock ?? (() => new Date())\n this.episodes = options.episodes ?? null\n }\n\n // ---------- message mutators ----------\n\n async addUserMessage(text: string): Promise<void> {\n const content: ContentBlockParam[] = [{ type: 'text', text }]\n this.messages.push({ role: 'user', content })\n await this.writeEntry({\n type: 'user',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'user', content },\n })\n this.episodes?.logTurn(this.turnCount, 'user', text)\n }\n\n async addAssistantMessage(content: ContentBlockParam[]): Promise<void> {\n this.messages.push({ role: 'assistant', content })\n await this.writeEntry({\n type: 'assistant',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'assistant', content },\n })\n if (this.episodes) {\n // Episode payload is the assistant text + tool_use call signatures\n // joined into a single line. Tool inputs are stringified so the\n // search index can match against them later.\n const summary = content\n .map((block) => {\n const b = block as { type: string; text?: string; name?: string; input?: unknown }\n if (b.type === 'text') return b.text ?? ''\n if (b.type === 'tool_use') return `[${b.name ?? '?'}: ${JSON.stringify(b.input ?? {})}]`\n return ''\n })\n .filter((s) => s.length > 0)\n .join(' ')\n this.episodes.logTurn(this.turnCount, 'assistant', summary)\n }\n }\n\n /**\n * Inject a tool_result + a follow-up text block as a SINGLE user\n * message. Used by the resume() synthetic-release path when a\n * paused run is resumed without an explicit `gateAnswer`: we need\n * to both satisfy the tool_use↔tool_result pairing AND give the\n * model a retry instruction, in the same user turn.\n *\n * Splitting this into `addToolResult(...) + addUserMessage(...)`\n * produces two consecutive user messages, which the AI SDK's\n * openai-compatible adapter rejects with\n * `MissingToolResultsError`. Combining them into one user message\n * is the portable shape that works on every provider we support.\n *\n * Writes a single `user` transcript entry carrying the mixed\n * content, so `rebuildMessagesFromEntries` reconstructs the same\n * single-message shape on resume.\n */\n async addMixedUserMessage(blocks: ContentBlockParam[]): Promise<void> {\n this.messages.push({ role: 'user', content: blocks })\n await this.writeEntry({\n type: 'user',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n message: { role: 'user', content: blocks },\n })\n // Episodic memory — log the tool_result content + any text blocks.\n const summary = blocks\n .map((b) => {\n const x = b as { type?: string; text?: string; content?: unknown }\n if (x.type === 'text') return x.text ?? ''\n if (x.type === 'tool_result') {\n return typeof x.content === 'string' ? x.content : JSON.stringify(x.content)\n }\n return ''\n })\n .filter((s) => s.length > 0)\n .join('\\n')\n this.episodes?.logTurn(this.turnCount, 'user', summary)\n }\n\n /**\n * Append a tool result to the conversation. The Anthropic Messages\n * API requires tool_result blocks to be wrapped in a user message,\n * so multiple results in the same turn collapse into one user message\n * by appending blocks to the previous tool_result message.\n */\n async addToolResult(toolUseId: string, content: string, isError: boolean): Promise<void> {\n const block: ToolResultBlockParam = {\n type: 'tool_result',\n tool_use_id: toolUseId,\n content,\n ...(isError ? { is_error: true } : {}),\n }\n\n // If the previous message is a user message containing only\n // tool_result blocks, append to it. Otherwise create a new one.\n const prev = this.messages[this.messages.length - 1]\n if (\n prev !== undefined &&\n prev.role === 'user' &&\n Array.isArray(prev.content) &&\n prev.content.every(\n (b) => typeof b === 'object' && (b as { type: string }).type === 'tool_result',\n )\n ) {\n prev.content.push(block)\n } else {\n this.messages.push({ role: 'user', content: [block] })\n }\n\n await this.writeEntry({\n type: 'tool_result',\n uuid: this.nextUuid(),\n parentUuid: this.lastUuid,\n ts: this.now(),\n toolUseId,\n content,\n ...(isError ? { isError: true } : {}),\n })\n this.episodes?.logTurn(this.turnCount, 'tool_result', content, {\n toolUseId,\n isError,\n })\n }\n\n // ---------- accessors ----------\n\n getMessages(): readonly MessageParam[] {\n return this.messages\n }\n\n getTurnCount(): number {\n return this.turnCount\n }\n\n getTokensUsed(): Readonly<typeof this.tokensUsed> {\n return this.tokensUsed\n }\n\n /** Plan 019 — record that a capability-stubbed tool fired during this run. */\n recordCapabilityMissing(toolName: string): void {\n this.capabilitiesMissing.add(toolName)\n }\n\n /** Plan 019 — capability-stubbed tool names observed this run (deduped). */\n getCapabilitiesMissing(): readonly string[] {\n return [...this.capabilitiesMissing]\n }\n\n shouldContinue(): boolean {\n return this.turnCount < this.maxTurns\n }\n\n /** UUID of the most recently appended transcript entry, or null. */\n getLastUuid(): string | null {\n return this.lastUuid\n }\n\n /** Force-flush any buffered transcript entries through the writer. */\n async flushTranscript(): Promise<void> {\n await this.writer.flushLog()\n }\n\n /**\n * Re-seed a fresh RunContext with state from a paused snapshot. Used\n * by `engine.resume()` after the transcript has been replayed into\n * `addRehydratedMessage` calls. Sets the turn counter, token usage,\n * and last-uuid pointer back to where the run left off.\n */\n rehydrate(state: {\n messages: ReadonlyArray<MessageParam>\n turnCount: number\n tokensUsed: {\n input: number\n output: number\n cacheCreationInput?: number\n cacheReadInput?: number\n }\n lastUuid: string | null\n }): void {\n this.messages.length = 0\n this.messages.push(...state.messages)\n this.turnCount = state.turnCount\n this.tokensUsed = { ...state.tokensUsed }\n this.lastUuid = state.lastUuid\n }\n\n // ---------- mutators ----------\n\n incrementTurn(): void {\n this.turnCount++\n }\n\n /**\n * Mark the end of a turn: bumps the local counter AND flushes the\n * transcript writer's pending shards (under turn-end policy) plus\n * updates meta.json. The agent loop calls this once per turn.\n */\n async endTurn(): Promise<void> {\n this.turnCount++\n await this.writer.endTurn()\n }\n\n addTokenUsage(usage: TokenUsage): void {\n this.tokensUsed.input += usage.input\n this.tokensUsed.output += usage.output\n if (usage.cacheCreationInput !== undefined) {\n this.tokensUsed.cacheCreationInput =\n (this.tokensUsed.cacheCreationInput ?? 0) + usage.cacheCreationInput\n }\n if (usage.cacheReadInput !== undefined) {\n this.tokensUsed.cacheReadInput = (this.tokensUsed.cacheReadInput ?? 0) + usage.cacheReadInput\n }\n }\n\n // ---------- internal ----------\n\n private async writeEntry(entry: Entry): Promise<void> {\n await this.writer.append(entry)\n this.lastUuid = entry.uuid\n }\n\n private nextUuid(): string {\n return randomUUID()\n }\n\n private now(): string {\n return this.clock().toISOString()\n }\n}\n","/**\n * ToolExecutor — runs tools by name with input validation, timeouts,\n * cancellation, error isolation, and lifecycle hooks.\n *\n * Responsibilities:\n * 1. Resolve a tool by name from a `ToolRegistry`. Unknown name →\n * typed error result, never an exception.\n * 2. Validate the caller-supplied input against the tool's Zod schema.\n * Invalid input → typed error result.\n * 3. Build a `ToolContext` with an `AbortSignal` that fires on either\n * timeout or external cancellation.\n * 4. Race the tool's `execute()` against `timeoutMs` (when set). On\n * timeout, return an error result and abort the context signal.\n * 5. Catch any synchronous or asynchronous throw from the tool and\n * wrap it as `{ content, isError: true }`. **A misbehaving tool\n * must never crash the agent loop.**\n * 6. Fire `preToolCall` and `postToolCall` hooks. `postToolCall` runs\n * in a finally semantic — even on error, even on timeout. Hook\n * failures are isolated; they never propagate.\n *\n * The executor is stateless except for the registry reference; a\n * single instance per engine run is fine.\n */\n\nimport type { PermissionPolicy } from '../permissions/evaluator.js'\nimport type { Tool, ToolContext, ToolResult } from '../tools/contract.js'\nimport type { ToolRegistry } from '../tools/contract.js'\n\nexport interface PreToolCallEvent {\n readonly toolName: string\n readonly input: unknown\n}\n\nexport interface PostToolCallEvent {\n readonly toolName: string\n readonly input: unknown\n readonly result: ToolResult\n readonly durationMs: number\n}\n\nexport interface ToolExecutorHooks {\n readonly preToolCall?: (event: PreToolCallEvent) => void | Promise<void>\n readonly postToolCall?: (event: PostToolCallEvent) => void | Promise<void>\n}\n\nexport interface ToolExecutorOptions {\n readonly registry: ToolRegistry\n /** Per-call timeout in milliseconds. Omit or 0 to disable. */\n readonly timeoutMs?: number\n readonly hooks?: ToolExecutorHooks\n /** Permission policy. When set, every tool dispatch is checked before\n * execution. Denied tools get an isError result without running. */\n readonly permissions?: PermissionPolicy\n}\n\nexport interface ExecuteOptions {\n /** Optional external AbortSignal that can cancel the tool early. */\n readonly signal?: AbortSignal\n}\n\nconst DEFAULT_TIMEOUT_MS = 0 // 0 = no timeout\n\nexport class ToolExecutor {\n private readonly registry: ToolRegistry\n private readonly timeoutMs: number\n private readonly hooks: ToolExecutorHooks\n private readonly permissions: PermissionPolicy | undefined\n\n constructor(options: ToolExecutorOptions) {\n this.registry = options.registry\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.hooks = options.hooks ?? {}\n this.permissions = options.permissions\n }\n\n async execute(\n toolName: string,\n rawInput: unknown,\n options: ExecuteOptions = {},\n ): Promise<ToolResult> {\n const start = Date.now()\n let result: ToolResult\n\n await this.firePreHook(toolName, rawInput)\n try {\n result = await this.executeInner(toolName, rawInput, options)\n } catch (err) {\n // Subagent pause propagation — must escape the tool runtime so\n // the agentLoop can surface it as a parent pause. All other\n // errors are defensively wrapped as tool-level failures.\n if (isSubagentPausedError(err)) throw err\n result = errorResult(`Tool runtime crashed: ${describeError(err)}`)\n }\n await this.firePostHook(toolName, rawInput, result, Date.now() - start)\n return result\n }\n\n // ---------- internal ----------\n\n private async executeInner(\n toolName: string,\n rawInput: unknown,\n options: ExecuteOptions,\n ): Promise<ToolResult> {\n const tool = this.registry.get(toolName)\n if (!tool) {\n return errorResult(`Tool \"${toolName}\" not found in registry`)\n }\n\n // Permission check — before input validation so denied tools pay\n // zero parsing cost.\n if (this.permissions !== undefined) {\n const decision = this.permissions.check(toolName)\n if (!decision.allowed) {\n return errorResult(decision.reason)\n }\n }\n\n const parsed = tool.inputSchema.safeParse(rawInput)\n if (!parsed.success) {\n return errorResult(`Tool \"${toolName}\" validation failed: ${parsed.error.message}`)\n }\n\n return this.runWithTimeout(tool, parsed.data as never, options.signal)\n }\n\n private async runWithTimeout(\n tool: Tool,\n input: unknown,\n externalSignal: AbortSignal | undefined,\n ): Promise<ToolResult> {\n const controller = new AbortController()\n if (externalSignal) {\n if (externalSignal.aborted) controller.abort()\n else externalSignal.addEventListener('abort', () => controller.abort(), { once: true })\n }\n\n const ctx: ToolContext = { signal: controller.signal }\n let timeoutHandle: ReturnType<typeof setTimeout> | null = null\n let timedOut = false\n\n const timeoutPromise =\n this.timeoutMs > 0\n ? new Promise<ToolResult>((resolve) => {\n timeoutHandle = setTimeout(() => {\n timedOut = true\n controller.abort()\n resolve(errorResult(`Tool \"${tool.name}\" timed out after ${this.timeoutMs}ms`))\n }, this.timeoutMs)\n })\n : null\n\n let toolPromise: Promise<ToolResult>\n try {\n // Wrap tool.execute() in a Promise.resolve so synchronous throws\n // become rejected promises and are caught uniformly.\n toolPromise = Promise.resolve().then(() => tool.execute(input as never, ctx))\n } catch (err) {\n // Truly synchronous throws before the await would be caught here,\n // but Promise.resolve().then() above already handles that path.\n return errorResult(`Tool \"${tool.name}\" threw synchronously: ${describeError(err)}`)\n }\n\n try {\n const result = timeoutPromise\n ? await Promise.race([toolPromise, timeoutPromise])\n : await toolPromise\n\n if (timedOut) {\n // The timeout already produced an error result; ignore the\n // stale tool result that may resolve later.\n return errorResult(`Tool \"${tool.name}\" timed out after ${this.timeoutMs}ms`)\n }\n return result\n } catch (err) {\n // Subagent pause propagation is NOT an error — the parent's\n // agentLoop must see the throw so it can produce its own paused\n // result with `pendingSubagent` set. Rethrow so it escapes the\n // tool-executor's \"wrap everything as isError\" semantics.\n if (isSubagentPausedError(err)) throw err\n return errorResult(`Tool \"${tool.name}\" threw: ${describeError(err)}`)\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle)\n }\n }\n\n private async firePreHook(toolName: string, input: unknown): Promise<void> {\n if (!this.hooks.preToolCall) return\n try {\n await this.hooks.preToolCall({ toolName, input })\n } catch {\n // Hook failures are isolated.\n }\n }\n\n private async firePostHook(\n toolName: string,\n input: unknown,\n result: ToolResult,\n durationMs: number,\n ): Promise<void> {\n if (!this.hooks.postToolCall) return\n try {\n await this.hooks.postToolCall({ toolName, input, result, durationMs })\n } catch {\n // Hook failures are isolated.\n }\n }\n}\n\nfunction errorResult(message: string): ToolResult {\n return { content: message, isError: true }\n}\n\n/**\n * Structural check for SubagentPausedError without importing engine/errors\n * (keeps the tool runtime dependency-light for tests that stub it).\n */\nfunction isSubagentPausedError(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as { code?: unknown; childSnapshot?: unknown }\n return e.code === 'ERR_SUBAGENT_PAUSED' && e.childSnapshot !== undefined\n}\n\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.message\n return String(err)\n}\n","/**\n * TranscriptWriter — shard-per-flush NDJSON writer.\n *\n * Buffers `Entry` records in memory, serializes them to JSONL, and flushes\n * them as numbered shard files (`000000.jsonl`, `000001.jsonl`, ...) under\n * `{logPath}/`. Each flush also updates `meta.json`.\n *\n * ## Flush triggers\n *\n * A flush can be triggered by any of:\n * 1. **Explicit**: `flushLog()`\n * 2. **Turn boundary**: `endTurn()` + `flushPolicy === 'turn-end'`\n * 3. **Every entry**: `append()` + `flushPolicy === 'entry'`\n * 4. **Size ceiling**: buffer grows past `maxBufferBytes`\n * 5. **Idle timer**: `idleFlushMs` has elapsed since the last append\n * 6. **Close**: `close()` always flushes pending content\n *\n * The idle timer is reset on every append. If the process stays quiet\n * long enough, the buffered content lands on disk without caller action.\n *\n * ## Concurrency\n *\n * A **single-flight guard** ensures that `flushLog()` calls issued while\n * another flush is in progress coalesce — they all await the same promise.\n * This prevents double-writing a shard and race conditions on the counter.\n *\n * ## Error recovery\n *\n * On write failure, the buffer is restored and the counter is NOT bumped,\n * so the caller can retry `flushLog()` and land the same content in the\n * same shard slot. No data is lost unless the process dies between the\n * failure and the retry.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { serializeEntry, type Entry } from './entries.js'\nimport {\n createInitialMeta,\n readMeta,\n writeMeta,\n type TranscriptMeta,\n type TranscriptStatus,\n} from './meta.js'\n\nexport type FlushPolicy = 'turn-end' | 'entry' | 'manual'\n\nexport interface TranscriptWriterOptions {\n readonly storage: StorageAdapter\n readonly logPath: string\n readonly flushPolicy: FlushPolicy\n /** Buffer size ceiling in bytes; flush triggered when exceeded. */\n readonly maxBufferBytes?: number\n /** Idle duration in ms after which a flush is triggered. 0 disables. */\n readonly idleFlushMs?: number\n /** Injectable clock for deterministic timestamps in tests. */\n readonly clock?: () => Date\n /**\n * Initial shard counter — used by `engine.resume()` to continue\n * appending after a paused run without overwriting existing shards.\n * Defaults to 0 (fresh run).\n */\n readonly initialShardIndex?: number\n /**\n * Initial meta document — used by `engine.resume()` to preserve\n * counters and timestamps from the prior run. If omitted, the writer\n * starts with a fresh `pending` meta.\n */\n readonly initialMeta?: TranscriptMeta\n}\n\nconst DEFAULT_MAX_BUFFER_BYTES = 256 * 1024\nconst SHARD_DIGITS = 6\n\nexport class TranscriptWriter {\n private readonly storage: StorageAdapter\n private readonly logPath: string\n private readonly flushPolicy: FlushPolicy\n private readonly maxBufferBytes: number\n private readonly idleFlushMs: number\n private readonly clock: () => Date\n\n private buffer: string[] = []\n private bufferBytes = 0\n private nextShardIndex = 0\n private meta: TranscriptMeta\n private closed = false\n private flushInFlight: Promise<void> | null = null\n private idleTimer: ReturnType<typeof setTimeout> | null = null\n\n constructor(options: TranscriptWriterOptions) {\n this.storage = options.storage\n this.logPath = options.logPath\n this.flushPolicy = options.flushPolicy\n this.maxBufferBytes = options.maxBufferBytes ?? DEFAULT_MAX_BUFFER_BYTES\n this.idleFlushMs = options.idleFlushMs ?? 0\n this.clock = options.clock ?? (() => new Date())\n this.meta = options.initialMeta ?? createInitialMeta(this.clock)\n this.nextShardIndex = options.initialShardIndex ?? 0\n }\n\n // ---------- public API ----------\n\n async append(entry: Entry): Promise<void> {\n this.assertOpen()\n\n const line = serializeEntry(entry) + '\\n'\n this.buffer.push(line)\n this.bufferBytes += line.length\n this.meta = { ...this.meta, messageCount: this.meta.messageCount + 1 }\n\n // Policy: flush on every entry\n if (this.flushPolicy === 'entry') {\n await this.flushLog()\n return\n }\n\n // Safety: flush if buffer has exceeded the size ceiling\n if (this.bufferBytes >= this.maxBufferBytes) {\n await this.flushLog()\n return\n }\n\n // Schedule / reset the idle flush timer\n this.resetIdleTimer()\n }\n\n async endTurn(): Promise<void> {\n this.assertOpen()\n\n this.meta = {\n ...this.meta,\n turnCount: this.meta.turnCount + 1,\n updatedAt: this.clock().toISOString(),\n }\n\n if (this.flushPolicy === 'turn-end' && this.buffer.length > 0) {\n await this.flushLog()\n } else {\n // Even if we're not flushing a shard, persist the bumped turnCount.\n await writeMeta(this.storage, this.logPath, this.meta)\n }\n }\n\n flushLog(): Promise<void> {\n // Coalesce with any in-flight flush\n if (this.flushInFlight) return this.flushInFlight\n if (this.buffer.length === 0) return Promise.resolve()\n\n this.flushInFlight = this.doFlush().finally(() => {\n this.flushInFlight = null\n })\n return this.flushInFlight\n }\n\n async setStatus(status: TranscriptStatus): Promise<void> {\n this.meta = {\n ...this.meta,\n status,\n updatedAt: this.clock().toISOString(),\n }\n await writeMeta(this.storage, this.logPath, this.meta)\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.clearIdleTimer()\n if (this.buffer.length > 0) {\n await this.flushLog()\n }\n this.closed = true\n }\n\n // ---------- internals ----------\n\n private async doFlush(): Promise<void> {\n const shardIndex = this.nextShardIndex\n const shardName = formatShardName(shardIndex)\n const shardKey = `${this.logPath}/${shardName}`\n const content = this.buffer.join('')\n const contentBytes = this.bufferBytes\n\n // Clear buffer before write so new appends during the async write\n // don't double-land in this shard. On failure we restore.\n this.buffer = []\n this.bufferBytes = 0\n\n try {\n await this.storage.writeFile(shardKey, content)\n } catch (err) {\n // Restore buffer + keep counter — caller can retry.\n this.buffer.unshift(content)\n this.bufferBytes = contentBytes\n throw err\n }\n\n this.nextShardIndex = shardIndex + 1\n this.meta = {\n ...this.meta,\n status: this.meta.status === 'pending' ? 'running' : this.meta.status,\n lastShardIndex: shardIndex,\n shardCount: this.meta.shardCount + 1,\n updatedAt: this.clock().toISOString(),\n }\n await writeMeta(this.storage, this.logPath, this.meta)\n this.clearIdleTimer()\n }\n\n private resetIdleTimer(): void {\n if (this.idleFlushMs <= 0) return\n this.clearIdleTimer()\n this.idleTimer = setTimeout(() => {\n this.idleTimer = null\n void this.flushLog().catch(() => {\n // Swallow errors from background flush — caller's next operation\n // will observe the error via the restored buffer or directly.\n })\n }, this.idleFlushMs)\n }\n\n private clearIdleTimer(): void {\n if (this.idleTimer) {\n clearTimeout(this.idleTimer)\n this.idleTimer = null\n }\n }\n\n private assertOpen(): void {\n if (this.closed) {\n throw new Error('TranscriptWriter is closed')\n }\n }\n}\n\nfunction formatShardName(index: number): string {\n return `${String(index).padStart(SHARD_DIGITS, '0')}.jsonl`\n}\n\n/**\n * Re-hydrate a writer's shard counter + meta from an existing transcript.\n * Used by pause/resume so the next shard lands at `lastShardIndex + 1`.\n * Returns null if there is no existing meta at `logPath`.\n */\nexport async function loadWriterState(\n storage: StorageAdapter,\n logPath: string,\n): Promise<{ nextShardIndex: number; meta: TranscriptMeta } | null> {\n const existing = await readMeta(storage, logPath)\n if (existing === null) return null\n const nextShardIndex = existing.lastShardIndex === null ? 0 : existing.lastShardIndex + 1\n return { nextShardIndex, meta: existing }\n}\n","/**\n * Transcript entry types and schemas.\n *\n * A transcript is a sequence of `Entry` records persisted as newline-\n * delimited JSON (NDJSON) sharded across numbered `.jsonl` files. This\n * module defines the entry type union, their Zod schemas, and the\n * serialize/parse helpers used by the writer and reader.\n *\n * The entry vocabulary is deliberately minimal — seven types. Everything\n * CLI-UX-specific in La-Machina's 19-type union has been dropped. Only\n * what a workflow engine needs to replay, audit, and learn from:\n *\n * user — user message (prompt, tool result from the client)\n * assistant — assistant message (text + tool_use blocks)\n * tool_result — result of a tool call dispatched by the engine\n * subagent_spawn — a child agent was created\n * subagent_done — a child agent returned its final output\n * meta — session-scoped metadata (title, tags, workflow ctx)\n * error — engine-level failure (tool crash, stream break, etc.)\n */\n\nimport { z } from 'zod'\n\n// ---------- shared base schema ----------\n\nconst UuidSchema = z.string().uuid()\nconst IsoTsSchema = z.string().datetime({ offset: true })\n\nconst TimelineBase = {\n uuid: UuidSchema,\n parentUuid: UuidSchema.nullable(),\n ts: IsoTsSchema,\n} as const\n\nconst SessionBase = {\n uuid: UuidSchema,\n ts: IsoTsSchema,\n} as const\n\n// ---------- message content blocks (permissive; tightened in Phase 4) ----------\n\nconst MessageSchema = z\n .object({\n role: z.enum(['user', 'assistant']),\n content: z.array(z.unknown()),\n })\n .strict()\n\n// ---------- individual entry schemas ----------\n\nconst UserEntrySchema = z\n .object({\n type: z.literal('user'),\n ...TimelineBase,\n message: MessageSchema,\n })\n .strict()\n\nconst AssistantEntrySchema = z\n .object({\n type: z.literal('assistant'),\n ...TimelineBase,\n message: MessageSchema,\n })\n .strict()\n\nconst ToolResultEntrySchema = z\n .object({\n type: z.literal('tool_result'),\n ...TimelineBase,\n toolUseId: z.string().min(1),\n content: z.unknown(),\n isError: z.boolean().optional(),\n })\n .strict()\n\nconst SubagentSpawnEntrySchema = z\n .object({\n type: z.literal('subagent_spawn'),\n ...TimelineBase,\n agentId: z.string().min(1),\n agentType: z.string().min(1),\n })\n .strict()\n\nconst SubagentDoneEntrySchema = z\n .object({\n type: z.literal('subagent_done'),\n ...TimelineBase,\n agentId: z.string().min(1),\n output: z.string(),\n })\n .strict()\n\nconst MetaEntrySchema = z\n .object({\n type: z.literal('meta'),\n ...SessionBase,\n key: z.string().min(1),\n value: z.unknown(),\n })\n .strict()\n\nconst ErrorEntrySchema = z\n .object({\n type: z.literal('error'),\n ...SessionBase,\n error: z\n .object({\n code: z.string().min(1),\n message: z.string(),\n stack: z.string().optional(),\n })\n .strict(),\n })\n .strict()\n\n// ---------- top-level union ----------\n\nexport const EntrySchema = z.discriminatedUnion('type', [\n UserEntrySchema,\n AssistantEntrySchema,\n ToolResultEntrySchema,\n SubagentSpawnEntrySchema,\n SubagentDoneEntrySchema,\n MetaEntrySchema,\n ErrorEntrySchema,\n])\n\nexport type Entry = z.infer<typeof EntrySchema>\nexport type UserEntry = z.infer<typeof UserEntrySchema>\nexport type AssistantEntry = z.infer<typeof AssistantEntrySchema>\nexport type ToolResultEntry = z.infer<typeof ToolResultEntrySchema>\nexport type SubagentSpawnEntry = z.infer<typeof SubagentSpawnEntrySchema>\nexport type SubagentDoneEntry = z.infer<typeof SubagentDoneEntrySchema>\nexport type MetaEntry = z.infer<typeof MetaEntrySchema>\nexport type ErrorEntry = z.infer<typeof ErrorEntrySchema>\n\n// ---------- serialization helpers ----------\n\n/**\n * Serialize an entry to a single JSON line (no trailing newline).\n * The writer is responsible for appending `\\n` between lines.\n * Throws if the entry fails schema validation — we never write\n * malformed entries to disk.\n */\nexport function serializeEntry(entry: Entry): string {\n const validated = EntrySchema.parse(entry)\n return JSON.stringify(validated)\n}\n\n/**\n * Parse a single NDJSON line into an entry. Throws if the line is\n * malformed JSON or if the parsed object does not match any entry variant.\n * The caller is responsible for providing context (shard index, line\n * number) in the thrown error message if wanted.\n */\nexport function parseEntryLine(line: string): Entry {\n if (line.length === 0) {\n throw new Error('parseEntryLine: empty line')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(line)\n } catch (err) {\n throw new Error(`parseEntryLine: invalid JSON: ${(err as Error).message}`)\n }\n const result = EntrySchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(`parseEntryLine: not a valid Entry — ${result.error.message}`)\n }\n return result.data\n}\n","/**\n * TranscriptMeta — the small sidecar at `{logPath}/meta.json` that the\n * writer updates on every flush.\n *\n * The meta document serves two purposes:\n * 1. **Fast session listing**: upstream callers (Nikaido, dashboard)\n * can stat this file to know turn count, status, and last update\n * without reading the transcript shards.\n * 2. **Resume anchor**: on pause/resume, the snapshot points to the\n * last shard index recorded here, letting the reader skip straight\n * to where it left off.\n *\n * The document is tiny (<1KB) and written frequently, so the cost of\n * overwriting on every flush is negligible. Writes go through the\n * storage adapter's atomic `writeFile`.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport type TranscriptStatus = 'pending' | 'running' | 'paused' | 'done' | 'failed'\n\nconst TranscriptMetaSchema = z\n .object({\n version: z.literal(1),\n status: z.enum(['pending', 'running', 'paused', 'done', 'failed']),\n startedAt: z.string().datetime({ offset: true }),\n updatedAt: z.string().datetime({ offset: true }),\n turnCount: z.number().int().nonnegative(),\n messageCount: z.number().int().nonnegative(),\n lastShardIndex: z.number().int().nonnegative().nullable(),\n shardCount: z.number().int().nonnegative(),\n })\n .strict()\n\nexport type TranscriptMeta = z.infer<typeof TranscriptMetaSchema>\n\nconst META_FILENAME = 'meta.json'\n\nfunction metaPath(logPath: string): string {\n return `${logPath}/${META_FILENAME}`\n}\n\n/**\n * Create a fresh meta document in `pending` state. Pass a `clock` for\n * deterministic timestamps in tests.\n */\nexport function createInitialMeta(clock: () => Date = () => new Date()): TranscriptMeta {\n const now = clock().toISOString()\n return {\n version: 1,\n status: 'pending',\n startedAt: now,\n updatedAt: now,\n turnCount: 0,\n messageCount: 0,\n lastShardIndex: null,\n shardCount: 0,\n }\n}\n\n/**\n * Read `meta.json` from `{logPath}/`. Returns `null` if the file does not\n * exist. Throws if the file is corrupted or fails schema validation — this\n * is a hard error, not a soft \"ignore the bad meta and continue\" case,\n * because a corrupted meta means we can't trust resume state.\n */\nexport async function readMeta(\n storage: StorageAdapter,\n logPath: string,\n): Promise<TranscriptMeta | null> {\n const raw = await storage.readFile(metaPath(logPath))\n if (raw === null) return null\n\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch (err) {\n throw new Error(`readMeta: invalid JSON at ${metaPath(logPath)}: ${(err as Error).message}`)\n }\n\n const result = TranscriptMetaSchema.safeParse(parsed)\n if (!result.success) {\n throw new Error(`readMeta: schema violation at ${metaPath(logPath)}: ${result.error.message}`)\n }\n return result.data\n}\n\n/**\n * Validate + persist `meta.json`. Writes are atomic via the adapter's\n * temp+rename semantics, so a concurrent `readMeta` will either see the\n * previous version or the new one, never a partial.\n */\nexport async function writeMeta(\n storage: StorageAdapter,\n logPath: string,\n meta: TranscriptMeta,\n): Promise<void> {\n const validated = TranscriptMetaSchema.parse(meta)\n await storage.writeFile(metaPath(logPath), JSON.stringify(validated, null, 2))\n}\n","/**\n * Fork subagent — child inherits parent's full message context.\n *\n * Ported 1:1 from La-Machina's forkSubagent.ts. When `subagent_type`\n * is omitted, the Agent tool forks a child that sees the parent's\n * entire conversation history + a directive. This enables \"continue\n * this but focus on X\" delegation without starting from scratch.\n *\n * Key behaviors:\n * - Placeholder tool_results are byte-identical across all forks\n * (enables prompt cache sharing)\n * - Recursion guard via `<fork-boilerplate>` tag detection\n * - Fork children are instructed NOT to spawn sub-agents\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { ContentBlockParam, MessageParam } from '@anthropic-ai/sdk/resources/messages'\n\nconst FORK_BOILERPLATE_TAG = 'fork-boilerplate'\nconst FORK_PLACEHOLDER = 'Fork started — processing in background'\n\n/**\n * Detect whether the current message history contains a fork boilerplate\n * tag — prevents recursive forking (child can't re-fork).\n */\nexport function isInForkChild(messages: readonly MessageParam[]): boolean {\n return messages.some((m) => {\n if (m.role !== 'user') return false\n const content = m.content\n if (!Array.isArray(content)) return false\n return content.some(\n (b) =>\n typeof b === 'object' &&\n b !== null &&\n 'type' in b &&\n b.type === 'text' &&\n 'text' in b &&\n typeof b.text === 'string' &&\n b.text.includes(`<${FORK_BOILERPLATE_TAG}>`),\n )\n })\n}\n\n/**\n * Build the messages a forked child sees. The child gets:\n * 1. All of the parent's existing messages (passed separately)\n * 2. A cloned assistant message with tool_use blocks\n * 3. Placeholder tool_results + fork directive\n *\n * The placeholder text is identical across all forks so the LLM\n * provider can cache-share the prefix.\n */\nexport function buildForkedMessages(\n directive: string,\n assistantContent: readonly ContentBlockParam[],\n): MessageParam[] {\n // Clone the parent's last assistant message\n const clonedAssistant: MessageParam = {\n role: 'assistant',\n content: [...assistantContent],\n }\n\n // Build placeholder tool_results for each tool_use block\n const toolUseBlocks = assistantContent.filter(\n (b): b is ContentBlockParam & { type: 'tool_use'; id: string } => b.type === 'tool_use',\n )\n\n if (toolUseBlocks.length === 0) {\n // No tool_use blocks — just the directive\n return [\n {\n role: 'user',\n content: [{ type: 'text', text: buildForkDirective(directive) }],\n },\n ]\n }\n\n // Placeholder results (byte-identical for cache sharing)\n const placeholders: ContentBlockParam[] = toolUseBlocks.map((b) => ({\n type: 'tool_result' as const,\n tool_use_id: b.id,\n content: FORK_PLACEHOLDER,\n }))\n\n const directiveMessage: MessageParam = {\n role: 'user',\n content: [...placeholders, { type: 'text', text: buildForkDirective(directive) }],\n }\n\n return [clonedAssistant, directiveMessage]\n}\n\n/**\n * Build the fork directive with rules and output format.\n * Ported from La-Machina's buildChildMessage().\n */\nfunction buildForkDirective(directive: string): string {\n return `<${FORK_BOILERPLATE_TAG}>\nSTOP. READ THIS FIRST.\n\nYou are a forked worker process. You are NOT the main agent.\n\nRULES (non-negotiable):\n1. Do NOT spawn sub-agents; execute directly.\n2. Do NOT converse, ask questions, or suggest next steps.\n3. USE your tools directly: Bash, Read, Write, etc.\n4. If you modify files, commit your changes before reporting.\n5. Do NOT emit text between tool calls. Use tools silently, then report once at the end.\n6. Stay strictly within your directive's scope.\n7. Keep your report under 500 words. Be factual and concise.\n8. Your response MUST begin with \"Scope:\".\n\nOutput format:\n Scope: <your assigned scope in one sentence>\n Result: <key findings>\n Key files: <relevant file paths>\n Files changed: <list if modified>\n Issues: <list if any>\n</${FORK_BOILERPLATE_TAG}>\n\nDirective: ${directive}`\n}\n","/**\n * Bash tool — runs a shell command via `child_process.spawn` and\n * returns its output.\n *\n * Design:\n * - The command runs through `/bin/sh -c` so callers can pipe, redirect,\n * and use shell features. (We're a server-side automation engine, not\n * a sandboxed REPL — the caller is responsible for trusting commands.)\n * - stdout and stderr are merged into the result `content` for the agent\n * to read. exit code goes into `metadata.exitCode`.\n * - On non-zero exit, the result is `isError: true` with stderr included.\n * - Output is hard-capped at 512KB to bound the memory footprint of a\n * misbehaving command. Truncation is flagged in `metadata.truncated`.\n * - Cancellation is fully signal-driven: if the tool's AbortSignal fires\n * (timeout or external), the child process gets SIGTERM, then SIGKILL\n * after a short grace period.\n *\n * The bash tool does NOT need a storage adapter — it operates against the\n * real filesystem via the OS. Use a sandbox at the engine layer if you\n * need isolation.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\n// Lazy import — `node:child_process` is not available in Cloudflare Workers.\n// The engine gates Bash registration behind `canSpawnProcesses()`, but the\n// import itself would crash Workers at module load time without this pattern.\nlet _spawn: typeof import('node:child_process').spawn | null = null\n\nasync function getSpawn(): Promise<typeof import('node:child_process').spawn> {\n if (_spawn === null) {\n const cp = await import('node:child_process')\n _spawn = cp.spawn\n }\n return _spawn\n}\n\nconst MAX_OUTPUT_BYTES = 512 * 1024\nconst SIGKILL_GRACE_MS = 500\n\n/**\n * Device paths that could hang the process or produce infinite output.\n * Ported from La-Machina's pathValidation.ts BLOCKED_DEVICE_PATHS.\n */\nconst BLOCKED_DEVICE_PATHS =\n /\\b(\\/dev\\/zero|\\/dev\\/random|\\/dev\\/urandom|\\/proc\\/kcore|\\/dev\\/sda|\\/dev\\/mem)\\b/\n\nconst inputSchema = z.object({\n command: z.string().min(1),\n cwd: z.string().min(1).optional(),\n})\n\nexport function createBashTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Bash',\n description:\n 'Execute a shell command via /bin/sh -c. Returns combined stdout+stderr and the exit code.',\n inputSchema,\n requiresNode: true,\n execute: async ({ command, cwd }, ctx) => {\n // Block commands that read from dangerous device paths\n if (BLOCKED_DEVICE_PATHS.test(command)) {\n return {\n content:\n 'Blocked: command references a dangerous device path (/dev/zero, /dev/random, /proc/kcore, etc.)',\n isError: true,\n }\n }\n\n const spawn = await getSpawn()\n return new Promise<ToolResult>((resolve) => {\n const buffers: Buffer[] = []\n let totalBytes = 0\n let truncated = false\n\n const child = spawn('/bin/sh', ['-c', command], {\n stdio: ['ignore', 'pipe', 'pipe'],\n ...(cwd !== undefined ? { cwd } : {}),\n })\n\n const append = (chunk: Buffer): void => {\n if (truncated) return\n if (totalBytes + chunk.length > MAX_OUTPUT_BYTES) {\n const remaining = MAX_OUTPUT_BYTES - totalBytes\n if (remaining > 0) buffers.push(chunk.subarray(0, remaining))\n truncated = true\n totalBytes = MAX_OUTPUT_BYTES\n return\n }\n buffers.push(chunk)\n totalBytes += chunk.length\n }\n\n child.stdout.on('data', append)\n child.stderr.on('data', append)\n\n let resolved = false\n const finish = (result: ToolResult): void => {\n if (resolved) return\n resolved = true\n cleanup()\n // Best-effort: destroy lingering pipes so the process is fully\n // released even if stdio buffers are still draining.\n child.stdout?.destroy()\n child.stderr?.destroy()\n resolve(result)\n }\n\n child.on('error', (err) => {\n finish({\n content: `Failed to spawn command: ${err.message}`,\n isError: true,\n })\n })\n\n // Listen on 'exit' rather than 'close' because 'close' waits for\n // all stdio pipes to drain; on SIGKILL the pipes can stay open\n // indefinitely while the kernel reaps the process. 'exit' fires\n // as soon as the process status changes.\n child.on('exit', (code, signal) => {\n const output = Buffer.concat(buffers).toString('utf8')\n const exitCode = typeof code === 'number' ? code : -1\n const metadata: Record<string, unknown> = { exitCode, truncated }\n if (signal) metadata.signal = signal\n\n if (exitCode === 0) {\n finish({ content: output, metadata })\n } else {\n const reason = signal ? `killed by ${signal}` : `exit ${exitCode}`\n finish({\n content: output.length > 0 ? output : `Command failed (${reason})`,\n isError: true,\n metadata,\n })\n }\n })\n\n const onAbort = (): void => {\n child.kill('SIGTERM')\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL')\n }, SIGKILL_GRACE_MS)\n }\n ctx.signal.addEventListener('abort', onAbort, { once: true })\n if (ctx.signal.aborted) onAbort()\n\n function cleanup(): void {\n ctx.signal.removeEventListener('abort', onAbort)\n }\n })\n },\n })\n}\n","/**\n * SendMessage tool — inter-agent communication within a single run.\n *\n * Routes messages to agents tracked in the SubagentRegistry:\n *\n * - **Running agent**: Message is queued via `registry.queueMessage()`.\n * The child's agentLoop drains queued messages at the start of\n * each turn (injected as a user message).\n *\n * - **Stopped agent**: Returns an error — auto-resume is deferred to v0.5.\n *\n * - **Completed agent**: Returns an error — can't send to finished agents.\n *\n * Ported from La-Machina's SendMessageTool.ts (918 lines). The engine\n * version omits mailbox/UDS/bridge routing (CLI-only) and structured\n * messages (shutdown_request, plan_approval) — headless mode doesn't\n * need them.\n */\n\nimport { z } from 'zod'\nimport type { SubagentRegistry } from '../subagent/registry.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n to: z.string().min(1).describe('Agent name (subagent_type) or agentId to send the message to.'),\n message: z.string().min(1).describe('Message content to deliver to the target agent.'),\n})\n\nexport interface SendMessageToolOptions {\n readonly registry: SubagentRegistry\n}\n\nexport function createSendMessageTool(options: SendMessageToolOptions): Tool<typeof inputSchema> {\n return defineTool({\n name: 'SendMessage',\n description:\n 'Send a text message to a running subagent by name or agentId. ' +\n \"The message is queued and delivered at the start of the agent's next turn. \" +\n 'Use this to redirect, provide additional context, or coordinate with agents you spawned.',\n inputSchema,\n execute: async ({ to, message }): Promise<ToolResult> => {\n const { registry } = options\n\n // Resolve target — try name first, then direct agentId\n let agentId = registry.findByName(to)\n if (agentId === undefined) {\n // Try as direct agentId\n try {\n registry.getDepth(to) // throws if not found\n agentId = to\n } catch {\n return {\n content: `Agent \"${to}\" not found. Available agents: check your spawned agent names.`,\n isError: true,\n }\n }\n }\n\n const status = registry.getStatus(agentId)\n\n switch (status) {\n case 'running':\n registry.queueMessage(agentId, message)\n return {\n content: `Message queued for agent \"${to}\" (${agentId}). It will be delivered at the start of the agent's next turn.`,\n metadata: { agentId, status: 'queued' },\n }\n\n case 'stopped':\n return {\n content: `Agent \"${to}\" (${agentId}) is stopped. Cannot deliver message. Consider spawning a new agent.`,\n isError: true,\n }\n\n case 'completed':\n return {\n content: `Agent \"${to}\" (${agentId}) has already completed. Cannot deliver message.`,\n isError: true,\n }\n\n default:\n return {\n content: `Agent \"${to}\" has unknown status \"${status}\".`,\n isError: true,\n }\n }\n },\n })\n}\n","/**\n * FileEdit tool — read-modify-write replacement of a substring in a file.\n *\n * Default semantics enforce uniqueness: `old_string` must occur exactly\n * once. This catches the most common LLM mistake — accidentally replacing\n * one occurrence in a file that has many. Set `replace_all: true` to\n * replace every occurrence (e.g. for renaming a variable).\n *\n * The replacement is computed in memory and written back atomically via\n * the storage adapter.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n old_string: z.string().min(1),\n new_string: z.string(),\n replace_all: z.boolean().optional(),\n})\n\nexport function createFileEditTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Edit',\n description:\n 'Replace old_string with new_string in a file. By default old_string must be unique; set replace_all to replace every occurrence.',\n inputSchema,\n execute: async ({ path, old_string, new_string, replace_all }): Promise<ToolResult> => {\n if (old_string === new_string) {\n return {\n content: 'old_string and new_string are identical — no change to make',\n isError: true,\n }\n }\n\n let original: string | null\n try {\n original = await storage.readFile(path)\n } catch (err) {\n return {\n content: `Failed to read \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n if (original === null) {\n return { content: `File not found: ${path}`, isError: true }\n }\n\n // Try exact match first, then normalized quotes (smart → ASCII).\n // Ported from La-Machina's findActualString / preserveQuoteStyle.\n let matchString = old_string\n let occurrences = countOccurrences(original, matchString)\n if (occurrences === 0) {\n const normalized = normalizeQuotes(old_string)\n if (normalized !== old_string) {\n const normOcc = countOccurrences(original, normalized)\n if (normOcc > 0) {\n matchString = normalized\n occurrences = normOcc\n }\n }\n }\n if (occurrences === 0) {\n return { content: `old_string not found in ${path}`, isError: true }\n }\n if (occurrences > 1 && !replace_all) {\n return {\n content: `old_string is not unique in ${path}: ${occurrences} occurrences found. Add more context to make it unique, or set replace_all: true.`,\n isError: true,\n }\n }\n\n const replacements = replace_all ? occurrences : 1\n // If we're using a normalized match, replace the normalized version.\n const newStringNormalized =\n matchString !== old_string ? normalizeQuotes(new_string) : new_string\n const updated = replace_all\n ? splitJoin(original, matchString, newStringNormalized)\n : original.replace(matchString, newStringNormalized)\n\n try {\n await storage.writeFile(path, updated)\n } catch (err) {\n return {\n content: `Failed to write \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n return {\n content: `Edited ${path} (${replacements} replacement${replacements === 1 ? '' : 's'})`,\n metadata: { path, replacements },\n }\n },\n })\n}\n\nfunction countOccurrences(haystack: string, needle: string): number {\n if (needle.length === 0) return 0\n let count = 0\n let i = 0\n while ((i = haystack.indexOf(needle, i)) !== -1) {\n count++\n i += needle.length\n }\n return count\n}\n\nfunction splitJoin(haystack: string, needle: string, replacement: string): string {\n return haystack.split(needle).join(replacement)\n}\n\n/**\n * Normalize smart/curly quotes to ASCII equivalents.\n * Ported from La-Machina's preserveQuoteStyle.\n */\nfunction normalizeQuotes(s: string): string {\n return s\n .replace(/\\u201C/g, '\"') // \" → \"\n .replace(/\\u201D/g, '\"') // \" → \"\n .replace(/\\u2018/g, \"'\") // ' → '\n .replace(/\\u2019/g, \"'\") // ' → '\n}\n","/**\n * FileRead tool — read a file from the workspace storage adapter and\n * return its contents formatted with `cat -n` style line numbers.\n *\n * The line-numbered format is what Claude is trained to read in source\n * files: each line is prefixed with a 6-space-padded line number, a tab,\n * and the original line content. This format also makes line citations\n * (`file.ts:42`) trivial for the model to produce.\n *\n * Optional `offset` (1-based) and `limit` let the model paginate through\n * large files without exhausting context.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport type { FileTracker } from './fileTracker.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n offset: z.number().int().positive().optional(),\n limit: z.number().int().positive().optional(),\n /** PDF page range, e.g. \"1-5\", \"3\", \"10-20\". Max 20 pages per request. */\n pages: z.string().optional(),\n})\n\nconst IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg'])\nconst PDF_EXTENSION = '.pdf'\n\n/** Extract file extension without requiring node:path (Workers-safe). */\nfunction extname(filePath: string): string {\n const dot = filePath.lastIndexOf('.')\n if (dot === -1 || dot === filePath.length - 1) return ''\n const slash = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\\\'))\n if (dot < slash) return ''\n return filePath.slice(dot).toLowerCase()\n}\nconst MAX_PDF_PAGES = 20\nconst MAX_IMAGE_BYTES = 10 * 1024 * 1024 // 10MB\n\nexport interface FileReadToolOptions {\n readonly storage: StorageAdapter\n readonly tracker?: FileTracker | undefined\n}\n\nexport function createFileReadTool(\n storageOrOptions: StorageAdapter | FileReadToolOptions,\n): Tool<typeof inputSchema> {\n const opts: FileReadToolOptions =\n 'readFile' in storageOrOptions ? { storage: storageOrOptions } : storageOrOptions\n const { storage, tracker } = opts\n return defineTool({\n name: 'Read',\n description:\n 'Read a file from the workspace. Text files return cat -n style line numbers. PDF files extract text per page (use pages param). Image files return base64 for visual analysis.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ path, offset, limit, pages }): Promise<ToolResult> => {\n const ext = extname(path)\n\n // PDF handling — extract text per page.\n if (ext === PDF_EXTENSION) {\n return readPdf(storage, path, pages)\n }\n\n // Image handling — return base64 for vision.\n if (IMAGE_EXTENSIONS.has(ext)) {\n return readImage(storage, path, ext)\n }\n\n // Normal text file.\n let content: string | null\n try {\n content = await storage.readFile(path)\n } catch (err) {\n return {\n content: `Failed to read \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n if (content === null) {\n return { content: `File not found: ${path}`, isError: true }\n }\n\n const lines = content.split('\\n')\n const totalLines = lines.length\n const startLine = offset ?? 1\n if (startLine > totalLines) {\n return {\n content: `Offset ${startLine} is out of range; file has ${totalLines} lines`,\n isError: true,\n }\n }\n const endLine = limit ? Math.min(startLine + limit - 1, totalLines) : totalLines\n const slice = lines.slice(startLine - 1, endLine)\n tracker?.trackRead(path)\n\n const formatted = slice\n .map((line, idx) => {\n const lineNo = String(startLine + idx).padStart(6, ' ')\n return `${lineNo}\\t${line}`\n })\n .join('\\n')\n return { content: formatted }\n },\n })\n}\n\n// ---------- PDF reading ----------\n\nasync function readPdf(\n storage: StorageAdapter,\n filePath: string,\n pagesParam?: string,\n): Promise<ToolResult> {\n let pdfParse: (data: Buffer) => Promise<{ numpages: number; text: string }>\n try {\n // Dynamic import — pdf-parse is an optional dep. If not installed,\n // the tool returns a helpful error instead of crashing.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod = (await import('pdf-parse')) as any\n pdfParse = (mod.default ?? mod) as typeof pdfParse\n } catch {\n return {\n content: 'PDF reading requires the \"pdf-parse\" package. Install with: npm install pdf-parse',\n isError: true,\n }\n }\n\n let buffer: Buffer\n try {\n // Read through storage adapter (works on both local FS and R2/Workers)\n const content = await storage.readFile(filePath)\n if (content === null) {\n return { content: `PDF file not found: \"${filePath}\"`, isError: true }\n }\n buffer = Buffer.from(content, 'binary')\n } catch (err) {\n return {\n content: `Failed to read PDF \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n let parsed: { numpages: number; text: string }\n try {\n parsed = await pdfParse(buffer)\n } catch (err) {\n return {\n content: `Failed to parse PDF \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Page range filtering.\n const totalPages = parsed.numpages\n let startPage = 1\n let endPage = totalPages\n\n if (pagesParam) {\n const range = parsePageRange(pagesParam, totalPages)\n if (range.error) {\n return { content: range.error, isError: true }\n }\n startPage = range.start\n endPage = range.end\n }\n\n if (endPage - startPage + 1 > MAX_PDF_PAGES) {\n return {\n content: `Too many pages requested (${endPage - startPage + 1}). Maximum ${MAX_PDF_PAGES} pages per request. Use the \"pages\" parameter to specify a range.`,\n isError: true,\n }\n }\n\n // pdf-parse returns all text concatenated. For page-level output,\n // we note the total pages and return the full text (pdf-parse doesn't\n // expose per-page text without a custom renderer).\n const header = `PDF: ${filePath} (${totalPages} pages${pagesParam ? `, showing ${pagesParam}` : ''})\\n\\n`\n return {\n content: header + parsed.text,\n metadata: { pages: totalPages, format: 'pdf' },\n }\n}\n\nfunction parsePageRange(\n spec: string,\n total: number,\n):\n | { start: number; end: number; error?: undefined }\n | { start: number; end: number; error: string } {\n const parts = spec.split('-').map((s) => s.trim())\n if (parts.length === 1) {\n const page = parseInt(parts[0]!, 10)\n if (isNaN(page) || page < 1 || page > total) {\n return { start: 1, end: 1, error: `Invalid page \"${spec}\". File has ${total} pages.` }\n }\n return { start: page, end: page }\n }\n if (parts.length === 2) {\n const start = parseInt(parts[0]!, 10)\n const end = parseInt(parts[1]!, 10)\n if (isNaN(start) || isNaN(end) || start < 1 || end > total || start > end) {\n return { start: 1, end: 1, error: `Invalid page range \"${spec}\". File has ${total} pages.` }\n }\n return { start, end }\n }\n return { start: 1, end: 1, error: `Invalid page range format \"${spec}\". Use \"3\" or \"1-5\".` }\n}\n\n// ---------- Image reading ----------\n\nasync function readImage(\n storage: StorageAdapter,\n filePath: string,\n ext: string,\n): Promise<ToolResult> {\n let buffer: Buffer\n try {\n // Read through storage adapter (works on both local FS and R2/Workers)\n const content = await storage.readFile(filePath)\n if (content === null) {\n return { content: `Image file not found: \"${filePath}\"`, isError: true }\n }\n buffer = Buffer.from(content, 'binary')\n } catch (err) {\n return {\n content: `Failed to read image \"${filePath}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (buffer.length > MAX_IMAGE_BYTES) {\n return {\n content: `Image \"${filePath}\" is too large (${(buffer.length / 1024 / 1024).toFixed(1)}MB). Maximum ${MAX_IMAGE_BYTES / 1024 / 1024}MB.`,\n isError: true,\n }\n }\n\n const mimeMap: Record<string, string> = {\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.webp': 'image/webp',\n '.bmp': 'image/bmp',\n '.svg': 'image/svg+xml',\n }\n const mimeType = mimeMap[ext] ?? 'application/octet-stream'\n const base64 = buffer.toString('base64')\n\n return {\n content: `[Image: ${filePath} (${mimeType}, ${(buffer.length / 1024).toFixed(1)}KB)]\\n\\nBase64 data is included in the metadata for visual analysis.`,\n metadata: {\n format: 'image',\n mimeType,\n bytes: buffer.length,\n base64,\n },\n }\n}\n","/**\n * FileWrite tool — write a file via the storage adapter.\n *\n * Staleness check (ported from La-Machina): before writing, the tool\n * verifies the file was previously read OR is a new file. This prevents\n * blind overwrites of files the model hasn't seen, catching a common\n * class of bugs in multi-tool workflows.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport type { FileTracker } from './fileTracker.js'\n\nconst inputSchema = z.object({\n path: z.string().min(1),\n content: z.string(),\n})\n\nexport interface FileWriteToolOptions {\n readonly storage: StorageAdapter\n readonly tracker?: FileTracker | undefined\n}\n\nexport function createFileWriteTool(\n storageOrOptions: StorageAdapter | FileWriteToolOptions,\n): Tool<typeof inputSchema> {\n const opts: FileWriteToolOptions =\n 'readFile' in storageOrOptions ? { storage: storageOrOptions } : storageOrOptions\n const { storage, tracker } = opts\n\n return defineTool({\n name: 'Write',\n description: 'Write a file to the workspace. Creates parents and overwrites existing files.',\n inputSchema,\n execute: async ({ path, content }): Promise<ToolResult> => {\n // Staleness check: if the file exists and was never read, reject.\n if (tracker !== undefined) {\n const exists = await storage.exists(path)\n if (exists && !tracker.wasRead(path)) {\n return {\n content:\n `Cannot write \"${path}\": this file exists but you haven't read it yet. ` +\n `Use the Read tool first to see the current contents, then retry the write.`,\n isError: true,\n }\n }\n }\n\n try {\n await storage.writeFile(path, content)\n } catch (err) {\n return {\n content: `Failed to write \"${path}\": ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Track the write as a \"read\" so subsequent writes to the same\n // file within the same run don't trigger the staleness check.\n tracker?.trackRead(path)\n\n return {\n content: `Wrote ${content.length} bytes to ${path}`,\n metadata: { path, bytes: Buffer.byteLength(content, 'utf8') },\n }\n },\n })\n}\n","/**\n * Glob tool — find files in the workspace by glob pattern.\n *\n * Walks the storage adapter starting at `path` (defaults to root) and\n * returns every relative path that matches `pattern`. Pattern matching\n * is delegated to picomatch, which understands the standard glob\n * vocabulary: `*`, `**`, `?`, `[abc]`, `{a,b}`, dotfiles via the dot\n * option, etc.\n *\n * Results are sorted by mtime descending — recently-modified files\n * surface first, which is what the model usually wants when searching\n * for \"where did I just edit this\".\n */\n\nimport picomatch from 'picomatch'\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport { walkAdapter } from './walkAdapter.js'\n\nconst inputSchema = z.object({\n pattern: z.string().min(1),\n path: z.string().optional(),\n})\n\nconst MAX_RESULTS = 1000\n\nexport function createGlobTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Glob',\n description:\n 'Find files by glob pattern. Supports *, **, ?, [abc], {a,b}. Returns paths sorted by mtime descending.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ pattern, path: searchPath }): Promise<ToolResult> => {\n const startPath = searchPath ?? ''\n const matcher = picomatch(pattern, { dot: true })\n\n const matches: Array<{ path: string; mtime: Date }> = []\n try {\n for await (const filePath of walkAdapter(storage, startPath, {\n maxFiles: MAX_RESULTS * 5,\n })) {\n // The matcher operates on the path RELATIVE to the search path,\n // so a pattern like `*.ts` matches `a.ts` even when the file\n // lives at `src/a.ts` (caller can scope via `path`).\n const relative =\n startPath && filePath.startsWith(`${startPath}/`)\n ? filePath.slice(startPath.length + 1)\n : filePath\n if (!matcher(relative)) continue\n\n let mtime = new Date(0)\n try {\n const stat = await storage.stat(filePath)\n if (stat) mtime = stat.mtime\n } catch {\n // ignore stat failures, sort by epoch\n }\n matches.push({ path: relative, mtime })\n if (matches.length >= MAX_RESULTS) break\n }\n } catch (err) {\n return {\n content: `Glob failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (matches.length === 0) {\n return {\n content: `No matches for pattern \"${pattern}\" in ${startPath || '.'}`,\n metadata: { count: 0 },\n }\n }\n\n matches.sort((a, b) => b.mtime.getTime() - a.mtime.getTime())\n const lines = matches.map((m) => m.path).join('\\n')\n return {\n content: lines,\n metadata: { count: matches.length },\n }\n },\n })\n}\n","/**\n * walkAdapter — recursive walker over a `StorageAdapter` directory tree.\n *\n * Yields every file path (relative to the adapter root) reachable from\n * `startPath`. Used by the Glob and Grep tools, neither of which can\n * call `fs.readdir` directly because the adapter abstracts the backend.\n *\n * The walker uses `listDir` + `isDirectory` per entry. On R2 this is\n * cheap (everything is a single LIST/HEAD pair); on local fs this is\n * a few syscalls per directory. There are no symlink loops to worry\n * about because the adapter's path normalization rejects them.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface WalkOptions {\n /** Maximum directory depth to descend. Unbounded by default. */\n readonly maxDepth?: number\n /** Maximum number of files to yield. Unbounded by default. */\n readonly maxFiles?: number\n}\n\n/**\n * Walk a directory tree starting at `startPath` (relative to the\n * adapter root). Yields every file path encountered.\n */\nexport async function* walkAdapter(\n adapter: StorageAdapter,\n startPath: string,\n options: WalkOptions = {},\n): AsyncGenerator<string, void, void> {\n const maxDepth = options.maxDepth ?? Infinity\n const maxFiles = options.maxFiles ?? Infinity\n let yielded = 0\n\n // Stack-based DFS so we don't recurse — keeps the call stack flat\n // even on very deep trees.\n const stack: Array<{ path: string; depth: number }> = [{ path: startPath, depth: 0 }]\n\n while (stack.length > 0) {\n if (yielded >= maxFiles) return\n const current = stack.pop()\n if (!current) return\n\n let entries: string[]\n try {\n entries = await adapter.listDir(current.path)\n } catch {\n continue\n }\n\n // Sort for deterministic output across both backends.\n entries.sort()\n\n for (const name of entries) {\n const childPath = current.path === '' ? name : `${current.path}/${name}`\n const isDir = await adapter.isDirectory(childPath)\n if (isDir) {\n if (current.depth + 1 < maxDepth) {\n stack.push({ path: childPath, depth: current.depth + 1 })\n }\n } else {\n yield childPath\n yielded++\n if (yielded >= maxFiles) return\n }\n }\n }\n}\n","/**\n * Grep tool — regex search across files.\n *\n * Two implementations:\n * 1. **ripgrep (preferred):** Spawns `rg` binary on PATH for 10-100x\n * faster search. Supports context lines, multiline, type filters,\n * pagination. Ported from La-Machina's GrepTool.\n * 2. **JS fallback:** When `rg` is not on PATH, falls back to the\n * original in-process RegExp scanner. Slower but always works.\n *\n * The tool checks for `rg` availability once at construction time.\n */\n\nimport picomatch from 'picomatch'\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\nimport { walkAdapter } from './walkAdapter.js'\n\nconst inputSchema = z.object({\n pattern: z.string().min(1),\n path: z.string().optional(),\n glob: z.string().optional(),\n type: z.string().optional(),\n output_mode: z.enum(['content', 'files_with_matches', 'count']).optional(),\n '-i': z.boolean().optional(),\n '-n': z.boolean().optional(),\n '-A': z.number().int().nonnegative().optional(),\n '-B': z.number().int().nonnegative().optional(),\n '-C': z.number().int().nonnegative().optional(),\n context: z.number().int().nonnegative().optional(),\n multiline: z.boolean().optional(),\n head_limit: z.number().int().nonnegative().optional(),\n offset: z.number().int().nonnegative().optional(),\n})\n\nconst MAX_FILES_SCANNED = 5_000\nconst MAX_MATCHES_PER_FILE = 100\nconst DEFAULT_HEAD_LIMIT = 250\n\n// Lazy child_process import — not available in Cloudflare Workers.\nlet _cpModule: typeof import('node:child_process') | null | false = null\nlet _cpPromise: Promise<typeof import('node:child_process') | null> | null = null\n\nasync function getChildProcessAsync(): Promise<typeof import('node:child_process') | null> {\n if (_cpModule === false) return null\n if (_cpModule !== null) return _cpModule\n if (_cpPromise !== null) return _cpPromise\n _cpPromise = import('node:child_process')\n .then((m) => {\n _cpModule = m\n return m\n })\n .catch(() => {\n _cpModule = false\n return null\n })\n return _cpPromise\n}\n\nfunction getChildProcessSync(): typeof import('node:child_process') | null {\n if (_cpModule === false) return null\n if (_cpModule !== null) return _cpModule\n // If async hasn't resolved yet, can't use it synchronously\n return null\n}\n\nfunction hasRipgrep(): boolean {\n // Pre-load child_process at tool creation time (async, best-effort)\n getChildProcessAsync().catch(() => {})\n // For the sync check, try require (works in CJS bundles)\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n _cpModule = require('node:child_process') as typeof import('node:child_process')\n } catch {\n _cpModule = false\n return false\n }\n try {\n _cpModule.execSync('which rg', { stdio: 'ignore' })\n return true\n } catch {\n return false\n }\n}\n\nexport function createGrepTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n const rgAvailable = hasRipgrep()\n\n return defineTool({\n name: 'Grep',\n description:\n 'Search for a regex pattern across files. Supports ripgrep when available (context lines, multiline, type filters, pagination). Falls back to JS RegExp scanner.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async (input, ctx): Promise<ToolResult> => {\n if (rgAvailable && input.path !== undefined) {\n // Use ripgrep for filesystem searches with an explicit path.\n return runRipgrep(input, ctx)\n }\n // JS fallback for storage-adapter-based searches or when rg is missing.\n return runJsFallback(input, storage)\n },\n })\n}\n\n// ---------- ripgrep implementation ----------\n\nasync function runRipgrep(\n input: z.infer<typeof inputSchema>,\n ctx: { signal: AbortSignal },\n): Promise<ToolResult> {\n const args: string[] = []\n const outputMode = input.output_mode ?? 'files_with_matches'\n const headLimit = input.head_limit ?? DEFAULT_HEAD_LIMIT\n\n // Output mode flags\n if (outputMode === 'files_with_matches') args.push('-l')\n if (outputMode === 'count') args.push('-c')\n if (outputMode === 'content') {\n const showLineNumbers = input['-n'] !== false\n if (showLineNumbers) args.push('-n')\n }\n\n // Search options\n if (input['-i']) args.push('-i')\n if (input.multiline) args.push('-U', '--multiline-dotall')\n if (input.glob) args.push('--glob', input.glob)\n if (input.type) args.push('--type', input.type)\n\n // Context lines\n const contextLines = input['-C'] ?? input.context\n if (contextLines !== undefined) args.push('-C', String(contextLines))\n else {\n if (input['-A'] !== undefined) args.push('-A', String(input['-A']))\n if (input['-B'] !== undefined) args.push('-B', String(input['-B']))\n }\n\n // Cap per-file matches\n args.push('--max-count', String(MAX_MATCHES_PER_FILE))\n\n // Pattern and path\n args.push('--', input.pattern)\n if (input.path) args.push(input.path)\n\n const cp = getChildProcessSync() ?? (await getChildProcessAsync())\n if (cp === null) {\n return { content: 'ripgrep not available in this runtime', isError: true }\n }\n\n return new Promise<ToolResult>((resolve) => {\n const child = cp.spawn('rg', args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n timeout: 30_000,\n })\n\n let stdout = ''\n let stderr = ''\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString()\n // Early truncation if we've collected way more than we need.\n if (stdout.length > 1_000_000) {\n child.kill('SIGTERM')\n }\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString()\n })\n\n if (ctx.signal.aborted) {\n child.kill('SIGTERM')\n } else {\n ctx.signal.addEventListener('abort', () => child.kill('SIGTERM'), { once: true })\n }\n\n child.on('close', (code) => {\n if (code === 1 && stdout.length === 0) {\n // rg exit 1 = no matches (not an error).\n resolve({\n content: `No matches found`,\n metadata: { filesMatched: 0, engine: 'ripgrep' },\n })\n return\n }\n if (code !== 0 && code !== 1 && stderr.length > 0) {\n resolve({\n content: `Grep error: ${stderr.slice(0, 500)}`,\n isError: true,\n metadata: { engine: 'ripgrep', exitCode: code },\n })\n return\n }\n\n // Apply offset + head_limit pagination.\n let lines = stdout.split('\\n')\n if (input.offset) lines = lines.slice(input.offset)\n if (headLimit > 0) lines = lines.slice(0, headLimit)\n const output = lines.join('\\n').trim()\n\n resolve({\n content: output || 'No matches found',\n metadata: {\n engine: 'ripgrep',\n linesReturned: lines.length,\n },\n })\n })\n })\n}\n\n// ---------- JS fallback implementation ----------\n\nasync function runJsFallback(\n input: z.infer<typeof inputSchema>,\n storage: StorageAdapter,\n): Promise<ToolResult> {\n const flags = input['-i'] ? 'gi' : 'g'\n let regex: RegExp\n try {\n regex = new RegExp(input.pattern, flags + (input.multiline ? 's' : ''))\n } catch (err) {\n return {\n content: `Invalid regex: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const matcher = input.glob ? picomatch(input.glob, { dot: true }) : null\n const startPath = input.path ?? ''\n const outputMode = input.output_mode ?? 'content'\n const headLimit = input.head_limit ?? DEFAULT_HEAD_LIMIT\n\n const fileResults: Array<{ path: string; matches: Array<{ line: number; text: string }> }> = []\n let scanned = 0\n\n try {\n for await (const filePath of walkAdapter(storage, startPath, {\n maxFiles: MAX_FILES_SCANNED,\n })) {\n scanned++\n const relative =\n startPath && filePath.startsWith(`${startPath}/`)\n ? filePath.slice(startPath.length + 1)\n : filePath\n if (matcher && !matcher(relative)) continue\n\n let content: string | null\n try {\n content = await storage.readFile(filePath)\n } catch {\n continue\n }\n if (content === null) continue\n\n const lines = content.split('\\n')\n const matches: Array<{ line: number; text: string }> = []\n for (let i = 0; i < lines.length; i++) {\n if (matches.length >= MAX_MATCHES_PER_FILE) break\n const line = lines[i]!\n if (regex.test(line)) {\n matches.push({ line: i + 1, text: line })\n }\n // Reset lastIndex for global regex.\n regex.lastIndex = 0\n }\n if (matches.length > 0) {\n fileResults.push({ path: relative, matches })\n }\n }\n } catch (err) {\n return {\n content: `Grep failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (fileResults.length === 0) {\n return {\n content: `No matches for \"${input.pattern}\" (${scanned} files scanned)`,\n metadata: { filesScanned: scanned, filesMatched: 0, engine: 'js-fallback' },\n }\n }\n\n const formatted = formatJsResults(fileResults, outputMode, headLimit)\n return {\n content: formatted,\n metadata: {\n filesScanned: scanned,\n filesMatched: fileResults.length,\n totalMatches: fileResults.reduce((acc, f) => acc + f.matches.length, 0),\n engine: 'js-fallback',\n },\n }\n}\n\nfunction formatJsResults(\n results: ReadonlyArray<{ path: string; matches: ReadonlyArray<{ line: number; text: string }> }>,\n mode: 'content' | 'files_with_matches' | 'count',\n limit: number,\n): string {\n if (mode === 'files_with_matches') {\n return results\n .slice(0, limit)\n .map((r) => r.path)\n .join('\\n')\n }\n if (mode === 'count') {\n return results\n .slice(0, limit)\n .map((r) => `${r.path}:${r.matches.length}`)\n .join('\\n')\n }\n const lines: string[] = []\n for (const r of results) {\n for (const m of r.matches) {\n lines.push(`${r.path}:${m.line}:${m.text}`)\n if (lines.length >= limit) {\n lines.push(`... (truncated at ${limit} lines)`)\n return lines.join('\\n')\n }\n }\n }\n return lines.join('\\n')\n}\n","/**\n * WebFetch tool — fetch a URL and return its content as plain text.\n *\n * Design:\n * - Uses `fetch` (configurable for tests). Default is `globalThis.fetch`.\n * - Honors `ToolContext.signal` for cancellation; passes it straight\n * into `fetch({ signal })`.\n * - HTML responses get a basic tag-stripping pass: `<script>` and\n * `<style>` blocks are removed entirely, then all remaining tags are\n * stripped, then whitespace is collapsed. This is good enough for\n * feeding doc pages to the model. v0.2 may swap in a real Markdown\n * converter (turndown / html-to-md) if richer fidelity is needed.\n * - Output is hard-capped at 256 KB to bound memory.\n * - Non-2xx responses become `isError` results with the status code.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n url: z.string().url(),\n prompt: z.string().optional(),\n})\n\nconst MAX_OUTPUT_BYTES = 256 * 1024\n\nexport interface WebFetchToolOptions {\n /** Custom fetch implementation. Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. */\n readonly timeoutMs?: number\n}\n\nexport function createWebFetchTool(options: WebFetchToolOptions = {}): Tool<typeof inputSchema> {\n const fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n return defineTool({\n name: 'WebFetch',\n description:\n 'Fetch a URL and return its content as plain text. HTML is stripped to its readable text.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ url }, ctx): Promise<ToolResult> => {\n let response: Response\n try {\n // Use redirect: 'manual' to detect cross-host redirects.\n // Ported from La-Machina's WebFetchTool.\n response = await fetchImpl(url, { signal: ctx.signal, redirect: 'manual' })\n } catch (err) {\n return {\n content: `Failed to fetch ${url}: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n // Detect redirects — if the redirect goes to a different host,\n // report it instead of silently following (might be a login page).\n if (response.status >= 300 && response.status < 400) {\n const location = response.headers.get('location')\n if (location) {\n try {\n const originalHost = new URL(url).host\n const redirectHost = new URL(location, url).host\n if (originalHost !== redirectHost) {\n return {\n content:\n `URL redirected to a different host.\\n` +\n `Original: ${url}\\n` +\n `Redirect: ${location}\\n\\n` +\n `Make a new WebFetch request with the redirect URL if you want to follow it.`,\n metadata: { redirect: true, location, status: response.status },\n }\n }\n } catch {\n // URL parse failed — fall through to re-fetch with follow.\n }\n }\n // Same-host redirect or unparseable — re-fetch with follow.\n try {\n response = await fetchImpl(url, { signal: ctx.signal })\n } catch (err) {\n return {\n content: `Failed to fetch ${url} (after redirect): ${(err as Error).message}`,\n isError: true,\n }\n }\n }\n\n const contentType = response.headers.get('content-type') ?? 'application/octet-stream'\n\n if (!response.ok) {\n const body = await safeText(response)\n return {\n content: `HTTP ${response.status} from ${url}: ${body.slice(0, 500)}`,\n isError: true,\n metadata: { status: response.status, contentType },\n }\n }\n\n let raw: string\n try {\n raw = await response.text()\n } catch (err) {\n return {\n content: `Failed to read body from ${url}: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const text = isHtml(contentType) ? htmlToText(raw) : raw\n const { content, truncated } = truncate(text, MAX_OUTPUT_BYTES)\n\n return {\n content,\n metadata: {\n status: response.status,\n contentType,\n bytes: Buffer.byteLength(content, 'utf8'),\n truncated,\n },\n }\n },\n })\n}\n\nfunction isHtml(contentType: string): boolean {\n return contentType.toLowerCase().includes('html')\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n}\n\nfunction truncate(text: string, maxBytes: number): { content: string; truncated: boolean } {\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) {\n return { content: text, truncated: false }\n }\n // Truncate by character count as a rough proxy. UTF-8 may slightly\n // over- or under-shoot but never crosses a code point boundary.\n let lo = 0\n let hi = text.length\n while (lo < hi) {\n const mid = (lo + hi + 1) >>> 1\n if (Buffer.byteLength(text.slice(0, mid), 'utf8') <= maxBytes) {\n lo = mid\n } else {\n hi = mid - 1\n }\n }\n return { content: text.slice(0, lo) + '\\n... (truncated)', truncated: true }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text()\n } catch {\n return ''\n }\n}\n","/**\n * FileTracker — tracks which files have been read during a run.\n *\n * Shared between Read and Write tools within a single run. The Write\n * tool checks this before writing: if a file exists but was never read,\n * the write is rejected with isError so the model reads first.\n *\n * Ported from La-Machina's read-before-write invariant.\n */\n\nexport class FileTracker {\n private readonly readPaths = new Set<string>()\n\n /** Mark a file as read. Called by the Read tool after a successful read. */\n trackRead(path: string): void {\n this.readPaths.add(normalizePath(path))\n }\n\n /** Check if a file was previously read. */\n wasRead(path: string): boolean {\n return this.readPaths.has(normalizePath(path))\n }\n}\n\nfunction normalizePath(p: string): string {\n // Normalize trailing slashes and consecutive slashes.\n return p.replace(/\\/+/g, '/').replace(/\\/$/, '')\n}\n","/**\n * WebSearch — search the web and return results.\n *\n * Strategy: uses WebFetch to query a search-engine-friendly URL and\n * extract results. When a proper search API is configured in the\n * future, this tool can be swapped without changing the tool contract.\n *\n * Current implementation: fetches a DuckDuckGo lite HTML page, strips\n * tags, and returns the text. The model interprets the search results\n * from the raw text content.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(2),\n max_results: z.number().int().positive().optional(),\n})\n\nexport function createWebSearchTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'WebSearch',\n description:\n 'Search the web for information. Returns search result snippets. Use when you need current information not available in local files.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query }): Promise<ToolResult> => {\n const encoded = encodeURIComponent(query)\n const url = `https://lite.duckduckgo.com/lite/?q=${encoded}`\n\n let response: Response\n try {\n response = await fetch(url, {\n headers: {\n 'User-Agent': 'la-machina-engine/0.2.0',\n Accept: 'text/html',\n },\n })\n } catch (err) {\n return {\n content: `Web search failed: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n if (!response.ok) {\n return {\n content: `Web search returned HTTP ${response.status}`,\n isError: true,\n }\n }\n\n let html: string\n try {\n html = await response.text()\n } catch (err) {\n return {\n content: `Failed to read search response: ${(err as Error).message}`,\n isError: true,\n }\n }\n\n const text = htmlToText(html)\n const trimmed = text.slice(0, 8000) // cap output\n\n return {\n content: `Search results for \"${query}\":\\n\\n${trimmed}`,\n metadata: { query, bytes: trimmed.length },\n }\n },\n })\n}\n\nfunction htmlToText(html: string): string {\n return html\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/[ \\t]+/g, ' ')\n .replace(/\\n[ \\t]+/g, '\\n')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n}\n","/**\n * Sleep tool — pauses execution for a given number of milliseconds.\n * Honors the ToolContext's AbortSignal for early cancellation.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n durationMs: z.number().int().nonnegative().max(300_000),\n reason: z.string().optional(),\n})\n\nexport function createSleepTool(): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Sleep',\n description:\n 'Pause execution for the given number of milliseconds (max 300000 = 5 minutes). Use when you need to wait for an external process or rate limit.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ durationMs, reason }, ctx): Promise<ToolResult> => {\n if (durationMs === 0) {\n return { content: 'Slept for 0ms (no-op).' }\n }\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, durationMs)\n if (typeof timer.unref === 'function') timer.unref()\n if (ctx.signal.aborted) {\n clearTimeout(timer)\n resolve()\n } else {\n ctx.signal.addEventListener(\n 'abort',\n () => {\n clearTimeout(timer)\n resolve()\n },\n { once: true },\n )\n }\n })\n const cancelled = ctx.signal.aborted\n return {\n content: cancelled\n ? `Sleep cancelled after partial wait (requested ${durationMs}ms).`\n : `Slept for ${durationMs}ms.${reason ? ` Reason: ${reason}` : ''}`,\n metadata: { durationMs, cancelled },\n }\n },\n })\n}\n","/**\n * ToolSearch — search registered tools by keyword.\n * Ported from La-Machina's deferred-tool search logic.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolRegistry, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n max_results: z.number().int().positive().optional(),\n})\n\nexport function createToolSearchTool(registry: ToolRegistry): Tool<typeof inputSchema> {\n return defineTool({\n name: 'ToolSearch',\n description:\n 'Search the available tools by keyword. Returns matching tool names and descriptions. Use when you want to discover what tools are available for a task.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query, max_results }): Promise<ToolResult> => {\n const limit = max_results ?? 10\n const q = query.toLowerCase()\n const all = registry.list()\n\n const scored = all\n .map((tool) => {\n let score = 0\n const nameLower = tool.name.toLowerCase()\n const descLower = tool.description.toLowerCase()\n\n if (nameLower === q) score += 100\n if (nameLower.includes(q)) score += 50\n if (descLower.includes(q)) score += 20\n\n // Score individual query words.\n for (const word of q.split(/\\s+/)) {\n if (nameLower.includes(word)) score += 10\n if (descLower.includes(word)) score += 5\n }\n\n return { tool, score }\n })\n .filter(({ score }) => score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit)\n\n if (scored.length === 0) {\n return {\n content: `No tools found matching \"${query}\". ${all.length} tools are registered.`,\n metadata: { totalTools: all.length, matches: 0 },\n }\n }\n\n const lines = scored.map(({ tool }) => `- **${tool.name}**: ${tool.description}`)\n return {\n content: `Found ${scored.length} tool(s) matching \"${query}\":\\n${lines.join('\\n')}`,\n metadata: { totalTools: all.length, matches: scored.length },\n }\n },\n })\n}\n","/**\n * Memorize tool — lets the model explicitly save facts to smart memory.\n * Wires to the existing SmartMemory façade (Hippocampus backend).\n */\n\nimport { z } from 'zod'\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n text: z.string().min(1),\n kind: z.enum(['rule', 'lesson']).default('lesson'),\n topic: z.string().optional(),\n})\n\nexport function createMemorizeTool(memory: SmartMemory): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Memorize',\n description:\n 'Save a fact, rule, or lesson to persistent memory. Memories survive across runs and are included in the system prompt of future runs. Use \"rule\" for behavioral constraints (always/never do X). Use \"lesson\" for learnings and observations.',\n inputSchema,\n execute: async ({ text, kind, topic }): Promise<ToolResult> => {\n if (memory.mode === 'off' || memory.mode === 'read-only') {\n return {\n content: `Cannot memorize: memory mode is \"${memory.mode}\". Set config.memory.mode to \"read-write\" to enable.`,\n isError: true,\n }\n }\n\n if (kind === 'rule') {\n await memory.encodeRule(text, 'always')\n return {\n content: `Memorized rule: \"${text.slice(0, 80)}${text.length > 80 ? '…' : ''}\"`,\n metadata: { kind: 'rule' },\n }\n }\n\n await memory.encodeLesson(text, topic)\n return {\n content: `Memorized lesson: \"${text.slice(0, 80)}${text.length > 80 ? '…' : ''}\"${topic ? ` (topic: ${topic})` : ''}`,\n metadata: { kind: 'lesson', topic },\n }\n },\n })\n}\n","/**\n * Recall tool — search persistent memory for previously saved facts.\n * Wires to SmartMemory (Hippocampus recall) + EpisodicMemory search.\n */\n\nimport { z } from 'zod'\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n scope: z.enum(['identity', 'rules', 'lessons', 'all']).default('all'),\n topic: z.string().optional(),\n})\n\nexport function createRecallTool(memory: SmartMemory): Tool<typeof inputSchema> {\n return defineTool({\n name: 'Recall',\n description:\n 'Search persistent memory for previously saved facts, rules, and lessons. Use when you need to recall information from prior runs or check what rules/lessons are stored.',\n inputSchema,\n isConcurrencySafe: () => true,\n execute: async ({ query, scope, topic }): Promise<ToolResult> => {\n if (memory.mode === 'off') {\n return {\n content: 'Cannot recall: memory mode is \"off\".',\n isError: true,\n }\n }\n\n const parts: string[] = []\n\n if (scope === 'identity' || scope === 'all') {\n const identity = await memory.recallIdentity()\n if (identity.length > 0) parts.push(`## Identity\\n${identity}`)\n }\n\n if (scope === 'rules' || scope === 'all') {\n const rules = await memory.recallRules()\n if (rules.length > 0) parts.push(`## Rules\\n${rules}`)\n }\n\n if (scope === 'lessons' || scope === 'all') {\n const lessons = await memory.recallLessons()\n if (lessons.length > 0) parts.push(`## Lessons\\n${lessons}`)\n }\n\n if (topic !== undefined) {\n const topicContent = await memory.recallTopic(topic)\n if (topicContent.length > 0) parts.push(`## Topic: ${topic}\\n${topicContent}`)\n }\n\n if (parts.length === 0) {\n return {\n content: `No memories found${scope !== 'all' ? ` in scope \"${scope}\"` : ''}.`,\n metadata: { found: false },\n }\n }\n\n // Simple relevance filter: if the query mentions specific words,\n // highlight lines that contain them.\n const content = parts.join('\\n\\n')\n return {\n content: `Memory recall for \"${query}\":\\n\\n${content}`,\n metadata: { found: true, scope, charCount: content.length },\n }\n },\n })\n}\n","/**\n * NotebookEdit — edit Jupyter .ipynb notebook cells.\n * Supports insert, replace, and delete operations on cells by index.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool, type ToolResult } from './contract.js'\n\nconst inputSchema = z.object({\n notebook_path: z.string().min(1),\n edit_mode: z.enum(['replace', 'insert', 'delete']).default('replace'),\n cell_index: z.number().int().nonnegative(),\n new_source: z.string().optional(),\n cell_type: z.enum(['code', 'markdown']).optional(),\n})\n\ninterface NotebookCell {\n cell_type: string\n source: string[]\n metadata: Record<string, unknown>\n outputs?: unknown[]\n execution_count?: number | null\n}\n\ninterface Notebook {\n nbformat: number\n nbformat_minor: number\n metadata: Record<string, unknown>\n cells: NotebookCell[]\n}\n\nexport function createNotebookEditTool(storage: StorageAdapter): Tool<typeof inputSchema> {\n return defineTool({\n name: 'NotebookEdit',\n description:\n 'Edit a Jupyter notebook (.ipynb) by inserting, replacing, or deleting cells. Specify the cell_index (0-based) and the operation.',\n inputSchema,\n execute: async ({\n notebook_path,\n edit_mode,\n cell_index,\n new_source,\n cell_type,\n }): Promise<ToolResult> => {\n const raw = await storage.readFile(notebook_path)\n if (raw === null) {\n return {\n content: `Notebook not found: ${notebook_path}`,\n isError: true,\n }\n }\n\n let notebook: Notebook\n try {\n notebook = JSON.parse(raw) as Notebook\n } catch {\n return {\n content: `Failed to parse notebook JSON: ${notebook_path}`,\n isError: true,\n }\n }\n\n if (!Array.isArray(notebook.cells)) {\n return {\n content: `Invalid notebook format: missing cells array`,\n isError: true,\n }\n }\n\n const cellCount = notebook.cells.length\n\n if (edit_mode === 'delete') {\n if (cell_index >= cellCount) {\n return {\n content: `Cell index ${cell_index} out of range (notebook has ${cellCount} cells).`,\n isError: true,\n }\n }\n notebook.cells.splice(cell_index, 1)\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Deleted cell at index ${cell_index}. Notebook now has ${notebook.cells.length} cells.`,\n metadata: { operation: 'delete', cell_index, cellCount: notebook.cells.length },\n }\n }\n\n if (new_source === undefined) {\n return {\n content: `new_source is required for ${edit_mode} operations.`,\n isError: true,\n }\n }\n\n const sourceLines = new_source\n .split('\\n')\n .map((line, i, arr) => (i < arr.length - 1 ? line + '\\n' : line))\n\n const newCell: NotebookCell = {\n cell_type: cell_type ?? 'code',\n source: sourceLines,\n metadata: {},\n ...(cell_type !== 'markdown' ? { outputs: [], execution_count: null } : {}),\n }\n\n if (edit_mode === 'insert') {\n const insertAt = Math.min(cell_index, cellCount)\n notebook.cells.splice(insertAt, 0, newCell)\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Inserted ${newCell.cell_type} cell at index ${insertAt}. Notebook now has ${notebook.cells.length} cells.`,\n metadata: { operation: 'insert', cell_index: insertAt, cellCount: notebook.cells.length },\n }\n }\n\n // replace\n if (cell_index >= cellCount) {\n return {\n content: `Cell index ${cell_index} out of range (notebook has ${cellCount} cells).`,\n isError: true,\n }\n }\n notebook.cells[cell_index] = newCell\n await storage.writeFile(notebook_path, JSON.stringify(notebook, null, 1))\n return {\n content: `Replaced cell at index ${cell_index} with ${newCell.cell_type} cell.`,\n metadata: { operation: 'replace', cell_index, cellCount: notebook.cells.length },\n }\n },\n })\n}\n","/**\n * TaskStore — in-memory task collection scoped to a single engine run.\n *\n * Tasks are identified by auto-incrementing string IDs (\"1\", \"2\", ...).\n * The store is passed to the task tools at registry construction time\n * and shared across all tool invocations within the same `engine.run()`.\n *\n * Optionally persists to the workspace storage adapter as a JSON file\n * so tasks survive across pause/resume cycles.\n */\n\nimport type { StorageAdapter } from '../../storage/interface.js'\nimport type { Task, TaskStatus } from './types.js'\n\nconst TASKS_FILE = 'tasks.json'\n\nexport class TaskStore {\n private tasks: Map<string, Task> = new Map()\n private nextId = 1\n private readonly storage: StorageAdapter | undefined\n private readonly logPath: string\n\n constructor(options: { storage?: StorageAdapter; logPath: string }) {\n this.storage = options.storage\n this.logPath = options.logPath\n }\n\n create(subject: string, description: string, metadata?: Record<string, unknown>): Task {\n const id = String(this.nextId++)\n const now = new Date().toISOString()\n const task: Task = {\n id,\n subject,\n description,\n status: 'pending',\n createdAt: now,\n updatedAt: now,\n metadata: metadata ?? {},\n }\n this.tasks.set(id, task)\n void this.persist()\n return task\n }\n\n get(id: string): Task | undefined {\n return this.tasks.get(id)\n }\n\n list(filter?: { status?: TaskStatus }): Task[] {\n const out: Task[] = []\n for (const task of this.tasks.values()) {\n if (task.status === 'deleted') continue\n if (filter?.status !== undefined && task.status !== filter.status) continue\n out.push(task)\n }\n return out\n }\n\n update(\n id: string,\n fields: {\n subject?: string | undefined\n status?: TaskStatus | undefined\n description?: string | undefined\n metadata?: Record<string, unknown> | undefined\n },\n ): Task | undefined {\n const task = this.tasks.get(id)\n if (!task) return undefined\n\n if (fields.subject !== undefined) (task as { subject: string }).subject = fields.subject\n if (fields.status !== undefined) task.status = fields.status\n if (fields.description !== undefined)\n (task as { description: string }).description = fields.description\n if (fields.metadata !== undefined) {\n Object.assign(task.metadata, fields.metadata)\n }\n task.updatedAt = new Date().toISOString()\n void this.persist()\n return task\n }\n\n private async persist(): Promise<void> {\n if (!this.storage) return\n const data = JSON.stringify(Array.from(this.tasks.values()), null, 2)\n try {\n await this.storage.writeFile(`${this.logPath}/${TASKS_FILE}`, data)\n } catch {\n // Best-effort persistence — don't crash the run.\n }\n }\n}\n","/**\n * Task tools — TaskCreate, TaskGet, TaskList, TaskUpdate.\n * All four close over the same TaskStore instance.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from '../contract.js'\nimport type { TaskStore } from './store.js'\n\nconst TaskStatusEnum = z.enum(['pending', 'in_progress', 'completed', 'deleted'])\n\n// ---------- TaskCreate ----------\n\nconst createSchema = z.object({\n subject: z.string().min(1),\n description: z.string().default(''),\n metadata: z.record(z.unknown()).optional(),\n})\n\nexport function createTaskCreateTool(store: TaskStore): Tool<typeof createSchema> {\n return defineTool({\n name: 'TaskCreate',\n description:\n 'Create a new task. Use to break work into trackable steps. Returns the created task with its ID.',\n inputSchema: createSchema,\n execute: async ({ subject, description, metadata }) => {\n const task = store.create(subject, description, metadata)\n return {\n content: `Created task #${task.id}: \"${task.subject}\" (status: ${task.status})`,\n metadata: { task },\n }\n },\n })\n}\n\n// ---------- TaskGet ----------\n\nconst getSchema = z.object({\n taskId: z.string().min(1),\n})\n\nexport function createTaskGetTool(store: TaskStore): Tool<typeof getSchema> {\n return defineTool({\n name: 'TaskGet',\n description:\n 'Get a task by its ID. Returns the full task object including status and metadata.',\n inputSchema: getSchema,\n isConcurrencySafe: () => true,\n execute: async ({ taskId }) => {\n const task = store.get(taskId)\n if (!task) {\n return { content: `Task #${taskId} not found.`, isError: true }\n }\n return {\n content: `Task #${task.id}: \"${task.subject}\" — status: ${task.status}\\n${task.description}`,\n metadata: { task },\n }\n },\n })\n}\n\n// ---------- TaskList ----------\n\nconst listSchema = z.object({\n status: TaskStatusEnum.optional(),\n})\n\nexport function createTaskListTool(store: TaskStore): Tool<typeof listSchema> {\n return defineTool({\n name: 'TaskList',\n description:\n 'List all tasks. Optionally filter by status (pending, in_progress, completed). Deleted tasks are excluded.',\n inputSchema: listSchema,\n isConcurrencySafe: () => true,\n execute: async ({ status }) => {\n const tasks = store.list(status !== undefined ? { status } : undefined)\n if (tasks.length === 0) {\n return {\n content: status ? `No tasks with status \"${status}\".` : 'No tasks created yet.',\n metadata: { count: 0 },\n }\n }\n const lines = tasks.map((t) => `- #${t.id} [${t.status}] ${t.subject}`)\n return {\n content: `${tasks.length} task(s):\\n${lines.join('\\n')}`,\n metadata: { count: tasks.length, tasks },\n }\n },\n })\n}\n\n// ---------- TaskUpdate ----------\n\nconst updateSchema = z.object({\n taskId: z.string().min(1),\n subject: z.string().min(1).optional(),\n status: TaskStatusEnum.optional(),\n description: z.string().optional(),\n metadata: z.record(z.unknown()).optional(),\n})\n\nexport function createTaskUpdateTool(store: TaskStore): Tool<typeof updateSchema> {\n return defineTool({\n name: 'TaskUpdate',\n description:\n 'Update a task\\'s status, subject, description, or metadata. Set status to \"in_progress\" when starting, \"completed\" when done.',\n inputSchema: updateSchema,\n execute: async ({ taskId, subject, status, description, metadata }) => {\n const task = store.update(taskId, {\n subject,\n status,\n description,\n metadata: metadata,\n })\n if (!task) {\n return { content: `Task #${taskId} not found.`, isError: true }\n }\n return {\n content: `Updated task #${task.id}: \"${task.subject}\" — status: ${task.status}`,\n metadata: { task },\n }\n },\n })\n}\n","/**\n * Logger — structured log emission gated by `config.logging.level` and\n * routed to `config.logging.sink`.\n *\n * Levels (ascending verbosity):\n *\n * silent < error < warn < info < debug\n *\n * `silent` suppresses everything (no-op Logger). Any other level passes\n * records at that rank OR ANY RANK ABOVE IT through to the sink.\n *\n * Sinks:\n * - `'stderr'` — `console.error(JSON.stringify(entry))` per record.\n * Structured output that's cheap to grep/pipe through `jq`.\n * - `'none'` — true no-op. Use when embedding the engine inside a\n * host that has its own observability stack and doesn't want the\n * engine yelling into stderr.\n * - `(entry) => void` — callable sink. The engine hands the full\n * `LogEntry` to the caller on every emission. Use this to route into\n * OpenTelemetry, Pino, Winston, Sentry, a worker queue, etc.\n *\n * The returned logger is intentionally small: `{ error, warn, info, debug }`.\n * Each method takes a short message and an optional structured `meta`\n * object. The engine calls these at known checkpoints (run start/end,\n * turn boundaries, tool dispatch, pauses, failures) — see engine.ts for\n * the full emission schedule.\n */\n\nimport type { LogEntry, LogLevel, LogSink, ResolvedLoggingConfig } from '../config/types.js'\n\n/** Numeric rank for level comparisons. Higher = more verbose. */\nconst LEVEL_RANK: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n}\n\nexport interface Logger {\n error(msg: string, meta?: Record<string, unknown>): void\n warn(msg: string, meta?: Record<string, unknown>): void\n info(msg: string, meta?: Record<string, unknown>): void\n debug(msg: string, meta?: Record<string, unknown>): void\n}\n\nconst NOOP_LOGGER: Logger = {\n error: () => {},\n warn: () => {},\n info: () => {},\n debug: () => {},\n}\n\n/**\n * Build a Logger from a resolved logging config.\n *\n * Silent-level shortcuts to a true no-op so hot paths don't even\n * allocate the meta object. Non-silent loggers filter per-call against\n * the level rank before dispatching to the sink.\n */\nexport function createLogger(config: ResolvedLoggingConfig): Logger {\n if (config.level === 'silent') return NOOP_LOGGER\n\n const threshold = LEVEL_RANK[config.level]\n const dispatch = buildDispatcher(config.sink)\n\n const emit = (level: LogLevel, msg: string, meta?: Record<string, unknown>): void => {\n if (LEVEL_RANK[level] > threshold) return\n const entry: LogEntry = {\n level,\n msg,\n ts: new Date().toISOString(),\n ...(meta !== undefined ? { meta } : {}),\n }\n dispatch(entry)\n }\n\n return {\n error: (msg, meta) => emit('error', msg, meta),\n warn: (msg, meta) => emit('warn', msg, meta),\n info: (msg, meta) => emit('info', msg, meta),\n debug: (msg, meta) => emit('debug', msg, meta),\n }\n}\n\nfunction buildDispatcher(sink: LogSink): (entry: LogEntry) => void {\n if (sink === 'none') return () => {}\n if (sink === 'stderr') {\n return (entry) => {\n // Structured single-line JSON — easy to pipe through `jq`.\n console.error(JSON.stringify(entry))\n }\n }\n // Callable sink — user-supplied. Wrap in try so a throwing sink can't\n // tear down the engine mid-run.\n return (entry) => {\n try {\n sink(entry)\n } catch {\n // Swallow — logger failures must not abort the run.\n }\n }\n}\n","/**\n * Agents loader — discovers custom subagent definitions under a directory.\n *\n * Format (intentionally minimal, no YAML dependency):\n *\n * {customPath}/\n * ├── researcher.md\n * └── reviewer.md\n *\n * Each `.md` file defines one agent:\n *\n * # researcher\n *\n * One-line description. This is what the parent model sees in the Agent\n * tool's description catalogue.\n *\n * ---\n *\n * You are a research subagent. You have access to the web and filesystem...\n *\n * Parsing rules:\n *\n * - The **filename** (sans `.md`) is the agent's `name`. It must match\n * `^[a-zA-Z0-9_-]+$` or the file is skipped.\n * - The **first non-empty line** (after stripping leading `# `) is the\n * agent's `description`. One liner.\n * - The **rest of the file after the `---` separator** is the agent's\n * `systemPrompt`. If no `---` separator exists, the entire body after\n * the description is the system prompt. If there is no body at all,\n * `systemPrompt` is undefined and the agent inherits the parent's prompt.\n */\n\nimport type { AgentDefinition } from '../tools/agent.js'\nimport type { StorageAdapter } from '../storage/interface.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\n/**\n * Walk `baseDir` under the given storage adapter and return one\n * `AgentDefinition` per valid `.md` file. Returns an empty array when\n * the directory is missing or empty.\n */\nexport async function loadAgents(\n storage: StorageAdapter,\n baseDir: string,\n): Promise<AgentDefinition[]> {\n const entries = await storage.listDir(baseDir)\n if (entries.length === 0) return []\n\n const out: AgentDefinition[] = []\n for (const entry of entries.slice().sort()) {\n if (!entry.endsWith('.md')) continue\n const name = entry.replace(/\\.md$/, '')\n if (!SAFE_NAME.test(name)) continue\n\n const content = await storage.readFile(`${baseDir}/${entry}`)\n if (content === null) continue\n\n const parsed = parseAgentFile(content, name)\n out.push(parsed)\n }\n\n return out\n}\n\nfunction parseAgentFile(content: string, name: string): AgentDefinition {\n const lines = content.split('\\n')\n let description = ''\n let bodyStart = 0\n let inHeading = false\n\n // Find the first non-empty line, strip `# ` if present, use as description.\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!.trim()\n if (line.length === 0) continue\n if (line.startsWith('#')) {\n inHeading = true\n // If there's text after `#`, keep looking — the heading itself is\n // usually the agent name (which we already have from the filename),\n // not the description.\n continue\n }\n description = line\n bodyStart = i + 1\n break\n }\n\n if (description === '' && inHeading) {\n // Only a heading, no body — use the agent name as the description.\n return { name, description: name }\n }\n\n // Look for a `---` separator between the description and the system prompt.\n // If not found, the remainder of the file is the system prompt.\n let promptStart = bodyStart\n for (let i = bodyStart; i < lines.length; i++) {\n if (lines[i]!.trim() === '---') {\n promptStart = i + 1\n break\n }\n }\n\n const systemPrompt = lines.slice(promptStart).join('\\n').trim()\n if (systemPrompt.length === 0) {\n return { name, description }\n }\n return { name, description, systemPrompt }\n}\n","/**\n * Coordinator mode — resolves config, builds the worker agent definition,\n * and determines the effective system prompt and tool restrictions.\n */\n\nimport type { ResolvedConfig } from '../config/types.js'\nimport type { AgentDefinition } from '../tools/agent.js'\nimport { getCoordinatorSystemPrompt } from './prompt.js'\nimport type { ResolvedCoordinatorConfig } from './types.js'\n\n/**\n * Check whether the engine is running in coordinator mode.\n */\nexport function isCoordinatorMode(config: ResolvedConfig): boolean {\n return config.coordinator.enabled\n}\n\n/**\n * Build the worker agent definition. Workers get a restricted tool set\n * and a simple system prompt. The coordinator dispatches to them via\n * `Agent({ subagent_type: 'worker', ... })`.\n */\nexport function buildWorkerAgent(config: ResolvedCoordinatorConfig): AgentDefinition {\n return {\n name: 'worker',\n description:\n 'A focused worker agent with restricted tool access. Executes research, implementation, or verification tasks as directed by the coordinator. Cannot spawn sub-agents.',\n systemPrompt: buildWorkerSystemPrompt(config),\n }\n}\n\nfunction buildWorkerSystemPrompt(config: ResolvedCoordinatorConfig): string {\n const tools = config.workerTools.join(', ')\n return `You are a worker agent inside la-machina-engine. You execute focused tasks as directed.\n\nYour available tools: ${tools}\n\nRules:\n- Execute the task given to you completely and accurately.\n- Report your findings, changes, and results clearly.\n- If you encounter an error, report it with the full error message, file path, and line number.\n- Do not ask questions — work with what you have. If information is missing, note what's missing in your report.\n- For implementation tasks: run tests and typecheck before reporting done. Commit your changes.\n- For research tasks: do not modify files. Report findings only.\n- For verification tasks: prove the code works — don't just confirm it exists. Try edge cases.\n- Be thorough but concise. Include file paths and line numbers in your reports.`\n}\n\n/**\n * Get the coordinator's system prompt override. Used by the engine's\n * prompt builder when coordinator mode is active.\n */\nexport function getCoordinatorBasePrompt(): string {\n return getCoordinatorSystemPrompt()\n}\n","/**\n * Coordinator system prompt — ported from La-Machina's coordinatorMode.ts.\n *\n * 370+ lines of behavioral instructions that transform the agent from\n * an implementer into an orchestrator. The prompt enforces:\n * - Research → Synthesis → Implementation → Verification phases\n * - Anti-lazy-delegation (must synthesize before directing workers)\n * - Parallel reads, serial writes\n * - Worker prompt quality standards\n *\n * Adapted for headless: no slash commands, no terminal UI, no interactive\n * approval dialogs. Tool names are parameterized.\n */\n\nexport function getCoordinatorSystemPrompt(): string {\n return `You are an AI assistant running inside la-machina-engine in **coordinator mode**. You orchestrate tasks across multiple workers.\n\n## 1. Your Role\n\nYou are a **coordinator**. Your job is to:\n- Help the caller achieve their goal\n- Direct workers to research, implement and verify code changes\n- Synthesize results and report back\n- Answer questions directly when possible — don't delegate work that you can handle without tools\n\nEvery message you produce goes to the caller. Worker results and system notifications are internal signals — never thank or acknowledge them. Summarize new information as it arrives.\n\n## 2. Your Tools\n\n- **Agent** — Spawn a new worker (use subagent_type: \"worker\")\n- **TaskCreate/TaskUpdate** — Track progress across phases\n\nWhen calling Agent:\n- Do not use one worker to check on another. Workers notify you when done.\n- Do not use workers to trivially report file contents. Give them higher-level tasks.\n- After launching agents, briefly state what you launched and end your response. Never fabricate or predict agent results — results arrive as separate messages.\n\n## 3. Workers\n\nWhen calling Agent, use subagent_type \"worker\". Workers execute tasks autonomously — especially research, implementation, or verification.\n\nWorkers have access to: Bash, Read, Write, Edit, Glob, Grep. They do NOT have the Agent tool (cannot sub-delegate). They do NOT have WebFetch or MCP tools unless explicitly configured.\n\n## 4. Task Workflow\n\nMost tasks can be broken down into the following phases:\n\n### Phases\n\n| Phase | Who | Purpose |\n|-------|-----|---------|\n| Research | Workers (parallel) | Investigate codebase, find files, understand problem |\n| Synthesis | **You** (coordinator) | Read findings, understand the problem, craft implementation specs |\n| Implementation | Workers | Make targeted changes per spec, commit |\n| Verification | Workers | Test changes work |\n\n### Concurrency\n\n**Parallelism is your superpower. Workers are async. Launch independent workers concurrently whenever possible — don't serialize work that can run simultaneously. When doing research, cover multiple angles. To launch workers in parallel, make multiple tool calls in a single message.**\n\nManage concurrency:\n- **Read-only tasks** (research) — run in parallel freely\n- **Write-heavy tasks** (implementation) — one at a time per set of files\n- **Verification** can sometimes run alongside implementation on different file areas\n\n### What Real Verification Looks Like\n\nVerification means **proving the code works**, not confirming it exists. A verifier that rubber-stamps weak work undermines everything.\n\n- Run tests **with the feature enabled** — not just \"tests pass\"\n- Run typechecks and **investigate errors** — don't dismiss as \"unrelated\"\n- Be skeptical — if something looks off, dig in\n- **Test independently** — prove the change works, don't rubber-stamp\n\n### Handling Worker Failures\n\nWhen a worker reports failure (tests failed, build errors, file not found):\n- Spawn a new worker with corrected instructions that incorporate the error context\n- If a correction attempt fails, try a different approach or report to the caller\n\n## 5. Writing Worker Prompts\n\n**Workers can't see your conversation.** Every prompt must be self-contained with everything the worker needs.\n\n### Always synthesize — your most important job\n\nWhen workers report research findings, **you must understand them before directing follow-up work**. Read the findings. Identify the approach. Then write a prompt that proves you understood by including specific file paths, line numbers, and exactly what to change.\n\nNever write \"based on your findings\" or \"based on the research.\" These phrases delegate understanding to the worker instead of doing it yourself. You never hand off understanding to another worker.\n\n\\`\\`\\`\n// Anti-pattern — lazy delegation\nAgent({ prompt: \"Based on your findings, fix the auth bug\", ... })\nAgent({ prompt: \"The worker found an issue in the auth module. Please fix it.\", ... })\n\n// Good — synthesized spec\nAgent({ prompt: \"Fix the null pointer in src/auth/validate.ts:42. The user field on Session (src/auth/types.ts:15) is undefined when sessions expire but the token remains cached. Add a null check before user.id access — if null, return 401 with 'Session expired'. Commit and report the hash.\", ... })\n\\`\\`\\`\n\nA well-synthesized spec gives the worker everything it needs in a few sentences.\n\n### Add a purpose statement\n\nInclude a brief purpose so workers can calibrate depth and emphasis:\n\n- \"This research will inform an implementation plan — report file paths, line numbers, and type signatures.\"\n- \"This is a quick check before we finish — just verify the happy path.\"\n\n### Prompt tips\n\n**Good examples:**\n\n1. Implementation: \"Fix the null pointer in src/auth/validate.ts:42. The user field can be undefined when the session expires. Add a null check and return early with an appropriate error. Commit and report the hash.\"\n\n2. Precise git operation: \"Create a new branch from main called 'fix/session-expiry'. Cherry-pick only commit abc123 onto it. Push and create a draft PR targeting main.\"\n\n3. Research: \"Find all files in src/ that import from the auth module. Report the import paths, which functions they use, and whether they handle session expiry. Do not modify files.\"\n\n**Bad examples:**\n\n1. \"Fix the bug we discussed\" — no context, workers can't see your conversation\n2. \"Based on your findings, implement the fix\" — lazy delegation\n3. \"Something went wrong with the tests, can you look?\" — no error message, no file path\n\nAdditional tips:\n- Include file paths, line numbers, error messages — workers start fresh and need complete context\n- State what \"done\" looks like\n- For implementation: \"Run relevant tests and typecheck, then commit and report the hash\"\n- For research: \"Report findings — do not modify files\"\n- For verification: \"Prove the code works, don't just confirm it exists\"\n- For verification: \"Try edge cases and error paths — don't just re-run what the implementation worker ran\"\n\n## 6. Example Session\n\nCaller: \"There's a null pointer in the auth module. Can you fix it?\"\n\nYou:\n Let me investigate first.\n\n Agent({ description: \"Investigate auth bug\", subagent_type: \"worker\", prompt: \"Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation. Report specific file paths, line numbers, and types involved. Do not modify files.\" })\n Agent({ description: \"Research auth tests\", subagent_type: \"worker\", prompt: \"Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry. Do not modify files.\" })\n\n Investigating from two angles — I'll report back with findings.\n\n[Worker A completes with findings about validate.ts:42]\n\nYou:\n Found the bug — null pointer in validate.ts:42. The user field on Session is undefined when the session expires but the token remains cached.\n\n Agent({ description: \"Fix auth null pointer\", subagent_type: \"worker\", prompt: \"Fix the null pointer in src/auth/validate.ts:42. Add a null check before accessing user.id — if null, return 401 with 'Session expired'. Run the test suite. Commit and report the hash.\" })\n\n Fix is in progress.\n\n[Worker completes with commit hash]\n\nYou:\n Fixed in commit abc123. Let me verify.\n\n Agent({ description: \"Verify auth fix\", subagent_type: \"worker\", prompt: \"Run the full test suite for src/auth/. Verify that the null pointer fix in validate.ts:42 handles session expiry correctly. Try edge cases: expired session with cached token, valid session, no session. Report pass/fail for each.\" })\n\n Running verification.`\n}\n","/**\n * McpManager — lifecycle, tool collection, and orphan prevention for a\n * set of MCP servers.\n *\n * Production hardening (v0.2.0):\n *\n * 1. **Orphan prevention.** Registers a `process.on('exit')` handler\n * that synchronously SIGKILLs every still-running child process.\n * The handler is removed after `shutdownAll()` completes.\n *\n * 2. **Dead-server reconnect.** Before skipping a server in\n * `getTools()`, checks `client.isConnected`. If the child process\n * died between runs, the server transitions back to `'failed'` and\n * is retried on the current call.\n *\n * 3. **Shutdown timeout.** `shutdownAll()` races a `Promise.all`\n * against a 5-second deadline. Survivors are SIGKILLed.\n */\n\nimport type { Logger } from '../logging/logger.js'\nimport { hasProcessLifecycle } from '../runtime/detect.js'\nimport type { Tool } from '../tools/contract.js'\nimport { McpClient } from './client.js'\nimport { McpConnectionError, McpProtocolError } from './errors.js'\nimport { adaptMcpTool } from './toolAdapter.js'\nimport type { McpServerState, ResolvedMcpConfig } from './types.js'\n\n// Removed hardcoded constant — now comes from config.mcp.shutdownTimeoutMs\n\ninterface ManagedServer {\n readonly name: string\n readonly client: McpClient\n state: McpServerState\n tools: ReadonlyArray<Tool> | null\n connectPromise: Promise<void> | null\n}\n\nexport interface McpInstructionDelta {\n readonly connected: string[]\n readonly disconnected: string[]\n}\n\nexport class McpManager {\n private readonly logger: Logger\n private readonly servers: ManagedServer[]\n private readonly shutdownTimeoutMs: number\n private exitHandler: (() => void) | null = null\n /** Tracks which servers connected/disconnected since last delta retrieval. */\n private pendingConnected: string[] = []\n private pendingDisconnected: string[] = []\n\n constructor(\n config: ResolvedMcpConfig,\n logger: Logger,\n options: {\n samplingHandler?: import('./sampling.js').SamplingHandler\n } = {},\n ) {\n this.shutdownTimeoutMs = config.shutdownTimeoutMs\n this.logger = logger\n this.servers = Object.entries(config.servers).map(([name, serverConfig]) => ({\n name,\n client: new McpClient({\n serverName: name,\n config: serverConfig,\n connectTimeoutMs: config.connectTimeoutMs,\n callTimeoutMs: config.callTimeoutMs,\n logger,\n ...(options.samplingHandler !== undefined\n ? { samplingHandler: options.samplingHandler }\n : {}),\n }),\n state: 'uninitialized',\n tools: null,\n connectPromise: null,\n }))\n\n // Install a synchronous exit handler that kills child processes.\n // Only when process lifecycle hooks are available (Node.js). In\n // Cloudflare Workers, process.on('exit') is a stub — skip it.\n if (this.servers.length > 0 && hasProcessLifecycle()) {\n this.exitHandler = () => this.killAllSync()\n process.on('exit', this.exitHandler)\n }\n }\n\n get connectedCount(): number {\n return this.servers.filter((s) => s.state === 'connected').length\n }\n\n /**\n * Lazily connect every configured server and return the full set of\n * tools. Detects dead connections and retries them. Per-server failures\n * are isolated.\n */\n async getTools(): Promise<ReadonlyArray<Tool>> {\n if (this.servers.length === 0) return []\n\n await Promise.all(\n this.servers.map(async (server) => {\n // Skip already-disconnected (post-shutdown) servers.\n if (server.state === 'disconnected') return\n\n // Detect dead connections: the child may have died between runs.\n // The transport.onclose handler in McpClient flips isConnected to\n // false, so we can catch it here and allow a reconnect attempt.\n if (server.state === 'connected' && !server.client.isConnected) {\n this.logger.warn('mcp.connect dead connection detected, retrying', {\n server: server.name,\n })\n server.state = 'failed'\n server.tools = null\n this.pendingDisconnected.push(server.name)\n }\n\n if (server.state === 'connected') return\n await this.connectServer(server)\n }),\n )\n\n const out: Tool[] = []\n for (const server of this.servers) {\n if (server.state !== 'connected' || server.tools === null) continue\n out.push(...server.tools)\n }\n return out\n }\n\n /**\n * Retrieve and clear pending instruction deltas (connected/disconnected\n * servers since last call). Used by agentLoop to announce MCP changes\n * to the model. Ported from La-Machina's mcpInstructionsDelta.ts.\n */\n getInstructionDeltas(): McpInstructionDelta {\n const delta: McpInstructionDelta = {\n connected: this.pendingConnected.splice(0),\n disconnected: this.pendingDisconnected.splice(0),\n }\n return delta\n }\n\n /**\n * Graceful shutdown with a timeout. Attempts `client.close()` for\n * every active server within `SHUTDOWN_TIMEOUT_MS`. Servers that don't\n * respond in time are force-killed (SIGKILL for stdio, no-op for HTTP/SSE).\n *\n * Removes the process.on('exit') handler after cleanup.\n */\n async shutdownAll(): Promise<void> {\n const active = this.servers.filter((s) => s.state === 'connected' || s.state === 'connecting')\n\n if (active.length > 0) {\n this.logger.info('mcp.shutdown start', { connectedCount: active.length })\n\n const graceful = Promise.all(\n active.map(async (server) => {\n try {\n await server.client.close()\n } catch (err) {\n this.logger.warn('mcp.shutdown close failed', {\n server: server.name,\n error: (err as Error).message,\n })\n }\n server.state = 'disconnected'\n server.tools = null\n server.connectPromise = null\n }),\n )\n\n // Race against the shutdown timeout. If servers don't respond in\n // time, force-kill everything.\n const timeout = new Promise<'timeout'>((resolve) => {\n const timer = setTimeout(() => resolve('timeout'), this.shutdownTimeoutMs)\n if (typeof timer.unref === 'function') timer.unref()\n })\n\n const result = await Promise.race([graceful.then(() => 'ok' as const), timeout])\n if (result === 'timeout') {\n this.logger.warn('mcp.shutdown timeout — force-killing remaining servers')\n this.killAllSync()\n // Mark everything as disconnected.\n for (const server of active) {\n server.state = 'disconnected'\n server.tools = null\n server.connectPromise = null\n }\n }\n\n this.logger.info('mcp.shutdown complete', {})\n }\n\n // Remove the exit handler — we've cleaned up, nothing to kill.\n this.removeExitHandler()\n }\n\n /**\n * Synchronously SIGKILL every known child PID. Used by the\n * process.on('exit') handler (where async is not possible) and by the\n * shutdown timeout fallback.\n */\n private killAllSync(): void {\n for (const server of this.servers) {\n server.client.killSync()\n }\n }\n\n private removeExitHandler(): void {\n if (this.exitHandler !== null) {\n process.removeListener('exit', this.exitHandler)\n this.exitHandler = null\n }\n }\n\n private async connectServer(server: ManagedServer): Promise<void> {\n if (server.state === 'connecting' && server.connectPromise !== null) {\n await server.connectPromise\n return\n }\n\n server.state = 'connecting'\n server.connectPromise = this.doConnect(server)\n try {\n await server.connectPromise\n } finally {\n server.connectPromise = null\n }\n }\n\n private async doConnect(server: ManagedServer): Promise<void> {\n this.logger.debug('mcp.connect start', { server: server.name })\n try {\n await server.client.connect()\n const defs = server.client.listTools()\n server.tools = defs.map((def) => adaptMcpTool(server.client, server.name, def))\n server.state = 'connected'\n this.pendingConnected.push(server.name)\n } catch (err) {\n server.state = 'failed'\n server.tools = null\n if (err instanceof McpConnectionError || err instanceof McpProtocolError) {\n this.logger.warn('mcp.connect failed', {\n server: server.name,\n error: err.message,\n })\n } else {\n this.logger.warn('mcp.connect failed (unexpected error)', {\n server: server.name,\n error: (err as Error).message,\n })\n }\n }\n }\n}\n","/**\n * McpClient — wraps `@modelcontextprotocol/sdk`'s Client for all three\n * transports (stdio, HTTP, SSE).\n *\n * Production hardening (v0.2.0):\n * - Tracks the child PID for stdio transports → McpManager can\n * synchronously kill orphans in a process.on('exit') handler.\n * - Detects dead connections: if `callTool()` fails with a transport\n * error, `isConnected` flips to false so McpManager can retry the\n * next time `getTools()` is called.\n * - Flattens MCP content blocks into a single string.\n * - Maps SDK errors into engine-typed errors.\n */\n\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport {\n CreateMessageRequestSchema,\n type CreateMessageRequest,\n type CreateMessageResult,\n} from '@modelcontextprotocol/sdk/types.js'\nimport type { Logger } from '../logging/logger.js'\nimport { BindingHttpTransport } from './bindingTransport.js'\nimport { McpConnectionError, McpProtocolError, McpTimeoutError } from './errors.js'\nimport type { McpCallResult, McpToolDef, ResolvedMcpServerConfig } from './types.js'\n\nconst CLIENT_IDENTITY = { name: 'la-machina-engine', version: '0.3.0' } as const\nconst CLIENT_CAPABILITIES = {} as const\n\nexport interface McpClientOptions {\n readonly serverName: string\n readonly config: ResolvedMcpServerConfig\n readonly connectTimeoutMs: number\n readonly callTimeoutMs: number\n readonly logger: Logger\n readonly transportOverride?: Transport\n /**\n * Handler invoked when this server issues a `sampling/createMessage`\n * request. Only called when `config.allowSampling === true`. When\n * absent, sampling requests are refused with a protocol error.\n */\n readonly samplingHandler?: import('./sampling.js').SamplingHandler\n}\n\nexport class McpClient {\n readonly serverName: string\n private readonly options: McpClientOptions\n private sdkClient: Client | null = null\n private toolCache: readonly McpToolDef[] | null = null\n private connected = false\n /** PID of the child process (stdio only). Used for synchronous orphan kill. */\n private childPid: number | null = null\n\n constructor(options: McpClientOptions) {\n this.serverName = options.serverName\n this.options = options\n }\n\n get isConnected(): boolean {\n return this.connected\n }\n\n /** PID of the spawned child process (stdio only). Null for HTTP/SSE. */\n get pid(): number | null {\n return this.childPid\n }\n\n async connect(): Promise<void> {\n if (this.connected) return\n\n const transport = this.options.transportOverride ?? this.buildTransport()\n\n // Advertise the `sampling` capability only when the server has it\n // allowed AND a handler was provided. Without both, the server\n // receives zero sampling capabilities during initialize and won't\n // attempt the reverse call.\n const capabilities: Record<string, unknown> = { ...CLIENT_CAPABILITIES }\n const allowSampling =\n (this.options.config as { allowSampling?: boolean }).allowSampling === true\n const samplingHandler = this.options.samplingHandler\n if (allowSampling && samplingHandler !== undefined) {\n capabilities.sampling = {}\n }\n\n const client = new Client(CLIENT_IDENTITY, { capabilities })\n\n // Install the sampling request handler BEFORE transport connects\n // so the SDK is ready for server-initiated requests that may land\n // during or immediately after initialize.\n if (allowSampling && samplingHandler !== undefined) {\n this.installSamplingHandler(client, samplingHandler)\n }\n // Note: when allowSampling is false (default), we DON'T register a\n // refusal handler. The SDK rejects setRequestHandler for any\n // method whose capability we haven't advertised. Since we omit\n // `sampling: {}` from capabilities, the SDK itself returns the\n // \"method not supported\" error to the server — which is exactly\n // what we want. See Plan 018 §2 safety design.\n\n // Detect transport death so isConnected flips proactively.\n transport.onclose = () => {\n this.connected = false\n }\n\n try {\n await withTimeout(\n client.connect(transport),\n this.options.connectTimeoutMs,\n () =>\n new McpConnectionError(\n this.serverName,\n `initialize did not complete within ${this.options.connectTimeoutMs}ms`,\n ),\n )\n } catch (err) {\n await safeClose(client)\n throw wrapConnectionError(this.serverName, err)\n }\n\n // Capture PID for orphan kill (stdio transport only).\n if (transport instanceof StdioClientTransport) {\n this.childPid = transport.pid ?? null\n }\n\n let tools: readonly McpToolDef[]\n try {\n const response = await client.listTools()\n tools = normalizeToolList(response, this.serverName)\n } catch (err) {\n await safeClose(client)\n throw wrapProtocolError(this.serverName, err, 'tools/list failed')\n }\n\n this.sdkClient = client\n this.toolCache = tools\n this.connected = true\n this.options.logger.info('mcp.connect ok', {\n server: this.serverName,\n type: this.options.config.type,\n toolCount: tools.length,\n ...(this.childPid !== null ? { pid: this.childPid } : {}),\n })\n }\n\n listTools(): readonly McpToolDef[] {\n if (this.toolCache === null) {\n throw new McpProtocolError(this.serverName, 'listTools() called before connect()')\n }\n return this.toolCache\n }\n\n async callTool(toolName: string, input: unknown): Promise<McpCallResult> {\n const client = this.sdkClient\n if (client === null || !this.connected) {\n throw new McpProtocolError(this.serverName, `callTool(${toolName}) — not connected`)\n }\n\n const params = {\n name: toolName,\n arguments: normalizeInput(input),\n }\n\n this.options.logger.debug('mcp.callTool', { server: this.serverName, tool: toolName })\n\n let response: unknown\n try {\n response = await withTimeout(\n client.callTool(params),\n this.options.callTimeoutMs,\n () => new McpTimeoutError(this.serverName, toolName, this.options.callTimeoutMs),\n )\n } catch (err) {\n // Mark as disconnected so McpManager retries on the next getTools().\n this.connected = false\n throw err instanceof McpTimeoutError || err instanceof McpProtocolError\n ? err\n : wrapProtocolError(this.serverName, err, `callTool(${toolName})`)\n }\n\n return flattenCallResult(response, this.serverName, toolName)\n }\n\n async close(): Promise<void> {\n const client = this.sdkClient\n this.sdkClient = null\n this.connected = false\n this.toolCache = null\n this.childPid = null\n if (client !== null) {\n await safeClose(client)\n }\n }\n\n /**\n * Synchronously kill the child process (stdio only). Used by\n * McpManager's process.on('exit') handler where async work is not\n * possible. No-op for HTTP/SSE transports.\n */\n killSync(): void {\n const pid = this.childPid\n if (pid !== null) {\n try {\n process.kill(pid, 'SIGKILL')\n } catch {\n // Already dead or not our child — swallow.\n }\n this.childPid = null\n this.connected = false\n }\n }\n\n /**\n * Register the engine-side handler for MCP `sampling/createMessage`.\n * Runs user-supplied SamplingHandler, converts result to the MCP\n * `CreateMessageResult` shape.\n */\n private installSamplingHandler(\n client: Client,\n handler: import('./sampling.js').SamplingHandler,\n ): void {\n client.setRequestHandler(\n CreateMessageRequestSchema,\n async (request: CreateMessageRequest): Promise<CreateMessageResult> => {\n const params = request.params\n const engineRequest: import('./sampling.js').SamplingRequest = {\n messages: params.messages.map((m) => ({\n role: m.role,\n content: m.content,\n })) as ReadonlyArray<import('./sampling.js').SamplingMessage>,\n ...(typeof params.systemPrompt === 'string' ? { systemPrompt: params.systemPrompt } : {}),\n maxTokens: params.maxTokens,\n ...(typeof params.temperature === 'number' ? { temperature: params.temperature } : {}),\n ...(Array.isArray(params.stopSequences) ? { stopSequences: params.stopSequences } : {}),\n ...(params.modelPreferences !== undefined\n ? {\n modelPreferences:\n params.modelPreferences as import('./sampling.js').SamplingModelPreferences,\n }\n : {}),\n ...(params.includeContext !== undefined ? { includeContext: params.includeContext } : {}),\n ...(params.metadata !== undefined\n ? { metadata: params.metadata as Readonly<Record<string, unknown>> }\n : {}),\n }\n\n const response = await handler(engineRequest, {\n serverName: this.serverName,\n depth: 0,\n })\n\n return {\n role: response.role,\n content: response.content,\n model: response.model,\n ...(response.stopReason !== undefined ? { stopReason: response.stopReason } : {}),\n }\n },\n )\n }\n\n private buildTransport(): Transport {\n const config = this.options.config\n\n switch (config.type) {\n case 'stdio': {\n const env = resolveEnv(config.env, config.isolateEnv)\n return new StdioClientTransport({\n command: config.command,\n args: [...config.args],\n ...(env !== undefined ? { env } : {}),\n ...(config.cwd !== undefined ? { cwd: config.cwd } : {}),\n stderr: 'pipe',\n })\n }\n\n case 'http': {\n // Workers-friendly path — plain POST JSON-RPC, no long-lived SSE.\n // Opt-in via config.preferBindingTransport so Node users keep\n // the full Streamable HTTP behavior (notifications, resumption).\n if (config.preferBindingTransport === true) {\n return new BindingHttpTransport({\n url: config.url,\n ...(config.headers !== undefined ? { headers: config.headers } : {}),\n ...(config.headersProvider !== undefined\n ? { resolveHeaders: config.headersProvider }\n : {}),\n })\n }\n const url = new URL(config.url)\n const opts: { requestInit?: RequestInit; fetch?: typeof globalThis.fetch } = {}\n if (config.headers !== undefined) {\n opts.requestInit = { headers: { ...config.headers } }\n }\n if (config.headersProvider !== undefined) {\n // Wrap global fetch so the SDK's transport picks up fresh\n // headers per request. On 401 we invoke the provider a\n // second time and retry once (one-shot refresh).\n opts.fetch = wrapFetchWithHeadersProvider(\n globalThis.fetch.bind(globalThis),\n config.headersProvider,\n config.headers,\n )\n }\n // Cast: StreamableHTTPClientTransport has `sessionId?: string`\n // which conflicts with Transport's `sessionId?: string` under\n // exactOptionalPropertyTypes. The runtime shape is identical.\n return new StreamableHTTPClientTransport(url, opts) as unknown as Transport\n }\n\n case 'sse': {\n const url = new URL(config.url)\n const opts: { requestInit?: RequestInit; fetch?: typeof globalThis.fetch } = {}\n if (config.headers !== undefined) {\n opts.requestInit = { headers: { ...config.headers } }\n }\n if (config.headersProvider !== undefined) {\n opts.fetch = wrapFetchWithHeadersProvider(\n globalThis.fetch.bind(globalThis),\n config.headersProvider,\n config.headers,\n )\n }\n return new SSEClientTransport(url, opts)\n }\n }\n }\n}\n\n// ---------- helpers ----------\n\nfunction resolveEnv(\n explicit: Readonly<Record<string, string>> | undefined,\n isolate: boolean,\n): Record<string, string> | undefined {\n if (isolate) return explicit ? { ...explicit } : {}\n if (explicit === undefined) return undefined\n const parent: Record<string, string> = {}\n for (const [k, v] of Object.entries(process.env)) {\n if (typeof v === 'string') parent[k] = v\n }\n return { ...parent, ...explicit }\n}\n\nfunction normalizeInput(input: unknown): Record<string, unknown> {\n if (input === null || input === undefined) return {}\n if (typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>\n }\n return { input }\n}\n\nfunction normalizeToolList(response: unknown, serverName: string): readonly McpToolDef[] {\n if (\n response === null ||\n typeof response !== 'object' ||\n !('tools' in response) ||\n !Array.isArray((response as { tools: unknown }).tools)\n ) {\n throw new McpProtocolError(serverName, 'tools/list response did not contain a tools array')\n }\n const rawTools = (response as { tools: unknown[] }).tools\n const out: McpToolDef[] = []\n for (const t of rawTools) {\n if (t === null || typeof t !== 'object') continue\n const obj = t as Record<string, unknown>\n const name = typeof obj.name === 'string' ? obj.name : null\n if (name === null) continue\n const description = typeof obj.description === 'string' ? obj.description : ''\n const inputSchema =\n obj.inputSchema !== null &&\n typeof obj.inputSchema === 'object' &&\n !Array.isArray(obj.inputSchema)\n ? (obj.inputSchema as Record<string, unknown>)\n : { type: 'object', properties: {} }\n out.push({ name, description, inputSchema })\n }\n return out\n}\n\ninterface McpContentBlock {\n readonly type: string\n readonly text?: string\n readonly mimeType?: string\n readonly uri?: string\n readonly name?: string\n}\n\nfunction flattenCallResult(response: unknown, serverName: string, toolName: string): McpCallResult {\n if (response === null || typeof response !== 'object') {\n throw new McpProtocolError(serverName, `callTool(${toolName}) returned a non-object response`)\n }\n\n const obj = response as { content?: unknown; isError?: unknown; toolResult?: unknown }\n const isError = obj.isError === true\n\n if (obj.content === undefined && 'toolResult' in obj) {\n return {\n content: safeStringify(obj.toolResult),\n ...(isError ? { isError: true } : {}),\n }\n }\n\n if (!Array.isArray(obj.content)) {\n throw new McpProtocolError(serverName, `callTool(${toolName}) returned no content array`)\n }\n\n const pieces: string[] = []\n for (const raw of obj.content as unknown[]) {\n if (raw === null || typeof raw !== 'object') continue\n const block = raw as McpContentBlock\n if (block.type === 'text' && typeof block.text === 'string') {\n pieces.push(block.text)\n } else if (block.type === 'image') {\n pieces.push(`[image block: ${block.mimeType ?? 'unknown mime'}]`)\n } else if (block.type === 'audio') {\n pieces.push(`[audio block: ${block.mimeType ?? 'unknown mime'}]`)\n } else if (block.type === 'resource') {\n pieces.push(`[resource block: ${block.uri ?? '(no uri)'}]`)\n } else if (block.type === 'resource_link') {\n pieces.push(`[resource_link: ${block.name ?? ''} ${block.uri ?? ''}]`)\n } else {\n pieces.push(`[${block.type ?? 'unknown'} block]`)\n }\n }\n\n return {\n content: pieces.join('\\n'),\n ...(isError ? { isError: true } : {}),\n }\n}\n\nfunction safeStringify(value: unknown): string {\n if (typeof value === 'string') return value\n try {\n return JSON.stringify(value)\n } catch {\n return String(value)\n }\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n makeError: () => Error,\n): Promise<T> {\n if (timeoutMs <= 0) return promise\n let timer: NodeJS.Timeout | undefined\n try {\n return await Promise.race<T>([\n promise,\n new Promise<T>((_, reject) => {\n timer = setTimeout(() => reject(makeError()), timeoutMs)\n if (typeof timer.unref === 'function') timer.unref()\n }),\n ])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n}\n\nasync function safeClose(client: Client): Promise<void> {\n try {\n await client.close()\n } catch {\n // Swallow.\n }\n}\n\nfunction wrapConnectionError(serverName: string, err: unknown): McpConnectionError {\n if (err instanceof McpConnectionError) return err\n if (err instanceof McpTimeoutError) {\n return new McpConnectionError(serverName, err.message)\n }\n const message = err instanceof Error ? err.message : String(err)\n if (message.includes('ENOENT')) {\n return new McpConnectionError(serverName, `command not found (ENOENT)`)\n }\n if (message.includes('EACCES')) {\n return new McpConnectionError(serverName, `permission denied (EACCES)`)\n }\n return new McpConnectionError(serverName, message)\n}\n\nfunction wrapProtocolError(serverName: string, err: unknown, context: string): McpProtocolError {\n if (err instanceof McpProtocolError) return err\n const message = err instanceof Error ? err.message : String(err)\n return new McpProtocolError(serverName, `${context}: ${message}`)\n}\n\n/**\n * Wrap `fetch` so that it resolves fresh headers via the caller's\n * `headersProvider` on every request, merging over the static headers\n * passed in. On HTTP 401, invokes the provider again and retries the\n * request once (one-shot refresh) — see Plan 018 §1.\n */\nfunction wrapFetchWithHeadersProvider(\n baseFetch: typeof globalThis.fetch,\n headersProvider: () => Promise<Readonly<Record<string, string>>>,\n staticHeaders: Readonly<Record<string, string>> | undefined,\n): typeof globalThis.fetch {\n const doOnce = async (\n input: Parameters<typeof globalThis.fetch>[0],\n init: Parameters<typeof globalThis.fetch>[1],\n ): Promise<Response> => {\n const dynamic = await headersProvider()\n const merged = new Headers(init?.headers ?? {})\n if (staticHeaders !== undefined) {\n for (const [k, v] of Object.entries(staticHeaders)) merged.set(k, v)\n }\n for (const [k, v] of Object.entries(dynamic)) merged.set(k, v)\n return baseFetch(input, { ...init, headers: merged })\n }\n\n return async (input, init) => {\n const first = await doOnce(input, init)\n if (first.status !== 401) return first\n // One-shot refresh on 401. The provider is expected to invalidate\n // any internal token cache so the second call returns a fresh value.\n return doOnce(input, init)\n }\n}\n","/**\n * BindingHttpTransport — plain-POST JSON-RPC MCP transport for Cloudflare\n * Workers.\n *\n * The upstream `StreamableHTTPClientTransport` opens a long-lived `fetch()`\n * with a streaming SSE response for server-push notifications. On the\n * Workers runtime that stream can hang unpredictably after `initialize`,\n * causing `tools/list` and `tools/call` to stall. This transport sidesteps\n * that entirely: every message is a short, stateless POST; the response\n * is parsed once and handed to `onmessage`. No persistent reader, no SSE.\n *\n * Trade-off: server-push notifications (logs, progress) don't work. That's\n * fine for the tool-calling use case — `tools/list` and `tools/call` are\n * request/response only.\n *\n * Implements just enough of the MCP transport contract for the engine's\n * `McpClient` to use. All pure JS — no `node:*` imports, Workers-safe.\n */\n\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js'\n\nconst SESSION_HEADER = 'Mcp-Session-Id'\n\nexport interface BindingHttpTransportOptions {\n /** Full URL of the MCP Streamable-HTTP endpoint (e.g. https://mcp.example.com/mcp). */\n readonly url: string\n /** Extra headers sent on every POST (auth tokens, API keys). */\n readonly headers?: Readonly<Record<string, string>>\n /**\n * Per-request dynamic header factory. When set, called before every\n * send; its result is merged OVER the static `headers`. On HTTP 401\n * the transport calls the factory again (invalidating any token\n * cache inside) and retries the request once.\n */\n readonly resolveHeaders?: () => Promise<Readonly<Record<string, string>>>\n /** Override fetch (tests only). Defaults to globalThis.fetch. */\n readonly fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. Default: 30_000. */\n readonly timeoutMs?: number\n}\n\n/**\n * MCP transport that speaks JSON-RPC 2.0 over bare POST. No persistent\n * connection. Not suitable for servers that rely on async notifications.\n */\nexport class BindingHttpTransport implements Transport {\n readonly url: string\n private readonly headers: Record<string, string>\n private readonly resolveHeaders: (() => Promise<Readonly<Record<string, string>>>) | undefined\n private readonly fetchImpl: typeof globalThis.fetch\n private readonly timeoutMs: number\n private started = false\n private closed = false\n sessionId?: string\n\n onclose?: () => void\n onerror?: (error: Error) => void\n onmessage?: (message: JSONRPCMessage) => void\n\n constructor(options: BindingHttpTransportOptions) {\n this.url = options.url\n this.headers = { ...(options.headers ?? {}) }\n this.resolveHeaders = options.resolveHeaders\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n this.timeoutMs = options.timeoutMs ?? 30_000\n }\n\n async start(): Promise<void> {\n // No persistent connection; `send()` does all the work.\n this.started = true\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n if (this.closed) {\n throw new Error('BindingHttpTransport: send after close')\n }\n if (!this.started) {\n // Protocol.connect calls start() first, but be defensive.\n this.started = true\n }\n\n const body = JSON.stringify(message)\n let response = await this.doFetch(body)\n\n // One-shot refresh on 401 when a headersProvider is configured.\n // We intentionally don't retry more than once — if the fresh\n // token also 401s, something is genuinely wrong.\n if (response.status === 401 && this.resolveHeaders !== undefined) {\n response = await this.doFetch(body)\n }\n\n // Capture session id from the initialize response (or any response\n // that carries one). Server sets it on initialize and expects it back\n // on every subsequent request.\n const newSession = response.headers.get(SESSION_HEADER)\n if (newSession !== null && newSession.length > 0) {\n this.sessionId = newSession\n }\n\n // Notifications/responses-only messages return 202 with no body.\n if (response.status === 202 || response.status === 204) return\n\n if (!response.ok) {\n const text = await safeText(response)\n const err = new Error(\n `BindingHttpTransport: HTTP ${String(response.status)} ${response.statusText}${text ? ` — ${text}` : ''}`,\n )\n this.onerror?.(err)\n throw err\n }\n\n // Parse JSON response. Server in enableJsonResponse mode returns a\n // single JSON-RPC response object (or array for batches).\n const contentType = response.headers.get('Content-Type') ?? ''\n if (!contentType.includes('application/json')) {\n // SSE response mode — read the first `data: …` line and parse it.\n // We don't support streaming notifications; we close after the\n // first message.\n const text = await response.text()\n const parsed = parseSseFrames(text)\n for (const msg of parsed) this.onmessage?.(msg as JSONRPCMessage)\n return\n }\n\n const responseBody = await response.text()\n if (responseBody.length === 0) return\n\n let parsed: unknown\n try {\n parsed = JSON.parse(responseBody)\n } catch (err) {\n const error = new Error(\n `BindingHttpTransport: invalid JSON response: ${err instanceof Error ? err.message : String(err)}`,\n )\n this.onerror?.(error)\n throw error\n }\n\n if (Array.isArray(parsed)) {\n for (const m of parsed) this.onmessage?.(m as JSONRPCMessage)\n } else {\n this.onmessage?.(parsed as JSONRPCMessage)\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.closed = true\n this.onclose?.()\n }\n\n /**\n * Perform a single POST, applying current headers (static + dynamic).\n * Does not retry — the 401-refresh loop lives in `send()`.\n */\n private async doFetch(body: string): Promise<Response> {\n const dynamic = this.resolveHeaders !== undefined ? await this.resolveHeaders() : {}\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n ...this.headers,\n ...dynamic,\n }\n if (this.sessionId !== undefined) {\n headers[SESSION_HEADER] = this.sessionId\n }\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), this.timeoutMs)\n try {\n return await this.fetchImpl(this.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n this.onerror?.(error)\n throw error\n } finally {\n clearTimeout(timer)\n }\n }\n}\n\nasync function safeText(r: Response): Promise<string> {\n try {\n return await r.text()\n } catch {\n return ''\n }\n}\n\n/**\n * Parse a simple SSE stream body captured as text. Returns all `data:`\n * payloads as parsed JSON-RPC messages, skipping any we can't parse.\n * Only used for servers that refuse to switch to JSON response mode.\n */\nfunction parseSseFrames(text: string): unknown[] {\n const out: unknown[] = []\n for (const block of text.split(/\\r?\\n\\r?\\n/)) {\n const lines = block.split(/\\r?\\n/).filter((l) => l.startsWith('data:'))\n if (lines.length === 0) continue\n const raw = lines.map((l) => l.slice(5).trimStart()).join('\\n')\n if (raw.length === 0) continue\n try {\n out.push(JSON.parse(raw))\n } catch {\n /* skip unparseable frames */\n }\n }\n return out\n}\n","/**\n * MCP error taxonomy.\n *\n * Three error classes, all subclasses of `EngineError`:\n *\n * - `McpConnectionError` — a server failed to spawn, initialize, or list\n * tools. Swallowed by `McpManager`: logged as warn, server's tools are\n * absent from the registry, run proceeds.\n *\n * - `McpProtocolError` — a server returned a malformed JSON-RPC response\n * or an unexpected capability mismatch. Usually a server bug. Surfaces\n * in `tool_result` as `isError: true` when it happens during a call.\n *\n * - `McpTimeoutError` — a tool call exceeded `mcp.callTimeoutMs`.\n * Surfaces in `tool_result` as `isError: true` so the agent loop can\n * recover (retry, use a different tool, report back).\n *\n * The principle: MCP is best-effort. A run must never fail because one\n * of its MCP servers went wrong.\n */\n\nimport { EngineError } from '../engine/errors.js'\n\nexport class McpConnectionError extends EngineError {\n readonly serverName: string\n\n constructor(serverName: string, cause: string) {\n super('ERR_MCP_CONNECT', `mcp: ${serverName} — ${cause}`)\n this.serverName = serverName\n }\n}\n\nexport class McpProtocolError extends EngineError {\n readonly serverName: string\n\n constructor(serverName: string, cause: string) {\n super('ERR_MCP_PROTOCOL', `mcp: ${serverName} — ${cause}`)\n this.serverName = serverName\n }\n}\n\nexport class McpTimeoutError extends EngineError {\n readonly serverName: string\n readonly toolName: string\n readonly timeoutMs: number\n\n constructor(serverName: string, toolName: string, timeoutMs: number) {\n super('ERR_MCP_TIMEOUT', `mcp: ${serverName}/${toolName} exceeded ${timeoutMs}ms`)\n this.serverName = serverName\n this.toolName = toolName\n this.timeoutMs = timeoutMs\n }\n}\n","/**\n * adaptMcpTool — convert an `McpToolDef` into an engine `Tool`.\n *\n * The returned tool:\n *\n * - Has its name prefixed with `mcp__{serverName}__` so it cannot\n * collide with built-in or custom tools.\n * - Carries the server's description verbatim (the model sees this\n * as the tool's \"what does it do\" text).\n * - Uses `z.unknown()` as the engine-side input schema. MCP tools\n * author their validation in JSON Schema, not Zod, and the server\n * itself validates on receipt. Rather than run a lossy\n * JSON-Schema → Zod conversion at adapter time, we let the server\n * be the source of truth and pass input through unchanged.\n * - Sets `anthropicSchemaOverride` to the raw MCP JSON Schema — this\n * is what the engine ships to the Anthropic API so the model sees\n * a proper `input_schema` with typed parameters.\n * - Dispatches to `McpClient.callTool()`, turning `McpCallResult`\n * into the engine's `ToolResult` and catching any thrown MCP errors\n * into `{ isError: true }` results so the agent loop can recover.\n *\n * Why not use `z.any().passthrough()` instead of `z.unknown()`?\n * `z.unknown()` validates nothing (matches any value, including\n * `undefined`). `z.any()` is semantically equivalent but linters\n * frown on it. Either works; we pick `unknown` for stricter types.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from '../tools/contract.js'\nimport type { McpClient } from './client.js'\nimport { McpProtocolError, McpTimeoutError } from './errors.js'\nimport type { McpToolDef } from './types.js'\n\n/** Build the engine-side tool name for an MCP tool. */\nexport function mcpToolName(serverName: string, toolName: string): string {\n return `mcp__${serverName}__${toolName}`\n}\n\nexport function adaptMcpTool(\n client: McpClient,\n serverName: string,\n def: McpToolDef,\n): Tool<z.ZodUnknown> {\n const registeredName = mcpToolName(serverName, def.name)\n return defineTool({\n name: registeredName,\n description:\n def.description.length > 0 ? def.description : `MCP tool ${serverName}/${def.name}`,\n inputSchema: z.unknown(),\n // Pass the MCP server's JSON Schema through to Anthropic verbatim,\n // bypassing Zod-to-JSON-Schema conversion (which would produce `{}`\n // for our `z.unknown()` Zod schema).\n anthropicSchemaOverride: def.inputSchema,\n execute: async (input): Promise<ToolResult> => {\n try {\n const result = await client.callTool(def.name, input)\n return {\n content: result.content,\n ...(result.isError === true ? { isError: true } : {}),\n metadata: {\n mcpServer: serverName,\n mcpTool: def.name,\n },\n }\n } catch (err) {\n if (err instanceof McpTimeoutError || err instanceof McpProtocolError) {\n return {\n content: `${registeredName} failed: ${err.message}`,\n isError: true,\n metadata: { mcpServer: serverName, mcpTool: def.name, errorCode: err.code },\n }\n }\n return {\n content: `${registeredName} failed: ${(err as Error).message}`,\n isError: true,\n metadata: { mcpServer: serverName, mcpTool: def.name },\n }\n }\n },\n })\n}\n","/**\n * MCP sampling — Plan 018 §2.\n *\n * MCP servers can issue `sampling/createMessage` requests asking the\n * *client* to run an LLM completion on their behalf. The canonical use\n * case is a tool that needs to summarize / classify / structure some\n * text internally without carrying its own API key.\n *\n * This module provides:\n *\n * - `SamplingHandler` — the function callers can install via\n * `EngineInternals.samplingHandler` to customize routing.\n * - `defaultSamplingHandler(modelAdapter)` — a ready-to-use default\n * that routes every request to the engine's own model adapter.\n * Same model, same API key, same billing.\n * - Request/response shapes mirroring MCP's schema closely enough to\n * translate both directions without leaking SDK internals into the\n * rest of the engine.\n *\n * Safety: calling sampling is OFF by default per MCP server\n * (`allowSampling: false`). When a server attempts sampling and the\n * flag is off, the McpClient responds with a protocol error instead\n * of invoking the handler. The handler itself is only called after\n * the gate passes.\n */\n\nimport type { ModelAdapter } from '../model/adapter.js'\n\n/** Content block shape accepted from / sent to the MCP server. */\nexport interface SamplingTextBlock {\n readonly type: 'text'\n readonly text: string\n}\n\nexport interface SamplingMessage {\n readonly role: 'user' | 'assistant'\n readonly content: SamplingTextBlock | ReadonlyArray<SamplingTextBlock>\n}\n\nexport interface SamplingModelPreferences {\n readonly hints?: ReadonlyArray<{ readonly name?: string }>\n readonly costPriority?: number\n readonly speedPriority?: number\n readonly intelligencePriority?: number\n}\n\nexport interface SamplingRequest {\n readonly messages: ReadonlyArray<SamplingMessage>\n readonly systemPrompt?: string\n readonly maxTokens: number\n readonly temperature?: number\n readonly stopSequences?: ReadonlyArray<string>\n readonly modelPreferences?: SamplingModelPreferences\n readonly includeContext?: 'none' | 'thisServer' | 'allServers'\n readonly metadata?: Readonly<Record<string, unknown>>\n}\n\nexport interface SamplingResponse {\n readonly role: 'assistant'\n readonly model: string\n /** The assistant text. */\n readonly content: SamplingTextBlock\n readonly stopReason?: 'endTurn' | 'stopSequence' | 'maxTokens' | 'error'\n}\n\nexport interface SamplingContext {\n /** MCP server that issued the request. */\n readonly serverName: string\n /** Engine runId for the run this handler was invoked inside. */\n readonly runId?: string\n /** Engine nodeId for the run. */\n readonly nodeId?: string\n /**\n * Nesting depth — incremented when sampling itself triggers another\n * sampling request. Guards against loops: handlers MAY refuse when\n * `depth` exceeds a threshold (default implementation refuses at 3).\n */\n readonly depth: number\n}\n\nexport type SamplingHandler = (\n request: SamplingRequest,\n context: SamplingContext,\n) => Promise<SamplingResponse>\n\n/** Max depth the default handler will recurse through. */\nexport const DEFAULT_SAMPLING_MAX_DEPTH = 3\n\n/**\n * Build a default handler that routes every sampling request to the\n * provided `ModelAdapter`. Consumes the stream, concatenates the text\n * blocks, and maps the stop reason into the MCP vocabulary.\n *\n * If you want a different model per server, provide a custom\n * handler via `EngineInternals.samplingHandler`.\n */\nexport function defaultSamplingHandler(modelAdapter: ModelAdapter): SamplingHandler {\n return async (request, context) => {\n if (context.depth > DEFAULT_SAMPLING_MAX_DEPTH) {\n throw new Error(\n `Sampling depth ${String(context.depth)} exceeded max ${String(DEFAULT_SAMPLING_MAX_DEPTH)} — refusing to prevent loops`,\n )\n }\n\n const messages = request.messages.map((m) => ({\n role: m.role,\n content: extractText(m.content),\n }))\n\n const textChunks: string[] = []\n let mcpStopReason: NonNullable<SamplingResponse['stopReason']> = 'endTurn'\n\n for await (const event of modelAdapter.streamMessage({\n messages,\n ...(request.systemPrompt !== undefined ? { system: request.systemPrompt } : {}),\n maxTokens: request.maxTokens,\n ...(request.temperature !== undefined ? { temperature: request.temperature } : {}),\n })) {\n if (event.type === 'text') textChunks.push(event.text)\n if (event.type === 'message_stop') {\n mcpStopReason = mapStopReason(event.stopReason)\n }\n }\n\n return {\n role: 'assistant',\n // We don't know the concrete model id at this layer — adapters\n // should fill it in if they care. Use a generic label.\n model: 'engine-default',\n content: { type: 'text', text: textChunks.join('') },\n stopReason: mcpStopReason,\n }\n }\n}\n\nfunction extractText(content: SamplingTextBlock | ReadonlyArray<SamplingTextBlock>): string {\n if (Array.isArray(content)) {\n return content.map((b) => b.text).join('')\n }\n return (content as SamplingTextBlock).text\n}\n\nfunction mapStopReason(sr: unknown): NonNullable<SamplingResponse['stopReason']> {\n switch (sr) {\n case 'end_turn':\n case 'tool_use':\n case 'pause_turn':\n return 'endTurn'\n case 'stop_sequence':\n return 'stopSequence'\n case 'max_tokens':\n return 'maxTokens'\n case 'refusal':\n return 'error'\n default:\n return 'endTurn'\n }\n}\n","/**\n * Permission evaluator — the decision pipeline.\n *\n * Pipeline (evaluated in order, first match wins):\n *\n * 1. Mode check:\n * - `'open'` → allow immediately (no further evaluation)\n * - `'locked'` → check allowlist only (skip rules entirely)\n * - `'rules'` → proceed to step 2\n *\n * 2. Safe-tool allowlist fast-path:\n * - If the tool is on the safe allowlist → allow (skip rules)\n *\n * 3. Rule evaluation (top-to-bottom):\n * - First matching rule wins\n * - `allow:X` → allow\n * - `deny:X` → deny with reason\n *\n * 4. Fall-closed:\n * - If no rule matched → deny (\"no matching rule, mode is rules\")\n *\n * The evaluator is a pure function: no side effects, no LLM calls.\n * The gate hook (`hooks.gateBeforeTool`) runs AFTER this evaluation in\n * the engine's tool dispatch — it can override a permission allow with\n * a pause, but it cannot override a permission deny.\n */\n\nimport { isSafeTool } from './allowlist.js'\nimport { matchesRule, parseRules } from './rules.js'\nimport type { PermissionDecision, PermissionRule, ResolvedPermissionsConfig } from './types.js'\n\n/**\n * Compiled permission policy — call `check(toolName)` to get a decision.\n * Built once at engine construction time from the resolved config.\n */\nexport interface PermissionPolicy {\n check(toolName: string): PermissionDecision\n}\n\nconst ALLOW: PermissionDecision = { allowed: true }\n\n/**\n * Build a `PermissionPolicy` from a resolved config. The returned\n * object is reusable across all runs on the same engine instance.\n */\nexport function buildPermissionPolicy(config: ResolvedPermissionsConfig): PermissionPolicy {\n if (config.mode === 'open') {\n return { check: () => ALLOW }\n }\n\n if (config.mode === 'locked') {\n return {\n check: (toolName: string): PermissionDecision => {\n if (isSafeTool(toolName)) return ALLOW\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" is not on the safe-tool allowlist (mode: locked)`,\n }\n },\n }\n }\n\n // mode === 'rules'\n const rules: readonly PermissionRule[] = parseRules(config.rules)\n\n return {\n check: (toolName: string): PermissionDecision => {\n // Fast path: safe tools bypass rules.\n if (isSafeTool(toolName)) return ALLOW\n\n // Evaluate rules top-to-bottom, first match wins.\n for (const rule of rules) {\n if (matchesRule(toolName, rule)) {\n if (rule.action === 'allow') return ALLOW\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" matched deny rule \"${rule.action}:${rule.pattern}\"`,\n }\n }\n }\n\n // No rule matched — fall closed.\n return {\n allowed: false,\n reason: `Permission denied: \"${toolName}\" — no matching rule (mode: rules, fall-closed)`,\n }\n },\n }\n}\n","/**\n * Safe tool allowlist — tools that are always safe to run without\n * human approval or rule evaluation.\n *\n * Ported from La-Machina's `SAFE_YOLO_ALLOWLISTED_TOOLS`. These tools\n * are read-only or purely informational — they cannot modify the\n * filesystem, send messages, or cause side effects beyond reading state.\n *\n * Used by `'locked'` mode: only these tools pass, everything else is\n * denied. Also used as a fast-path in `'rules'` mode: allowlisted tools\n * skip rule evaluation entirely.\n */\n\nexport const SAFE_TOOL_ALLOWLIST: ReadonlySet<string> = new Set([\n // Filesystem reads\n 'Read',\n 'Glob',\n 'Grep',\n\n // Task management (read/write internal state, no external side effects)\n 'TaskCreate',\n 'TaskGet',\n 'TaskList',\n 'TaskUpdate',\n\n // Memory (read/write engine-internal memory, no external effects)\n 'Memorize',\n 'Recall',\n\n // Search + discovery (read-only)\n 'ToolSearch',\n 'SkillPage',\n 'WebSearch',\n\n // Plan/question (informational, triggers pause or produces output)\n 'AskUserQuestion',\n\n // Agent spawning (scoped to engine's own context)\n 'Agent',\n\n // Sleep (no side effects)\n 'Sleep',\n])\n\n/**\n * Check if a tool name is on the safe allowlist.\n */\nexport function isSafeTool(toolName: string): boolean {\n return SAFE_TOOL_ALLOWLIST.has(toolName)\n}\n","/**\n * Rule parser + matcher.\n *\n * Rule string format: `\"action:pattern\"`\n * - action: `allow` or `deny`\n * - pattern: exact tool name or glob with `*` wildcard\n *\n * Examples:\n * - `\"allow:Read\"` → allow the Read tool\n * - `\"deny:Bash\"` → deny the Bash tool\n * - `\"allow:mcp__fs__*\"` → allow all tools from the fs MCP server\n * - `\"deny:mcp__*\"` → deny all MCP tools\n * - `\"deny:*\"` → deny everything (catch-all)\n * - `\"allow:*\"` → allow everything (catch-all)\n *\n * Invalid rule strings are silently skipped (logged at warn level by\n * the evaluator).\n */\n\nimport picomatch from 'picomatch'\nimport type { PermissionAction, PermissionRule } from './types.js'\n\n/**\n * Parse a rule string into a structured `PermissionRule`. Returns null\n * if the string is malformed.\n */\nexport function parseRule(raw: string): PermissionRule | null {\n const colonIndex = raw.indexOf(':')\n if (colonIndex === -1) return null\n\n const action = raw.slice(0, colonIndex).trim().toLowerCase()\n const pattern = raw.slice(colonIndex + 1).trim()\n\n if (action !== 'allow' && action !== 'deny') return null\n if (pattern.length === 0) return null\n\n return { action: action as PermissionAction, pattern }\n}\n\n/**\n * Parse an array of rule strings into structured rules, skipping\n * malformed entries.\n */\nexport function parseRules(raw: readonly string[]): readonly PermissionRule[] {\n const out: PermissionRule[] = []\n for (const r of raw) {\n const parsed = parseRule(r)\n if (parsed !== null) out.push(parsed)\n }\n return out\n}\n\n/**\n * Check if a tool name matches a rule's pattern. Uses picomatch for\n * glob support (same library the engine uses for Glob/Grep tools).\n */\nexport function matchesRule(toolName: string, rule: PermissionRule): boolean {\n if (rule.pattern === '*') return true\n if (rule.pattern === toolName) return true\n return picomatch.isMatch(toolName, rule.pattern)\n}\n","/**\n * memoryConfig — applies the engine's `memory.mode` and `memory.scope`\n * gates to a wrapped Hippocampus + EpisodicMemory pair.\n *\n * Three modes from `ResolvedMemoryConfig`:\n *\n * - `'off'` — All reads return empty, all writes are no-ops.\n * The wrapped Hippocampus is built but never touched.\n * - `'read-only'` — Reads pass through to the wrapped Hippocampus,\n * writes are silent no-ops.\n * - `'read-write'` — Both reads and writes pass through.\n *\n * Scope (Plan 022): memory always reads/writes the workspace\n * adapter. The previous `'global'` scope was removed — the workspace\n * is the tenant root and nothing spans tenants.\n *\n * The factory returns a thin façade that exposes Hippocampus's read +\n * write surface plus the EpisodicMemory instance. The agent loop and\n * tools talk to this façade, never the raw Hippocampus.\n */\n\nimport type { MemoryMode, MemoryScope } from '../config/types.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { EpisodicMemory } from './episodes.js'\nimport { Hippocampus } from './hippocampus.js'\nimport type { EngramConfidence, EngramSource } from './types.js'\n\nexport interface SmartMemoryConfig {\n readonly mode: MemoryMode\n readonly scope: MemoryScope\n}\n\nexport interface SmartMemoryOptions {\n readonly storage: EngineStorage\n readonly config: SmartMemoryConfig\n}\n\nexport interface SmartMemory {\n readonly mode: MemoryMode\n readonly scope: MemoryScope\n readonly episodes: EpisodicMemory\n\n // ---------- recall ----------\n recallIdentity(): Promise<string>\n recallRules(): Promise<string>\n recallLessons(tokenBudget?: number): Promise<string>\n recallTopic(slug: string): Promise<string>\n\n // ---------- encode ----------\n encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence?: EngramConfidence,\n source?: EngramSource,\n ): Promise<void>\n encodeLesson(text: string, topic?: string, source?: EngramSource): Promise<void>\n rewriteIdentity(entries: ReadonlyArray<string>): Promise<void>\n}\n\nexport function createSmartMemory(options: SmartMemoryOptions): SmartMemory {\n const { storage, config } = options\n // Plan 022 — memory always lives in workspace scope.\n const adapter = storage.workspace\n const hippocampus = new Hippocampus(adapter, 'smart-memory')\n\n const writesEnabled = config.mode === 'read-write'\n const readsEnabled = config.mode !== 'off'\n\n // Episodic memory is write-only by nature; only enable when writes\n // are allowed AND mode isn't 'off'. Read-only mode keeps episodes off.\n const episodes = new EpisodicMemory(adapter, 'smart-memory/episodes', writesEnabled)\n\n return {\n mode: config.mode,\n scope: config.scope,\n episodes,\n\n async recallIdentity(): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallIdentity()\n },\n\n async recallRules(): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallRules()\n },\n\n async recallLessons(tokenBudget?: number): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallLessons(tokenBudget)\n },\n\n async recallTopic(slug: string): Promise<string> {\n if (!readsEnabled) return ''\n return hippocampus.recallTopic(slug)\n },\n\n async encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence?: EngramConfidence,\n source?: EngramSource,\n ): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.encodeRule(text, kind, confidence, source)\n },\n\n async encodeLesson(text: string, topic?: string, source?: EngramSource): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.encodeLesson(text, topic, source)\n },\n\n async rewriteIdentity(entries: ReadonlyArray<string>): Promise<void> {\n if (!writesEnabled) return\n await hippocampus.rewriteIdentity(entries)\n },\n }\n}\n","/**\n * EpisodicMemory — append-only JSONL log of every turn in a run.\n *\n * Ported from La-Machina with TS-strict cleanup. The episodic log\n * captures the raw timeline of conversation turns (user input,\n * assistant text, tool calls, tool results) for later inspection,\n * search, or training data extraction.\n *\n * Design rules:\n * - **Fire-and-forget**: `logTurn()` returns synchronously and never\n * throws. Storage errors are swallowed so logging cannot break the\n * agent loop.\n * - **Disabled = total no-op**: when `enabled` is false, no file is\n * created and `logTurn()` does nothing. Used to implement\n * `memory.mode === 'off'` at the engine config layer.\n * - **Per-session file**: each `startSession()` mints a fresh JSONL\n * under `{subdir}/{sessionId}.jsonl`. Format `YYYYMMDD_HHMMSS`.\n * - **Truncation**: tool_call and tool_result content is capped at\n * 2000 characters to keep individual entries small.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { Episode } from './types.js'\n\nconst MAX_TOOL_INPUT = 2000\nconst MAX_TOOL_RESULT = 2000\n\nexport class EpisodicMemory {\n private readonly storage: StorageAdapter\n private readonly subdir: string\n private _enabled: boolean\n private _sessionId: string | null = null\n private _filePath: string | null = null\n /**\n * Serialization chain — every log() chains its appendFile onto the\n * previous one so on-disk order matches call order. Without this,\n * two concurrent unawaited appendFile calls can land in arbitrary\n * order even though each individual O_APPEND is atomic.\n */\n private writeChain: Promise<void> = Promise.resolve()\n\n constructor(storage: StorageAdapter, subdir = 'smart-memory/episodes', enabled = true) {\n this.storage = storage\n this.subdir = subdir\n this._enabled = enabled\n }\n\n get enabled(): boolean {\n return this._enabled\n }\n\n set enabled(value: boolean) {\n this._enabled = value\n }\n\n get currentSessionId(): string | null {\n return this._sessionId\n }\n\n /**\n * Start a new session — mints a timestamp-based id and creates an\n * empty JSONL file under `{subdir}/`. Returns the session id, or\n * empty string if disabled.\n */\n async startSession(): Promise<string> {\n if (!this._enabled) return ''\n\n const now = new Date()\n const y = now.getUTCFullYear()\n const mo = String(now.getUTCMonth() + 1).padStart(2, '0')\n const d = String(now.getUTCDate()).padStart(2, '0')\n const h = String(now.getUTCHours()).padStart(2, '0')\n const mi = String(now.getUTCMinutes()).padStart(2, '0')\n const s = String(now.getUTCSeconds()).padStart(2, '0')\n this._sessionId = `${y}${mo}${d}_${h}${mi}${s}`\n this._filePath = `${this.subdir}/${this._sessionId}.jsonl`\n\n try {\n if (!(await this.storage.exists(this._filePath))) {\n await this.storage.writeFile(this._filePath, '')\n }\n } catch {\n // Fire-and-forget — failures here don't kill the run.\n }\n\n return this._sessionId\n }\n\n async resumeSession(sessionId: string): Promise<string> {\n this._sessionId = sessionId\n this._filePath = `${this.subdir}/${sessionId}.jsonl`\n try {\n if (!(await this.storage.exists(this._filePath))) {\n await this.storage.writeFile(this._filePath, '')\n }\n } catch {\n // Fire-and-forget\n }\n return this._sessionId\n }\n\n /**\n * Log a single episode entry. Fire-and-forget — never blocks, never\n * throws. Disabled mode and missing session both produce silent\n * no-ops so callers don't have to guard.\n */\n log(episode: Episode): void {\n if (!this._enabled || this._filePath === null) return\n const line = JSON.stringify(episode) + '\\n'\n const filePath = this._filePath\n // Chain onto the previous write so concurrent log() calls land\n // in the order they were issued. Errors are swallowed — episodic\n // logging must never block conversation.\n this.writeChain = this.writeChain.then(() =>\n this.storage.appendFile(filePath, line).catch(() => undefined),\n )\n }\n\n /** Convenience wrapper that builds an Episode and logs it. */\n logTurn(\n turn: number,\n role: Episode['role'],\n content: string,\n meta: Readonly<Record<string, unknown>> = {},\n ): void {\n if (!this._enabled || this._sessionId === null) return\n\n let truncated = content\n if (role === 'tool_call' && truncated.length > MAX_TOOL_INPUT) {\n truncated = truncated.slice(0, MAX_TOOL_INPUT)\n } else if (role === 'tool_result' && truncated.length > MAX_TOOL_RESULT) {\n truncated = truncated.slice(0, MAX_TOOL_RESULT)\n }\n\n this.log({\n ts: new Date().toISOString(),\n session: this._sessionId,\n turn,\n role,\n content: truncated,\n meta,\n })\n }\n}\n","/**\n * Hippocampus — memory encoding and retrieval engine.\n *\n * Ported from La-Machina. Named for the brain's hippocampus, which\n * encodes new traces (writing) and pattern-completes partial cues into\n * full memories (reading).\n *\n * Each Hippocampus instance manages one scope's files via a\n * StorageAdapter:\n * - profile.md → identity (full rewrite, not append)\n * - rules.md → behavioral gates (always / never / when sections)\n * - lessons.md → semantic facts (append + dedup, token-budgeted recall)\n * - topics/*.md → per-topic deep dives\n *\n * The storage backend is fully abstracted — the same instance works\n * against local fs or R2. Read-modify-write paths use the adapter's\n * atomic `writeFile` so concurrent writers see one or the other, never\n * a partial.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { EngramConfidence, EngramSource } from './types.js'\n\n// Metadata comment pattern: <!-- key:value key:value -->\nconst METADATA_RE = /\\s*<!--[\\s\\S]*?-->\\s*$/\n\nconst RULES_SKELETON = '# Rules\\n\\n## Always\\n\\n## Never\\n\\n## When\\n'\n\nexport class Hippocampus {\n private readonly storage: StorageAdapter\n private readonly subdir: string\n private readonly profilePath: string\n private readonly rulesPath: string\n private readonly lessonsPath: string\n private readonly topicsDir: string\n\n constructor(storage: StorageAdapter, subdir = 'smart-memory') {\n this.storage = storage\n this.subdir = subdir\n this.profilePath = `${subdir}/profile.md`\n this.rulesPath = `${subdir}/rules.md`\n this.lessonsPath = `${subdir}/lessons.md`\n this.topicsDir = `${subdir}/topics`\n }\n\n // ---------- recall (read) ----------\n\n async recallIdentity(): Promise<string> {\n const content = await this.storage.readFile(this.profilePath)\n return (content ?? '').trim()\n }\n\n async recallRules(): Promise<string> {\n const content = await this.storage.readFile(this.rulesPath)\n return (content ?? '').trim()\n }\n\n /**\n * Load semantic knowledge most recent first, within a token budget\n * (rough heuristic: 4 chars per token). The header lines (# Lessons,\n * blank lines) always survive; entry lines fill the remaining budget\n * starting from the most recent.\n */\n async recallLessons(tokenBudget = 1000): Promise<string> {\n const content = await this.storage.readFile(this.lessonsPath)\n if (content === null || content.trim().length === 0) return ''\n\n const lines = content\n .trim()\n .split('\\n')\n .filter((ln) => ln.trim().length > 0)\n const headerLines: string[] = []\n const entryLines: string[] = []\n\n for (const ln of lines) {\n if (ln.startsWith('- ') || ln.startsWith(' ')) {\n entryLines.push(ln)\n } else {\n headerLines.push(ln)\n }\n }\n\n // Reverse so most recent are first.\n entryLines.reverse()\n\n const charBudget = tokenBudget * 4\n const resultLines: string[] = [...headerLines]\n let used = resultLines.reduce((sum, ln) => sum + ln.length, 0)\n\n for (const ln of entryLines) {\n if (used + ln.length + 1 > charBudget) break\n resultLines.push(ln)\n used += ln.length + 1\n }\n\n return resultLines.join('\\n')\n }\n\n async recallTopic(slug: string): Promise<string> {\n const safeSlug = Hippocampus.sanitizeSlug(slug)\n const topicPath = `${this.topicsDir}/${safeSlug}.md`\n const content = await this.storage.readFile(topicPath)\n return (content ?? '').trim()\n }\n\n // ---------- encode (write) ----------\n\n async encodeRule(\n text: string,\n kind: 'always' | 'never' | 'when',\n confidence: EngramConfidence = 'medium',\n source: EngramSource = 'llm',\n ): Promise<void> {\n const ts = new Date().toISOString().slice(0, 10)\n const metadata = `<!-- confidence:${confidence} source:${source} ts:${ts} -->`\n const entry = `- ${text} ${metadata}\\n`\n const sectionHeader = `## ${kind.charAt(0).toUpperCase()}${kind.slice(1)}`\n\n let content = await this.storage.readFile(this.rulesPath)\n if (content === null) content = RULES_SKELETON\n\n if (Hippocampus.extractEntryTexts(content).has(text)) return\n\n const lines = content.split(/(?<=\\n)/) // split keeping newlines\n const out: string[] = []\n let inserted = false\n let i = 0\n\n while (i < lines.length) {\n const current = lines[i] as string\n out.push(current)\n if (current.trim() === sectionHeader && !inserted) {\n i++\n const sectionEntries: string[] = []\n while (\n i < lines.length &&\n !(\n (lines[i] as string).trim().startsWith('## ') &&\n (lines[i] as string).trim() !== sectionHeader\n )\n ) {\n sectionEntries.push(lines[i] as string)\n i++\n }\n out.push(...sectionEntries)\n const lastEntry = sectionEntries[sectionEntries.length - 1]\n if (sectionEntries.length > 0 && lastEntry !== undefined && lastEntry.trim().length > 0) {\n out.push('\\n')\n }\n out.push(entry)\n inserted = true\n continue\n }\n i++\n }\n\n if (!inserted) {\n out.push(`\\n${sectionHeader}\\n${entry}`)\n }\n\n await this.storage.writeFile(this.rulesPath, out.join(''))\n }\n\n async encodeLesson(text: string, topic = '', source: EngramSource = 'llm'): Promise<void> {\n const ts = new Date().toISOString().slice(0, 10)\n const topicTag = topic ? ` topic:${topic}` : ''\n const sourceTag = source !== 'llm' ? ` source:${source}` : ''\n const entry = `- ${text} <!--${topicTag}${sourceTag} ts:${ts} -->\\n`\n\n const existing = await this.storage.readFile(this.lessonsPath)\n if (existing === null) {\n await this.storage.writeFile(this.lessonsPath, `# Lessons\\n${entry}`)\n } else if (!Hippocampus.extractEntryTexts(existing).has(text)) {\n await this.storage.appendFile(this.lessonsPath, entry)\n }\n\n if (topic) {\n const slug = Hippocampus.sanitizeSlug(topic)\n const topicPath = `${this.topicsDir}/${slug}.md`\n const topicContent = await this.storage.readFile(topicPath)\n if (topicContent === null) {\n await this.storage.writeFile(topicPath, `# ${topic}\\n${entry}`)\n } else if (!Hippocampus.extractEntryTexts(topicContent).has(text)) {\n await this.storage.appendFile(topicPath, entry)\n }\n }\n }\n\n /**\n * Replace the identity snapshot — full rewrite, not append. Identity\n * is a coherent snapshot, not an append log.\n */\n async rewriteIdentity(entries: ReadonlyArray<string>): Promise<void> {\n const content = `# Profile\\n${entries.map((e) => `- ${e}`).join('\\n')}\\n`\n await this.storage.writeFile(this.profilePath, content)\n }\n\n async entryCount(): Promise<number> {\n let count = 0\n for (const filePath of [this.rulesPath, this.lessonsPath]) {\n const content = await this.storage.readFile(filePath)\n if (content === null) continue\n count += content.split('\\n').filter((ln) => ln.trim().startsWith('- ')).length\n }\n return count\n }\n\n // ---------- accessors ----------\n\n getStorage(): StorageAdapter {\n return this.storage\n }\n\n get rulesPathRelative(): string {\n return this.rulesPath\n }\n\n get lessonsPathRelative(): string {\n return this.lessonsPath\n }\n\n get subdirPath(): string {\n return this.subdir\n }\n\n // ---------- static helpers ----------\n\n /**\n * Extract normalized entry texts from a markdown memory file.\n * Strips the \"- \" prefix and trailing `<!-- ... -->` metadata so\n * dedup works regardless of the comment payload.\n */\n static extractEntryTexts(content: string): Set<string> {\n const texts = new Set<string>()\n for (const line of content.split('\\n')) {\n const stripped = line.trim()\n if (!stripped.startsWith('- ')) continue\n let entry = stripped.slice(2)\n entry = entry.replace(METADATA_RE, '').trim()\n if (entry.length > 0) texts.add(entry)\n }\n return texts\n }\n\n /** Sanitize a topic name into a safe file slug. */\n static sanitizeSlug(name: string): string {\n let text = name.toLowerCase().trim()\n text = text.replace(/[^a-z0-9\\s_-]/g, '')\n text = text.replace(/\\s+/g, '-')\n text = text.replace(/-+/g, '-')\n text = text.replace(/^-|-$/g, '')\n return text.length > 0 ? text : 'general'\n }\n}\n","/**\n * buildSystemPrompt — assemble the full system prompt from static\n * sections, dynamic per-run sections, and optional memory/skill recall.\n *\n * Section order (matches La-Machina's cacheable/dynamic split):\n *\n * ── STATIC (cacheable prefix — identical across runs) ──\n * 1. Base identity + capabilities\n * 2. Doing tasks (behavioral rules)\n * 3. Executing actions with care (reversibility, blast radius)\n * 4. Using your tools (tool-specific instructions)\n * 5. Tone and style + output efficiency\n *\n * ── DYNAMIC (changes per-run) ──\n * 6. Environment (OS, CWD, model, date)\n * 7. MCP tools (when config.mcp.servers is populated)\n * 8. Identity (smart memory profile.md)\n * 9. Rules (smart memory rules.md)\n * 10. Lessons (smart memory lessons.md, token-budgeted)\n * 11. Skills (loadSkills() output as name/description list)\n * 12. Custom base (caller-supplied override, appended last)\n *\n * The function is async because memory recall and skill discovery both\n * involve storage adapter reads. It's pure-ish — no writes, no side\n * effects beyond the reads themselves.\n */\n\nimport type { SmartMemory } from '../memory/memoryConfig.js'\nimport type { Tool } from '../tools/contract.js'\nimport { loadSkills } from '../skills/loader.js'\nimport type { EngineStorage } from '../storage/interface.js'\nimport { getBaseSection } from './sections/base.js'\nimport { getDoingTasksSection } from './sections/doingTasks.js'\nimport { getActionsSection } from './sections/actions.js'\nimport { getUsingToolsSection } from './sections/usingTools.js'\nimport { getToneAndStyleSection } from './sections/toneAndStyle.js'\nimport { getEnvironmentSection } from './sections/environment.js'\nimport { getMcpSection } from './sections/mcp.js'\n\nexport interface BuildSystemPromptOptions {\n /** Custom base instruction appended to the system prompt. */\n readonly base?: string\n /** SmartMemory façade — reads are gated by memory mode. */\n readonly memory: SmartMemory\n /** Storage adapter pair — used to enumerate skills. */\n readonly storage: EngineStorage\n /** Whether to scan and inject the skill index. */\n readonly skillsAutoload: boolean\n /** Directory to scan for skills (relative to each scope's adapter root). */\n readonly skillsDir?: string\n /**\n * Pre-resolved skill catalogue. When set, takes precedence over the\n * disk scan (`skillsAutoload` + `skillsDir`). Used by the engine when\n * `RunOptions.skills` supplies an inline list via `InlineSkillSource`.\n */\n readonly skillList?: ReadonlyArray<{ name: string; description: string }>\n /** Token budget for the lessons section (default: 1000). */\n readonly lessonsTokenBudget?: number\n /** Model ID for the environment section. */\n readonly modelId?: string\n /** Provider name for the environment section. */\n readonly provider?: string\n /** Working directory override for the environment section. */\n readonly cwd?: string\n /** Registered tool names — drives tool-specific prompt instructions. */\n readonly registeredToolNames?: ReadonlySet<string>\n /** MCP-sourced tools — listed in a dedicated prompt section. */\n readonly mcpTools?: ReadonlyArray<Tool>\n /** When true, skip normal static sections (base/doingTasks/etc.) —\n * the coordinator prompt replaces them via `base`. */\n readonly coordinatorMode?: boolean\n}\n\nexport async function buildSystemPrompt(options: BuildSystemPromptOptions): Promise<string> {\n const sections: string[] = []\n\n // ── STATIC SECTIONS ──\n // In coordinator mode, the coordinator prompt (passed via options.base)\n // replaces the normal static sections. The dynamic sections below\n // (environment, MCP, memory, skills) are still appended.\n if (!options.coordinatorMode) {\n sections.push(getBaseSection())\n sections.push(getDoingTasksSection())\n sections.push(getActionsSection())\n\n if (options.registeredToolNames !== undefined && options.registeredToolNames.size > 0) {\n sections.push(getUsingToolsSection({ registeredToolNames: options.registeredToolNames }))\n }\n\n sections.push(getToneAndStyleSection())\n }\n\n // ── DYNAMIC SECTIONS ──\n\n sections.push(\n await getEnvironmentSection({\n modelId: options.modelId ?? 'unknown',\n provider: options.provider ?? 'unknown',\n cwd: options.cwd,\n }),\n )\n\n // MCP tools section — only when MCP tools are registered.\n if (options.mcpTools !== undefined && options.mcpTools.length > 0) {\n const mcpSection = getMcpSection({ mcpTools: options.mcpTools })\n if (mcpSection !== null) sections.push(mcpSection)\n }\n\n // Memory sections — each gated by SmartMemory.mode internally.\n const identity = await options.memory.recallIdentity()\n if (identity.length > 0) {\n sections.push(`# Identity\\n${identity}`)\n }\n\n const rules = await options.memory.recallRules()\n if (rules.length > 0) {\n sections.push(`# Rules\\n${rules}`)\n }\n\n const lessons = await options.memory.recallLessons(options.lessonsTokenBudget)\n if (lessons.length > 0) {\n sections.push(`# Lessons\\n${lessons}`)\n }\n\n // Skills section.\n //\n // Two sources of truth, in precedence order:\n // 1. Pre-resolved `options.skillList` — set by the caller when they\n // already know the catalogue (e.g., RunOptions.skills override).\n // 2. Fallback disk scan via `skillsAutoload` + `skillsDir`.\n //\n // Callers using `SkillSource` (Plan 017) pass `skillList` directly and\n // leave `skillsAutoload` false. The legacy path is kept for backwards\n // compatibility with callers still supplying only `skillsAutoload`.\n const effectiveSkillList: ReadonlyArray<{ name: string; description: string }> | undefined =\n options.skillList !== undefined\n ? options.skillList\n : options.skillsAutoload\n ? await collectSkills(options.storage, options.skillsDir ?? 'skills')\n : undefined\n\n if (effectiveSkillList !== undefined && effectiveSkillList.length > 0) {\n const lines: string[] = ['# Skills']\n for (const skill of effectiveSkillList) {\n lines.push(`- ${skill.name}: ${skill.description}`)\n }\n lines.push('', 'Use the SkillPage tool to load a specific page from a multi-page skill.')\n sections.push(lines.join('\\n'))\n }\n\n // Custom base — In coordinator mode, the coordinator prompt was\n // already prepended at the top (before dynamic sections). In normal\n // mode, it's appended at the end so callers can override.\n if (options.base !== undefined && options.base.length > 0) {\n if (options.coordinatorMode) {\n // Prepend — coordinator prompt is the identity section.\n sections.unshift(options.base)\n } else {\n sections.push(options.base)\n }\n }\n\n return sections.join('\\n\\n')\n}\n\nasync function collectSkills(\n storage: EngineStorage,\n skillsDir: string,\n): Promise<Array<{ name: string; description: string }>> {\n // Plan 022 — workspace-only. Previous workspace+global merge was\n // removed along with the global scope.\n const workspace = await loadSkills(storage.workspace, skillsDir)\n return workspace.map((s) => ({ name: s.name, description: s.description }))\n}\n","/**\n * Skills loader — discovers `SKILL.md` files under a base directory.\n *\n * The skill format is intentionally minimal:\n *\n * skills/\n * ├── alpha/\n * │ ├── SKILL.md ← required (name + description)\n * │ └── pages/ ← optional (multi-page skill)\n * │ ├── intro.md\n * │ └── advanced.md\n * └── beta/\n * └── SKILL.md\n *\n * The loader returns one `LoadedSkill` per discovered `SKILL.md`. The\n * description is extracted from the first non-empty body line (anything\n * after the title heading) — falling back to the heading text itself if\n * the file has no body.\n *\n * The result feeds into:\n * - the system prompt builder (Phase 12+) which injects skill names +\n * descriptions so the model knows what's available\n * - the SkillPage tool, which lets the model load specific pages on\n * demand for multi-page skills\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\n\nexport interface LoadedSkill {\n /** Folder name (also used as the lookup key in SkillPage). */\n readonly name: string\n /** Human-readable description, extracted from SKILL.md. */\n readonly description: string\n /** Whether the skill has a pages/ subdirectory with content. */\n readonly hasPages: boolean\n /** Full relative path to the skill folder, e.g. \"skills/alpha\". */\n readonly path: string\n /** Full relative path to the SKILL.md file. */\n readonly skillFilePath: string\n}\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\n/**\n * Walk the given base directory and return one entry per discovered\n * skill. Returns an empty array when the base directory does not exist\n * or contains no skills.\n */\nexport async function loadSkills(storage: StorageAdapter, baseDir: string): Promise<LoadedSkill[]> {\n const entries = await storage.listDir(baseDir)\n if (entries.length === 0) return []\n\n const out: LoadedSkill[] = []\n\n for (const entry of entries.slice().sort()) {\n if (!SAFE_NAME.test(entry)) continue\n const folder = `${baseDir}/${entry}`\n if (!(await storage.isDirectory(folder))) continue\n\n const skillFilePath = `${folder}/SKILL.md`\n const content = await storage.readFile(skillFilePath)\n if (content === null) continue\n\n const description = extractDescription(content)\n const pagesDir = `${folder}/pages`\n const hasPages =\n (await storage.isDirectory(pagesDir)) && (await storage.listDir(pagesDir)).length > 0\n\n out.push({\n name: entry,\n description,\n hasPages,\n path: folder,\n skillFilePath,\n })\n }\n\n return out\n}\n\n/**\n * Pull a one-line description out of a SKILL.md document.\n *\n * Strategy:\n * 1. If the body has a non-empty paragraph (after a `# Heading`), use\n * its first line.\n * 2. Otherwise, use the heading text itself (with `# ` stripped).\n * 3. Otherwise return an empty string.\n */\nfunction extractDescription(content: string): string {\n const lines = content.split('\\n')\n let headingText = ''\n let inBody = false\n\n for (const rawLine of lines) {\n const line = rawLine.trim()\n if (!inBody) {\n // Capture the first heading\n if (line.startsWith('#')) {\n headingText = line.replace(/^#+\\s*/, '').trim()\n inBody = true\n continue\n }\n // No heading at all — use the first non-empty line\n if (line.length > 0) return line\n } else {\n // Body — return the first non-empty line\n if (line.length > 0) return line\n }\n }\n\n return headingText\n}\n","/**\n * Base identity + capabilities — the engine's equivalent of La-Machina's\n * SimpleIntro + SimpleSystem sections.\n *\n * Adapted for headless: no slash commands, no interactive prompts, no\n * terminal rendering. The model is told it runs inside la-machina-engine,\n * returns structured results, and works through tools.\n */\n\nexport function getBaseSection(): string {\n return `# System\n\nYou are an AI assistant running inside la-machina-engine. You complete tasks by using the tools available to you. Your output goes to a programmatic caller (not a human terminal), so focus on correctness and completeness.\n\nIMPORTANT: Assist with authorized security testing, defensive security, CTF challenges, and educational contexts. Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes.\nIMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident they are correct. You may use URLs provided in the task or discovered via tools.`\n}\n","/**\n * Task execution guidance — ported from La-Machina's SimpleDoingTasks.\n *\n * This is the core behavioral instruction set. Covers: ambition,\n * read-before-modify, security, code quality, verification, and honest\n * reporting. Kept nearly verbatim from La-Machina; terminal-only lines\n * (slash commands, /issue, /share) removed.\n */\n\nexport function getDoingTasksSection(): string {\n return `# Doing tasks\n\n- The caller will request you to perform tasks — solving bugs, adding features, refactoring, analyzing data, research, and more.\n- You are highly capable and often allow callers to complete ambitious tasks that would otherwise be too complex or take too long. You should defer to the caller's judgement about whether a task is too large to attempt.\n- If you notice the request is based on a misconception, or spot a bug adjacent to what was asked about, say so. You're a collaborator, not just an executor — callers benefit from your judgment, not just your compliance.\n- In general, do not propose changes to code you haven't read. If asked about or to modify a file, read it first. Understand existing code before suggesting modifications.\n- Do not create files unless they're absolutely necessary for achieving your goal. Generally prefer editing an existing file to creating a new one, as this prevents file bloat and builds on existing work more effectively.\n- Avoid giving time estimates or predictions for how long tasks will take. Focus on what needs to be done, not how long it might take.\n- If an approach fails, diagnose why before switching tactics — read the error, check your assumptions, try a focused fix. Don't retry the identical action blindly, but don't abandon a viable approach after a single failure either. Escalate only when you're genuinely stuck after investigation, not as a first response to friction.\n- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities. If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code.\n- Don't add features, refactor code, or make \"improvements\" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability. Don't add docstrings, comments, or type annotations to code you didn't change. Only add comments where the logic isn't self-evident.\n- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs). Don't use feature flags or backwards-compatibility shims when you can just change the code.\n- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. The right amount of complexity is what the task actually requires — no speculative abstractions, but no half-finished implementations either. Three similar lines of code is better than a premature abstraction.\n- Default to writing no comments. Only add one when the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug, behavior that would surprise a reader. If removing the comment wouldn't confuse a future reader, don't write it.\n- Don't explain WHAT the code does, since well-named identifiers already do that. Don't reference the current task, fix, or callers (\"used by X\", \"added for the Y flow\", \"handles the case from issue #123\"), since those belong in the commit message and rot as the codebase evolves.\n- Don't remove existing comments unless you're removing the code they describe or you know they're wrong. A comment that looks pointless to you may encode a constraint or a lesson from a past bug that isn't visible in the current diff.\n- Before reporting a task complete, verify it actually works: run the test, execute the script, check the output. Minimum complexity means no gold-plating, not skipping the finish line. If you can't verify (no test exists, can't run the code), say so explicitly rather than claiming success.\n- Report outcomes faithfully: if tests fail, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded. Never claim \"all tests pass\" when output shows failures, never suppress or simplify failing checks to manufacture a green result, and never characterize incomplete or broken work as done. Equally, when a check did pass or a task is complete, state it plainly — do not hedge confirmed results with unnecessary disclaimers, downgrade finished work to \"partial,\" or re-verify things you already checked. The goal is an accurate report, not a defensive one.`\n}\n","/**\n * Action safety guidance — ported from La-Machina's ActionsSection.\n *\n * Covers reversibility, blast radius, and when to pause for confirmation.\n * Adapted for headless: \"check with the user\" becomes \"check via the gate\n * callback\" since there's no interactive terminal.\n */\n\nexport function getActionsSection(): string {\n return `# Executing actions with care\n\nCarefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests. But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the caller before proceeding. The cost of pausing to confirm is low, while the cost of an unwanted action (lost work, unintended messages sent, deleted branches) can be very high. For actions like these, consider the context, the action, and caller instructions, and by default transparently communicate the action and ask for confirmation before proceeding. This default can be changed by caller instructions — if explicitly asked to operate more autonomously, then you may proceed without confirmation, but still attend to the risks and consequences when taking actions.\n\nExamples of the kind of risky actions that warrant confirmation:\n- Destructive operations: deleting files/branches, dropping database tables, killing processes, rm -rf, overwriting uncommitted changes\n- Hard-to-reverse operations: force-pushing (can overwrite upstream), git reset --hard, amending published commits, removing or downgrading packages/dependencies, modifying CI/CD pipelines\n- Actions visible to others or that affect shared state: pushing code, creating/closing/commenting on PRs or issues, sending messages (Slack, email, GitHub), posting to external services, modifying shared infrastructure or permissions\n- Uploading content to third-party web tools (diagram renderers, pastebins, gists) publishes it — consider whether it could be sensitive before sending, since it may be cached or indexed even if later deleted.\n\nWhen you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent in-progress work. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions — measure twice, cut once.`\n}\n","/**\n * Tool-specific instructions — ported from La-Machina's UsingYourTools.\n *\n * Tells the model to prefer dedicated tools over Bash, parallelize\n * independent tool calls, and use task tools for progress tracking.\n * Tool names are passed in so the section adapts to whatever tools\n * are actually registered.\n */\n\nexport interface ToolInstructionsOptions {\n readonly registeredToolNames: ReadonlySet<string>\n}\n\nexport function getUsingToolsSection(options: ToolInstructionsOptions): string {\n const has = (name: string) => options.registeredToolNames.has(name)\n const items: string[] = []\n\n // Core tool preference guidance — always included.\n items.push(\n `Do NOT use Bash to run commands when a relevant dedicated tool is provided. Using dedicated tools produces clearer, more reviewable output. This is CRITICAL:`,\n )\n\n if (has('Read')) items.push(` - To read files use Read instead of cat, head, tail, or sed`)\n if (has('Edit')) items.push(` - To edit files use Edit instead of sed or awk`)\n if (has('Write'))\n items.push(` - To create files use Write instead of cat with heredoc or echo redirection`)\n if (has('Glob')) items.push(` - To search for files use Glob instead of find or ls`)\n if (has('Grep')) items.push(` - To search the content of files, use Grep instead of grep or rg`)\n items.push(\n ` - Reserve using Bash exclusively for system commands and terminal operations that require shell execution. If you are unsure and there is a relevant dedicated tool, default to using the dedicated tool and only fallback on Bash if it is absolutely necessary.`,\n )\n\n // Parallel tool calls.\n items.push(\n `You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially.`,\n )\n\n // Agent tool guidance.\n if (has('Agent')) {\n items.push(\n `Use the Agent tool with specialized agents when the task at hand matches the agent's description. Subagents are valuable for parallelizing independent queries or for protecting the main context window from excessive results, but should not be used excessively when not needed. Importantly, avoid duplicating work that subagents are already doing — if you delegate research to a subagent, do not also perform the same searches yourself.`,\n )\n\n if (has('Glob') || has('Grep')) {\n items.push(\n `For simple, directed codebase searches (e.g. for a specific file/class/function) use Glob or Grep directly.`,\n )\n }\n }\n\n // Skill tool guidance.\n if (has('SkillPage')) {\n items.push(\n `Skills are surfaced in the system prompt. Use the SkillPage tool to load specific pages from multi-page skills when you need detailed instructions.`,\n )\n }\n\n return `# Using your tools\\n\\n${items.map((i) => ` - ${i}`).join('\\n')}`\n}\n","/**\n * Tone, style, and output format guidance — ported from La-Machina's\n * ToneAndStyle + OutputEfficiency sections.\n *\n * For the engine (headless), output goes to a programmatic caller —\n * so we optimize for conciseness, accuracy, and structured reporting\n * over conversational flair.\n */\n\nexport function getToneAndStyleSection(): string {\n return `# Tone and style\n\n- Only use emojis if the caller explicitly requests it. Avoid using emojis in all output unless asked.\n- Your responses should be concise and direct. Lead with the answer or action, not the reasoning.\n- When referencing specific functions or pieces of code include the pattern file_path:line_number.\n- When referencing GitHub issues or pull requests, use the owner/repo#123 format.\n- Do not use a colon before tool calls. Your tool calls may not be shown directly in the output, so text like \"Let me read the file:\" followed by a read tool call should just be \"Let me read the file.\" with a period.\n\n# Output efficiency\n\nGo straight to the point. Try the simplest approach first without going in circles. Do not overdo it. Be extra concise.\n\nKeep your text output brief and direct. Lead with the answer or action, not the reasoning. Skip filler words, preamble, and unnecessary transitions. Do not restate the task — just do it. When explaining, include only what is necessary.\n\nFocus text output on:\n- Decisions that need input\n- High-level status updates at natural milestones\n- Errors or blockers that change the plan\n\nIf you can say it in one sentence, don't use three. Prefer short, direct sentences over long explanations.`\n}\n","/**\n * Environment info — dynamic section injected per-run.\n *\n * Tells the model what OS, shell, platform, working directory, model\n * name, current date, and git status. La-Machina's equivalent reads\n * from the real system; the engine does the same but as a library it\n * can't assume a terminal.\n *\n * Git injection: when running in Node.js (canSpawnProcesses), queries\n * git for branch, status, and recent commits. Skips silently on\n * Workers or non-git directories. Ported from La-Machina's context.ts.\n */\n\nimport { canSpawnProcesses } from '../../runtime/detect.js'\n\nexport interface EnvironmentOptions {\n readonly modelId: string\n readonly provider: string\n readonly cwd?: string | undefined\n}\n\nexport async function getEnvironmentSection(options: EnvironmentOptions): Promise<string> {\n let platform = 'unknown'\n let osRelease = ''\n try {\n const os = await import('node:os')\n platform = os.platform()\n osRelease = os.release()\n } catch {\n platform = typeof navigator !== 'undefined' ? 'worker' : 'unknown'\n }\n const shell =\n (typeof process !== 'undefined' ? process.env?.SHELL : undefined) ??\n (platform === 'win32' ? 'cmd.exe' : '/bin/sh')\n const osVersion = `${platform}${osRelease ? ' ' + osRelease : ''}`\n const cwd = options.cwd ?? (typeof process !== 'undefined' && process.cwd ? process.cwd() : '/')\n const date = new Date().toISOString().split('T')[0]\n\n const lines = [\n '# Environment',\n '',\n `- Platform: ${platform}`,\n `- Shell: ${shell}`,\n `- OS Version: ${osVersion}`,\n `- Working directory: ${cwd}`,\n `- Model: ${options.modelId} (provider: ${options.provider})`,\n `- Current date: ${date}`,\n ]\n\n // Git injection — ported from La-Machina's context.ts.\n // Only runs in Node.js (needs child_process). Skips silently on Workers.\n if (canSpawnProcesses()) {\n const git = await getGitContext(cwd)\n if (git) {\n lines.push('')\n lines.push('## Git')\n if (git.branch) lines.push(`- Branch: ${git.branch}`)\n if (git.isRepo) lines.push(`- Is git repo: true`)\n if (git.status) lines.push(`- Status:\\n${git.status}`)\n if (git.recentCommits) lines.push(`- Recent commits:\\n${git.recentCommits}`)\n }\n }\n\n return lines.join('\\n')\n}\n\n// ---------- git helpers ----------\n\ninterface GitContext {\n isRepo: boolean\n branch?: string\n status?: string\n recentCommits?: string\n}\n\nasync function getGitContext(cwd: string): Promise<GitContext | null> {\n try {\n const { execSync } = await import('node:child_process')\n const opts = {\n cwd,\n stdio: ['ignore', 'pipe', 'ignore'] as ['ignore', 'pipe', 'ignore'],\n timeout: 5000,\n }\n\n // Check if inside a git repo\n try {\n execSync('git rev-parse --is-inside-work-tree', opts)\n } catch {\n return null // not a git repo\n }\n\n const branch = tryExec(execSync, 'git branch --show-current', opts)\n const status = tryExec(execSync, 'git status --short', opts, 2000)\n const recentCommits = tryExec(execSync, 'git log --oneline -5', opts, 2000)\n\n const ctx: GitContext = { isRepo: true }\n if (branch) ctx.branch = branch\n if (status) ctx.status = status\n if (recentCommits) ctx.recentCommits = recentCommits\n return ctx\n } catch {\n return null\n }\n}\n\nfunction tryExec(\n execSync: (cmd: string, opts: object) => Buffer,\n cmd: string,\n opts: object,\n maxChars = 1000,\n): string {\n try {\n const out = execSync(cmd, opts).toString('utf-8').trim()\n return out.length > maxChars ? out.slice(0, maxChars) + '\\n...(truncated)' : out\n } catch {\n return ''\n }\n}\n","/**\n * MCP server/tool instructions — dynamic section injected when MCP\n * servers are configured. Lists the available prefixed tools so the\n * model knows what external capabilities it has.\n */\n\nimport type { Tool } from '../../tools/contract.js'\n\nexport interface McpInstructionsOptions {\n readonly mcpTools: ReadonlyArray<Tool>\n}\n\nexport function getMcpSection(options: McpInstructionsOptions): string | null {\n if (options.mcpTools.length === 0) return null\n\n // Group tools by server name (extract from mcp__{server}__{tool}).\n const byServer = new Map<string, string[]>()\n for (const tool of options.mcpTools) {\n const match = tool.name.match(/^mcp__([^_]+)__(.+)$/)\n if (!match) continue\n const server = match[1]!\n const toolName = match[2]!\n if (!byServer.has(server)) byServer.set(server, [])\n byServer.get(server)!.push(toolName)\n }\n\n if (byServer.size === 0) return null\n\n const lines: string[] = ['# MCP Tools', '']\n lines.push(\n 'The following tools come from external MCP servers. Call them by their',\n 'full prefixed name (e.g. `mcp__filesystem__read_file`).',\n '',\n )\n\n for (const [server, tools] of byServer) {\n lines.push(`**${server}** (${tools.length} tool${tools.length === 1 ? '' : 's'}):`)\n for (const t of tools) {\n // Find the original tool to get its description.\n const fullName = `mcp__${server}__${t}`\n const original = options.mcpTools.find((o) => o.name === fullName)\n const desc = original?.description ?? ''\n lines.push(` - \\`${fullName}\\`${desc ? ` — ${desc}` : ''}`)\n }\n lines.push('')\n }\n\n return lines.join('\\n')\n}\n","/**\n * Structured JSON output — schema injection, parsing, validation.\n *\n * When `outputFormat: 'json'` is set on RunOptions:\n * 1. buildSchemaPrompt() injects output instructions into the system prompt\n * 2. tryParseJSON() extracts JSON from the model's response (handles fences, preamble)\n * 3. validateOutput() checks against the Zod schema\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { ZodTypeAny } from 'zod'\n\n// ---------- schema prompt injection ----------\n\n/**\n * Build the output format section to append to the system prompt.\n * Called when outputFormat is 'json'.\n */\nexport function buildSchemaPrompt(schema?: ZodTypeAny): string {\n const lines = [\n '# Output Format',\n '',\n 'CRITICAL: Your FINAL response (after all tool calls are complete) MUST be ONLY valid JSON.',\n 'No markdown fences. No explanation. No text before or after the JSON.',\n 'Do NOT wrap in ```json ... ```. Just raw JSON.',\n ]\n\n if (schema) {\n const jsonSchema = zodToJsonSchema(schema as Parameters<typeof zodToJsonSchema>[0], {\n target: 'jsonSchema7',\n $refStrategy: 'none',\n })\n const { $schema: _, ...clean } = jsonSchema as Record<string, unknown>\n lines.push('', 'The JSON MUST conform to this schema:', JSON.stringify(clean, null, 2))\n } else {\n lines.push('', 'Return a JSON object with the relevant data.')\n }\n\n return lines.join('\\n')\n}\n\n// ---------- JSON extraction ----------\n\nexport interface ParseResult {\n readonly ok: boolean\n readonly value?: unknown\n readonly error?: string\n}\n\n/**\n * Extract JSON from model output. Tries multiple strategies:\n * 1. Raw parse (entire text is JSON)\n * 2. Strip markdown fences (```json ... ```)\n * 3. Find first { ... } or [ ... ] block\n */\nexport function tryParseJSON(text: string): ParseResult {\n const trimmed = text.trim()\n\n // Strategy 1: raw parse\n try {\n return { ok: true, value: JSON.parse(trimmed) }\n } catch {\n /* continue */\n }\n\n // Strategy 2: strip markdown fences\n const fenced = trimmed.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)\\n?\\s*```/)\n if (fenced?.[1]) {\n try {\n return { ok: true, value: JSON.parse(fenced[1].trim()) }\n } catch {\n /* continue */\n }\n }\n\n // Strategy 3: find first { ... } or [ ... ] block (greedy)\n const braceStart = trimmed.indexOf('{')\n const bracketStart = trimmed.indexOf('[')\n const start =\n braceStart === -1\n ? bracketStart\n : bracketStart === -1\n ? braceStart\n : Math.min(braceStart, bracketStart)\n\n if (start !== -1) {\n const closer = trimmed[start] === '{' ? '}' : ']'\n const end = trimmed.lastIndexOf(closer)\n if (end > start) {\n try {\n return { ok: true, value: JSON.parse(trimmed.slice(start, end + 1)) }\n } catch {\n /* continue */\n }\n }\n }\n\n return { ok: false, error: 'No valid JSON found in response' }\n}\n\n// ---------- schema validation ----------\n\n/**\n * Validate parsed JSON against a Zod schema.\n * Returns the validated data or an error message.\n */\nexport function validateOutput(\n value: unknown,\n schema: ZodTypeAny,\n): { ok: true; data: unknown } | { ok: false; error: string } {\n const result = schema.safeParse(value)\n if (result.success) {\n return { ok: true, data: result.data }\n }\n // Format Zod errors into a readable string\n const issues = result.error.issues.map((i) => ` - ${i.path.join('.')}: ${i.message}`)\n return { ok: false, error: `Schema validation failed:\\n${issues.join('\\n')}` }\n}\n\n// ---------- retry prompt ----------\n\n/**\n * Build the retry prompt when JSON parsing or validation fails.\n */\nexport function buildRetryPrompt(error: string): string {\n return (\n `Your previous response was not valid JSON matching the required format.\\n` +\n `Error: ${error}\\n\\n` +\n `Respond with ONLY valid JSON. No markdown fences, no explanation, no text outside the JSON.`\n )\n}\n","/**\n * SkillPage tool — loads skill content on demand via a `SkillSource`.\n *\n * The tool is pluggable: the engine constructs it with either\n * `StorageSkillSource` (disk-backed, default) or `InlineSkillSource`\n * (per-run override). The tool itself only knows the interface.\n *\n * Input:\n * { skill: string, page?: string }\n *\n * - When `page` is omitted, the main `SKILL.md` body is returned.\n * - When `page` is set, the supplemental page body is returned.\n *\n * Errors surface as `{ isError: true, content }`:\n * - invalid skill / page name (path traversal shape)\n * - unknown skill (returned null from the source)\n * - unknown page\n * - upstream source throws (network error, SSRF block, etc.)\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool, type ToolResult } from '../tools/contract.js'\nimport type { SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\nconst inputSchema = z.object({\n skill: z.string().min(1),\n page: z.string().min(1).optional(),\n})\n\nexport interface SkillPageToolOptions {\n /** The skill source the tool reads through. */\n readonly source: SkillSource\n}\n\nexport function createSkillPageTool(options: SkillPageToolOptions): Tool<typeof inputSchema> {\n return defineTool({\n name: 'SkillPage',\n description:\n 'Load a skill. Pass `skill` alone to read the main SKILL.md; pass both `skill` and `page` to read a supplemental page. Skill names appear in the system prompt skill index.',\n inputSchema,\n execute: async ({ skill, page }): Promise<ToolResult> => {\n if (!SAFE_NAME.test(skill)) {\n return {\n content: `Invalid skill name \"${skill}\". Skill names must be alphanumeric with hyphens or underscores only.`,\n isError: true,\n }\n }\n if (page !== undefined && !SAFE_NAME.test(page)) {\n return {\n content: `Invalid page name \"${page}\". Page names must be alphanumeric with hyphens or underscores only.`,\n isError: true,\n }\n }\n\n let content: string | null\n try {\n content =\n page === undefined\n ? await options.source.getSkillFile(skill)\n : await options.source.getPage(skill, page)\n } catch (err) {\n return {\n content: `SkillPage: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n\n if (content === null) {\n if (page === undefined) {\n return {\n content: `Skill \"${skill}\" not found. Check the skill index in the system prompt for available skills.`,\n isError: true,\n }\n }\n const available = await options.source.listPages(skill)\n const suggestion =\n available.length > 0\n ? `\\n\\nAvailable pages in \"${skill}\":\\n${available.map((p) => `- ${p}`).join('\\n')}`\n : `\\n\\nThe skill \"${skill}\" has no pages.`\n return {\n content: `Page \"${page}\" not found in skill \"${skill}\".${suggestion}`,\n isError: true,\n }\n }\n\n return {\n content,\n metadata: page !== undefined ? { skill, page } : { skill },\n }\n },\n })\n}\n","/**\n * ApiCall — built-in tool for calling tenant-configured external\n * HTTP APIs without the model ever seeing credentials (Plan 020).\n *\n * The caller describes a set of `ApiServiceV1`s, supplies an `env`\n * map of credential values (or a `resolveAuth` callback for dynamic\n * auth), and this factory returns a `Tool` ready to register. The\n * model picks a service from a closed-over enum + issues a request;\n * the tool resolves auth, enforces per-service allowlists, fetches,\n * and returns the response. Credentials live only in the closure —\n * never in input, output, or any engine-persisted surface.\n *\n * Safety rails (all enforced per-call, first failure wins):\n * 1. `service` must be in the closed enum.\n * 2. Method must pass `allowedMethods` if set.\n * 3. Path must match an `allowedPaths` entry if set.\n * 4. Request body cannot exceed `maxBodyBytes` (default 256 KB).\n * 5. Model-supplied headers cannot override auth headers (the\n * sanitizer strips case-insensitive collisions).\n *\n * Response body is size-capped at `maxResponseBytes` (default 100 KB)\n * with a trailing truncation marker.\n */\n\nimport { z } from 'zod'\nimport { defineTool, type Tool } from './contract.js'\nimport type {\n ApiAuthResolverV1,\n ApiAuthV1,\n ApiHttpMethodV1,\n ApiRequestEventV1,\n ApiResolverCtxV1,\n ApiResponseEventV1,\n ApiServiceV1,\n} from './apiCall.types.js'\n\nconst ALL_METHODS: readonly ApiHttpMethodV1[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']\nconst DEFAULT_MAX_BODY_BYTES = 256 * 1024\nconst DEFAULT_MAX_RESPONSE_BYTES = 100 * 1024\n\nexport interface CreateApiCallToolOptions {\n readonly services: readonly ApiServiceV1[]\n readonly env?: Readonly<Record<string, string>>\n readonly resolveAuth?: ApiAuthResolverV1\n readonly fetch?: typeof globalThis.fetch\n readonly maxResponseBytes?: number\n readonly onRequest?: (e: ApiRequestEventV1) => void | Promise<void>\n readonly onResponse?: (e: ApiResponseEventV1) => void | Promise<void>\n readonly toolName?: string\n readonly toolDescription?: string\n}\n\nexport function createApiCallTool(opts: CreateApiCallToolOptions): Tool {\n if (opts.services.length === 0) {\n throw new Error('createApiCallTool: services list must be non-empty')\n }\n const services = new Map<string, ApiServiceV1>()\n for (const svc of opts.services) {\n if (services.has(svc.name)) {\n throw new Error(`createApiCallTool: duplicate service name \"${svc.name}\"`)\n }\n services.set(svc.name, svc)\n }\n const serviceNames = [...services.keys()] as [string, ...string[]]\n\n // Validate that every service with a `custom` auth type has a\n // resolver available. Built-in types (bearer/header/basic/none)\n // can be resolved from `env`; `custom` cannot.\n for (const svc of opts.services) {\n if (svc.auth?.type === 'custom' && opts.resolveAuth === undefined) {\n throw new Error(\n `createApiCallTool: service \"${svc.name}\" uses custom auth ` +\n `(id: ${svc.auth.id}) but no resolveAuth was supplied`,\n )\n }\n }\n\n const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis)\n const maxResponseBytes = opts.maxResponseBytes ?? DEFAULT_MAX_RESPONSE_BYTES\n\n const inputSchema = z.object({\n service: z.enum(serviceNames),\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']),\n path: z.string().regex(/^\\//, 'path must start with /'),\n query: z.record(z.string(), z.string()).optional(),\n body: z.unknown().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n })\n\n const description =\n opts.toolDescription ??\n `Call a configured external API. Services: ${serviceNames.join(', ')}. ` +\n `Auth is injected automatically — do not pass credentials via headers.`\n\n return defineTool({\n name: opts.toolName ?? 'ApiCall',\n description,\n inputSchema,\n execute: async (input) => {\n const svc = services.get(input.service)\n if (!svc) {\n return errResult(`ERR_API_UNKNOWN_SERVICE: ${input.service}`)\n }\n\n const allowedMethods = svc.allowedMethods ?? ALL_METHODS\n if (!allowedMethods.includes(input.method)) {\n return errResult(\n `ERR_API_METHOD_NOT_ALLOWED: ${input.method} not permitted for service ${svc.name}`,\n )\n }\n\n if (!pathAllowed(input.path, svc.allowedPaths)) {\n return errResult(`ERR_API_PATH_NOT_ALLOWED: ${input.path} for service ${svc.name}`)\n }\n\n let bodyText: string | undefined\n if (input.body !== undefined) {\n bodyText = JSON.stringify(input.body)\n const cap = svc.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES\n if (byteLength(bodyText) > cap) {\n return errResult(`ERR_API_BODY_TOO_LARGE: exceeds ${cap} bytes`)\n }\n }\n\n let authHeaders: Readonly<Record<string, string>>\n try {\n authHeaders = await resolveAuth({\n auth: svc.auth ?? { type: 'none' },\n env: opts.env,\n resolver: opts.resolveAuth,\n ctx: { serviceName: svc.name, method: input.method, path: input.path },\n })\n } catch (err) {\n // Truncate the error message aggressively — we don't know\n // what the resolver put in there. 200 chars is enough to\n // diagnose, short enough to reduce accidental-leak surface.\n const raw = err instanceof Error ? err.message : String(err)\n const truncated = raw.length > 200 ? raw.slice(0, 200) + '…' : raw\n return errResult(`ERR_API_RESOLVER_FAILED: ${truncated}`)\n }\n\n const userHeaders = sanitizeHeaders(input.headers ?? {}, authHeaders)\n\n const url = buildUrl(svc.baseUrl, input.path, input.query)\n\n await invokeHook(opts.onRequest, {\n service: svc.name,\n method: input.method,\n path: input.path,\n })\n\n const started = Date.now()\n let res: Response\n try {\n res = await fetchFn(url, {\n method: input.method,\n headers: {\n 'Content-Type': 'application/json',\n ...(svc.defaultHeaders ?? {}),\n ...userHeaders,\n ...authHeaders, // wins last — model cannot override\n },\n ...(bodyText !== undefined ? { body: bodyText } : {}),\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return errResult(`network error: ${msg}`)\n }\n\n const raw = await res.text()\n const content =\n raw.length > maxResponseBytes ? raw.slice(0, maxResponseBytes) + '\\n…[TRUNCATED]' : raw\n\n await invokeHook(opts.onResponse, {\n service: svc.name,\n method: input.method,\n path: input.path,\n status: res.status,\n latencyMs: Date.now() - started,\n bytesIn: raw.length,\n })\n\n return {\n content,\n isError: !res.ok,\n metadata: { status: res.status, service: svc.name },\n }\n },\n })\n}\n\n// ---------- helpers ----------\n\nfunction errResult(msg: string) {\n return { content: msg, isError: true as const }\n}\n\nfunction pathAllowed(path: string, allowed?: ReadonlyArray<string | RegExp>): boolean {\n if (!allowed || allowed.length === 0) return true\n for (const a of allowed) {\n if (typeof a === 'string') {\n if (path.startsWith(a)) return true\n } else if (a.test(path)) {\n return true\n }\n }\n return false\n}\n\nfunction byteLength(s: string): number {\n // TextEncoder is the only reliable way to count bytes across runtimes\n // (Buffer is Node-only, .length on a string counts UTF-16 code units).\n return new TextEncoder().encode(s).byteLength\n}\n\nfunction buildUrl(baseUrl: string, path: string, query?: Readonly<Record<string, string>>): string {\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl\n const url = new URL(base + path)\n for (const [k, v] of Object.entries(query ?? {})) {\n url.searchParams.set(k, v)\n }\n return url.toString()\n}\n\n/**\n * Case-insensitive sanitizer: drops any model-supplied header whose\n * canonical name collides with a resolved auth header. The model\n * cannot spoof `Authorization`, `X-API-Key`, or any custom auth\n * header the caller declared.\n */\nfunction sanitizeHeaders(\n user: Readonly<Record<string, string>>,\n auth: Readonly<Record<string, string>>,\n): Record<string, string> {\n const banned = new Set(Object.keys(auth).map((k) => k.toLowerCase()))\n const out: Record<string, string> = {}\n for (const [k, v] of Object.entries(user)) {\n if (banned.has(k.toLowerCase())) continue\n out[k] = v\n }\n return out\n}\n\nasync function resolveAuth(args: {\n auth: ApiAuthV1\n env: Readonly<Record<string, string>> | undefined\n resolver: ApiAuthResolverV1 | undefined\n ctx: ApiResolverCtxV1\n}): Promise<Readonly<Record<string, string>>> {\n const { auth, env, resolver, ctx } = args\n\n // Contract (Plan 020):\n // - Built-in auth types (bearer/header/basic/none) are always\n // resolved from `env` by the engine. Simple, predictable.\n // - `custom` is the extension point: the resolver handles it\n // and returns whatever headers are needed. If a user wants to\n // override bearer behavior (e.g., OAuth refresh), they declare\n // the auth as `custom` so the resolver owns it.\n //\n // This split keeps simple cases one-liners while leaving the\n // escape hatch fully general.\n switch (auth.type) {\n case 'none':\n return {}\n case 'bearer': {\n const token = envLookup(env, auth.tokenRef)\n return { Authorization: `Bearer ${token}` }\n }\n case 'header': {\n const value = envLookup(env, auth.valueRef)\n return { [auth.name]: value }\n }\n case 'basic': {\n const u = envLookup(env, auth.userRef)\n const p = envLookup(env, auth.passRef)\n return { Authorization: `Basic ${base64(`${u}:${p}`)}` }\n }\n case 'custom':\n if (resolver === undefined) {\n // Already validated at construction time; defensive fallback.\n throw new Error(`custom auth id \"${auth.id}\" requires resolveAuth`)\n }\n return resolver(auth, ctx)\n }\n}\n\nfunction envLookup(env: Readonly<Record<string, string>> | undefined, ref: string): string {\n if (env === undefined || env[ref] === undefined) {\n throw new Error(`ERR_API_ENV_MISSING: ${ref}`)\n }\n return env[ref]\n}\n\nfunction base64(input: string): string {\n // Prefer globalThis.btoa (browser/Workers); fall back to Buffer\n // (Node). Both exist in the runtimes we support.\n if (typeof globalThis.btoa === 'function') {\n return globalThis.btoa(input)\n }\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n return Buffer.from(input, 'utf8').toString('base64')\n}\n\nasync function invokeHook<E>(\n hook: ((e: E) => void | Promise<void>) | undefined,\n event: E,\n): Promise<void> {\n if (hook === undefined) return\n try {\n await hook(event)\n } catch {\n // Hook failures are non-fatal — telemetry must never break a run.\n }\n}\n","/**\n * SearchKnowledge — built-in tool (Plan 023 §4).\n *\n * Loads the indexes for the run's selected knowledge folders and\n * scores their sections against the model's query by token\n * overlap. Also scores any per-run external link descriptions.\n * Returns the top-K matches as short snippets the model can then\n * follow up on with `ReadKnowledge`.\n *\n * Per-call behaviour:\n * 1. Resolve the effective folder list + external links\n * (per-run override on `RunOptions.knowledge` is the only\n * source — engine-level config carries thresholds, not paths).\n * 2. For each unique base in the folder list: load\n * `{base}/_index.json` from the knowledge adapter (cached on\n * a Map held by the tool factory's closure for this run).\n * 3. Filter sections by sub-path.\n * 4. Score sections + external descriptions, return top-K.\n *\n * Per-agent isolation: each agent gets its own factory instance\n * with its own cache + folder list. Subagents can't search past\n * their parent's scope (engine wires this up).\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\nimport { buildKnowledgeIndex } from '../knowledge/indexer.js'\nimport { parseFolderRef, relPathInScope, type ScopedFolder } from '../knowledge/scope.js'\nimport { scoreOverlap, tokenize } from '../knowledge/tokenize.js'\nimport type {\n KnowledgeExternalLinkV1,\n KnowledgeIndexV1,\n SectionEntryV1,\n} from '../knowledge/types.js'\n\nexport interface CreateSearchKnowledgeToolOptions {\n /** Knowledge-side storage adapter (rooted at the tenant's `knowledge/` folder). */\n readonly adapter: StorageAdapter\n /** Folder paths the model is allowed to search this run. */\n readonly folders: readonly string[]\n /** External links the model can search by description. */\n readonly external: readonly KnowledgeExternalLinkV1[]\n /** Default + max top-K; defaults to 5 when omitted. */\n readonly maxSearchResults?: number\n}\n\nconst DEFAULT_MAX_RESULTS = 5\n\nconst inputSchema = z.object({\n query: z.string().min(1),\n maxResults: z.number().int().positive().optional(),\n})\n\nexport function createSearchKnowledgeTool(opts: CreateSearchKnowledgeToolOptions): Tool {\n const scoped = opts.folders.map(parseFolderRef)\n const indexCache = new Map<string, KnowledgeIndexV1>()\n const cap = opts.maxSearchResults ?? DEFAULT_MAX_RESULTS\n\n // Closed-over external link list — not read by the model\n const externals = opts.external\n\n return defineTool({\n name: 'SearchKnowledge',\n description:\n \"Search the agent's knowledge base. Returns up to K ranked snippets \" +\n 'matching the query (across all configured knowledge folders + any ' +\n 'attached external file links). Each result carries a `ref` you can ' +\n 'pass back to the `ReadKnowledge` tool to load the full content of ' +\n 'that section or file.',\n inputSchema,\n execute: async ({ query, maxResults }) => {\n const limit = Math.min(maxResults ?? cap, cap)\n const queryTokens = tokenize(query)\n if (queryTokens.length === 0) {\n return { content: 'no searchable tokens in query', isError: false }\n }\n\n // ── Index hits ──\n const sectionHits: Array<{ section: SectionEntryV1; base: string; score: number }> = []\n const seenBases = new Set<string>()\n for (const folder of scoped) {\n if (!seenBases.has(folder.base)) {\n seenBases.add(folder.base)\n }\n }\n for (const baseName of seenBases) {\n const idx = await loadIndex(opts.adapter, baseName, indexCache)\n if (idx === null) continue\n for (const section of idx.sections) {\n // Section qualifies if it falls under at least one of the\n // requested folders that share this base.\n const eligible = scoped.some(\n (f) => f.base === baseName && relPathInScope(f, section.relPath),\n )\n if (!eligible) continue\n const score = scoreOverlap(section.words, queryTokens)\n if (score > 0) sectionHits.push({ section, base: baseName, score })\n }\n }\n\n // ── External link hits ──\n const externalHits: Array<{ link: KnowledgeExternalLinkV1; score: number }> = []\n for (const link of externals) {\n const score = scoreOverlap(tokenize(link.description), queryTokens)\n if (score > 0) externalHits.push({ link, score })\n }\n\n const all = [\n ...sectionHits.map((h) => ({\n kind: 'knowledge' as const,\n score: h.score,\n render: () =>\n `[knowledge] ${h.base}/${h.section.relPath} §\"${h.section.heading || '(lead-in)'}\"\\n` +\n ` ${truncatePreview(h.section.preview)}\\n` +\n ` ref: ${h.base}/${h.section.slug}`,\n })),\n ...externalHits.map((h) => ({\n kind: 'external' as const,\n score: h.score,\n render: () =>\n `[external] ${h.link.name} (${h.link.format})\\n` +\n ` ${h.link.description}\\n` +\n ` ref: ext:${h.link.name}`,\n })),\n ]\n\n if (all.length === 0) {\n return { content: `no knowledge matches for \"${query}\"`, isError: false }\n }\n\n all.sort((a, b) => b.score - a.score)\n const top = all.slice(0, limit)\n const body = top.map((h, i) => `${i + 1}. ${h.render()}`).join('\\n\\n')\n return {\n content:\n `Found ${top.length} knowledge match${top.length === 1 ? '' : 'es'} ` +\n `(of ${all.length} ranked):\\n\\n${body}`,\n isError: false,\n metadata: { hits: all.length, returned: top.length },\n }\n },\n })\n}\n\nfunction truncatePreview(s: string): string {\n if (s.length <= 200) return s\n return s.slice(0, 200) + '…'\n}\n\n/**\n * Resolve a base's index. Order:\n * 1. Per-run cache hit\n * 2. `{base}/_index.json` on the adapter (fast path — pre-built)\n * 3. **Fallback**: build the index in memory by walking the base\n * and tokenising every file. Slower on first call but caches\n * for the rest of the run, so repeat queries cost nothing.\n *\n * Returns null only when the base genuinely has no readable files\n * (folder doesn't exist / empty) — i.e., even the build path would\n * find nothing. A corrupted `_index.json` falls through to the\n * build path; agents see real results instead of a misleading\n * \"no matches\".\n */\nasync function loadIndex(\n adapter: StorageAdapter,\n base: string,\n cache: Map<string, KnowledgeIndexV1>,\n): Promise<KnowledgeIndexV1 | null> {\n const cached = cache.get(base)\n if (cached !== undefined) return cached\n\n // Fast path — pre-built index file\n let raw: string | null = null\n try {\n raw = await adapter.readFile(`${base}/_index.json`)\n } catch {\n raw = null\n }\n if (raw !== null) {\n try {\n const parsed = JSON.parse(raw) as KnowledgeIndexV1\n cache.set(base, parsed)\n return parsed\n } catch {\n // Corrupted index — fall through to build path rather than\n // silently returning \"no matches\".\n }\n }\n\n // Fallback — build in-memory. Read-only: never writes _index.json.\n try {\n const built = await buildKnowledgeIndex({ adapter, base })\n cache.set(base, built)\n return built\n } catch {\n return null\n }\n}\n\n/** Re-export scope helper for direct use in folder validation tests. */\nexport type { ScopedFolder }\n","/**\n * Knowledge index builder (Plan 023 §3).\n *\n * Walks a single base folder under `{workspace}/knowledge/`, splits\n * every markdown file at heading boundaries, tokenizes each section,\n * and writes `{base}/_index.json`.\n *\n * Pure with respect to the storage adapter — works identically on\n * local filesystem, R2, or R2 binding. Designed to be called by\n * SaaS authors at upload time (when files change), not by the engine\n * at runtime.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { tokenize } from './tokenize.js'\nimport type { FileMetaV1, KnowledgeFormatV1, KnowledgeIndexV1, SectionEntryV1 } from './types.js'\n\nconst HEADING_RE = /^(#{1,6})[ \\t]+(.+?)\\s*$/\nconst WIKI_LINK_RE = /\\[\\[([^\\]|#]+)(?:[#|][^\\]]*)?\\]\\]/g\n\nconst FORMAT_BY_EXT: Record<string, KnowledgeFormatV1> = {\n md: 'md',\n markdown: 'md',\n txt: 'txt',\n json: 'json',\n csv: 'csv',\n html: 'html',\n htm: 'html',\n pdf: 'pdf',\n docx: 'docx',\n}\n\nconst PREVIEW_CHARS = 200\n\nexport interface BuildKnowledgeIndexOptions {\n /** Knowledge-side storage adapter (rooted at `workspaces/{wid}/knowledge/`). */\n readonly adapter: StorageAdapter\n /** Base folder name under the knowledge root, e.g. `'sales-playbook'`. */\n readonly base: string\n /** Override the timestamp written into the index (for deterministic tests). */\n readonly nowIso?: string\n}\n\nexport async function buildKnowledgeIndex(\n options: BuildKnowledgeIndexOptions,\n): Promise<KnowledgeIndexV1> {\n const { adapter, base } = options\n const safeBase = base.replace(/^\\/+|\\/+$/g, '')\n if (safeBase.length === 0 || safeBase.includes('..')) {\n throw new Error(`buildKnowledgeIndex: invalid base \"${base}\"`)\n }\n\n const files = await listFilesRecursive(adapter, safeBase)\n // relPath is relative to the base root\n const sections: SectionEntryV1[] = []\n const filesMeta: Record<string, FileMetaV1> = {}\n\n for (const fileRel of files) {\n if (fileRel === '_index.json') continue // skip our own output if present\n const fullPath = `${safeBase}/${fileRel}`\n const ext = (fileRel.split('.').pop() ?? '').toLowerCase()\n const format = FORMAT_BY_EXT[ext]\n if (format === undefined) continue // unknown format — skip silently\n\n const raw = await adapter.readFile(fullPath)\n if (raw === null) continue\n\n const sizeBytes = byteLength(raw)\n const meta: FileMetaV1 = { format, size: sizeBytes }\n\n if (format === 'md' || format === 'txt') {\n const fileSections = splitSections(raw, fileRel)\n sections.push(...fileSections)\n const wikiLinks = extractWikiLinks(raw)\n if (wikiLinks.length > 0) (meta as { wikiLinks?: readonly string[] }).wikiLinks = wikiLinks\n }\n\n filesMeta[fileRel] = meta\n }\n\n return {\n schema: 'v1' as const,\n base: safeBase,\n builtAt: options.nowIso ?? new Date().toISOString(),\n fileCount: Object.keys(filesMeta).length,\n sections,\n files: filesMeta,\n }\n}\n\n/**\n * Build the index AND write `_index.json` into the base folder.\n * Returns the index that was written.\n */\nexport async function writeKnowledgeIndex(\n options: BuildKnowledgeIndexOptions,\n): Promise<KnowledgeIndexV1> {\n const index = await buildKnowledgeIndex(options)\n await options.adapter.writeFile(`${index.base}/_index.json`, JSON.stringify(index, null, 2))\n return index\n}\n\n// ────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────\n\nasync function listFilesRecursive(adapter: StorageAdapter, dir: string): Promise<string[]> {\n // Returns paths relative to `dir`. Walks subfolders.\n const out: string[] = []\n const stack: string[] = ['']\n while (stack.length > 0) {\n const sub = stack.pop()!\n const fullDir = sub === '' ? dir : `${dir}/${sub}`\n let entries: string[] = []\n try {\n entries = await adapter.listDir(fullDir)\n } catch {\n continue\n }\n for (const name of entries) {\n const childRel = sub === '' ? name : `${sub}/${name}`\n const childFull = `${dir}/${childRel}`\n const isDir = await adapter.isDirectory(childFull).catch(() => false)\n if (isDir) {\n stack.push(childRel)\n } else {\n out.push(childRel)\n }\n }\n }\n return out.sort()\n}\n\nfunction splitSections(content: string, relPath: string): SectionEntryV1[] {\n const lines = content.split(/\\r?\\n/)\n const out: SectionEntryV1[] = []\n\n // First, find every heading line + its position\n type HeadingMark = { line: number; depth: number; heading: string }\n const heads: HeadingMark[] = []\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const m = HEADING_RE.exec(line)\n if (m) heads.push({ line: i + 1, depth: m[1]!.length, heading: m[2]!.trim() })\n }\n\n // Lead-in section before first heading, if any non-empty content there\n const leadInEndLine = heads.length > 0 ? heads[0]!.line - 1 : lines.length\n const leadInBody = lines.slice(0, leadInEndLine).join('\\n').trim()\n if (leadInBody.length > 0) {\n out.push({\n relPath,\n heading: '',\n slug: `${relPath}#`,\n depth: 0,\n words: tokenize(leadInBody),\n preview: makePreview(leadInBody),\n startLine: 1,\n endLine: leadInEndLine,\n })\n }\n\n // One entry per heading; section spans heading line through line\n // BEFORE the next heading (or end of file).\n for (let i = 0; i < heads.length; i++) {\n const h = heads[i]!\n const startLine = h.line\n const endLine = i + 1 < heads.length ? heads[i + 1]!.line - 1 : lines.length\n const body = lines.slice(startLine - 1, endLine).join('\\n')\n out.push({\n relPath,\n heading: h.heading,\n slug: `${relPath}#${slugify(h.heading)}`,\n depth: h.depth,\n words: tokenize(body),\n preview: makePreview(body),\n startLine,\n endLine,\n })\n }\n\n return out\n}\n\nfunction makePreview(body: string): string {\n // Strip the heading line if present (first line) for a cleaner preview\n const trimmed = body.replace(/^#{1,6}\\s+.+$\\r?\\n?/m, '').trim()\n if (trimmed.length <= PREVIEW_CHARS) return trimmed\n return trimmed.slice(0, PREVIEW_CHARS) + '…'\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n}\n\nfunction extractWikiLinks(text: string): string[] {\n const seen = new Set<string>()\n let m: RegExpExecArray | null\n WIKI_LINK_RE.lastIndex = 0\n while ((m = WIKI_LINK_RE.exec(text)) !== null) {\n const target = m[1]!.trim()\n if (target.length > 0) seen.add(target)\n }\n return [...seen].sort()\n}\n\nfunction byteLength(s: string): number {\n return new TextEncoder().encode(s).byteLength\n}\n","/**\n * Shared tokenizer for the knowledge subsystem (Plan 023).\n *\n * Both the indexer (`indexer.ts`) and SearchKnowledge use this\n * function so query tokens align with section tokens. ANY change\n * here must keep both ends consistent.\n */\n\nconst STOP_WORDS = new Set([\n 'the',\n 'and',\n 'of',\n 'to',\n 'a',\n 'in',\n 'is',\n 'it',\n 'you',\n 'that',\n 'was',\n 'for',\n 'on',\n 'are',\n 'with',\n 'as',\n 'this',\n 'by',\n 'from',\n 'or',\n 'but',\n 'not',\n 'all',\n 'an',\n 'has',\n 'have',\n 'had',\n 'will',\n 'can',\n 'do',\n 'did',\n 'be',\n 'been',\n 'being',\n 'your',\n 'our',\n 'their',\n 'his',\n 'her',\n 'my',\n 'we',\n 'they',\n 'them',\n 'than',\n 'so',\n 'if',\n 'at',\n 'no',\n 'yes',\n 'me',\n 'us',\n 'i',\n 'he',\n 'she',\n])\n\n/**\n * Lowercase, split on non-word characters, drop tokens shorter\n * than 2 chars, drop stop-words, dedupe (preserves first occurrence).\n *\n * Returns a deterministic, sorted list so two equivalent inputs\n * always yield the same array (helpful for snapshot tests).\n */\nexport function tokenize(text: string): string[] {\n if (typeof text !== 'string' || text.length === 0) return []\n const seen = new Set<string>()\n for (const raw of text.toLowerCase().split(/[\\W_]+/)) {\n if (raw.length < 2) continue\n if (STOP_WORDS.has(raw)) continue\n seen.add(raw)\n }\n return [...seen].sort()\n}\n\n/**\n * Score a section's word set against a query's token set.\n * Returns the count of query tokens that appear in the section.\n * Higher = better match. Used by SearchKnowledge.\n */\nexport function scoreOverlap(\n sectionWords: ReadonlyArray<string> | ReadonlySet<string>,\n queryTokens: ReadonlyArray<string>,\n): number {\n const set = sectionWords instanceof Set ? sectionWords : new Set(sectionWords)\n let n = 0\n for (const t of queryTokens) if (set.has(t)) n++\n return n\n}\n","/**\n * Path-safety + scope resolution helpers shared by SearchKnowledge\n * and ReadKnowledge.\n *\n * Centralised so all path validation runs through one place;\n * unit-tested separately so changes here can't silently weaken\n * the tenant boundary.\n */\n\nconst SAFE_PATH_RE = /^[a-zA-Z0-9_\\-./]+$/\n\nexport interface ScopedFolder {\n /** The folder path the user requested, normalized (no leading/trailing `/`). */\n readonly path: string\n /** The owning base — first path segment. */\n readonly base: string\n /** Sub-path within the base, or '' if the request IS the base root. */\n readonly subPath: string\n}\n\n/**\n * Validate a per-run folder request. Rejects:\n * - Empty / `..` / leading `/` / unsafe chars (whitespace, anything\n * outside `[a-zA-Z0-9_\\-./]`).\n *\n * Returns the normalized folder + its decomposed base + subPath.\n */\nexport function parseFolderRef(raw: string): ScopedFolder {\n if (typeof raw !== 'string' || raw.length === 0) {\n throw new Error(`invalid knowledge folder ref: empty`)\n }\n if (raw.startsWith('/')) {\n throw new Error(`invalid knowledge folder ref: absolute paths not allowed (\"${raw}\")`)\n }\n const trimmed = raw.replace(/\\/+$/g, '')\n if (trimmed.length === 0) {\n throw new Error(`invalid knowledge folder ref: \"${raw}\"`)\n }\n if (!SAFE_PATH_RE.test(trimmed)) {\n throw new Error(`invalid knowledge folder ref: unsafe characters in \"${raw}\"`)\n }\n if (trimmed.split('/').some((seg) => seg === '..' || seg === '.' || seg === '')) {\n throw new Error(`invalid knowledge folder ref: traversal in \"${raw}\"`)\n }\n const segs = trimmed.split('/')\n const base = segs[0]!\n const subPath = segs.slice(1).join('/')\n return { path: trimmed, base, subPath }\n}\n\n/**\n * Validate that a `relPath` from the index is allowed under the\n * requested folder. `relPath` is relative to the base root.\n */\nexport function relPathInScope(folder: ScopedFolder, relPath: string): boolean {\n if (folder.subPath === '') return true\n // relPath must start with subPath + '/' (or equal subPath for files\n // that ARE the sub-path itself, though sections always have a file\n // suffix so this is essentially the prefix-with-separator case).\n return relPath === folder.subPath || relPath.startsWith(`${folder.subPath}/`)\n}\n\n/**\n * Validate a ref the model passed to ReadKnowledge.\n *\n * - `ext:{name}` → external link (validated separately)\n * - `{base/path/to/file.ext}#{slug}` → section ref\n * - `{base/path/to/file.ext}` → whole-file ref\n *\n * Same character class + traversal rejection as parseFolderRef.\n */\nexport interface ParsedKnowledgeRef {\n readonly kind: 'ext' | 'section' | 'file'\n /** External: name; section/file: full file path under knowledge root. */\n readonly target: string\n /** Section anchor (slug after `#`) — present only for `kind === 'section'`. */\n readonly section?: string\n}\n\nexport function parseKnowledgeRef(raw: string): ParsedKnowledgeRef {\n if (typeof raw !== 'string' || raw.length === 0) {\n throw new Error('invalid knowledge ref: empty')\n }\n if (raw.startsWith('ext:')) {\n const name = raw.slice('ext:'.length)\n if (!/^[a-zA-Z0-9_-]+$/.test(name) || name.length === 0) {\n throw new Error(`invalid knowledge ref: external name \"${name}\" has unsafe characters`)\n }\n return { kind: 'ext', target: name }\n }\n if (raw.startsWith('/')) {\n throw new Error(`invalid knowledge ref: absolute paths not allowed (\"${raw}\")`)\n }\n // Split into [filePath]#[section]\n const hashAt = raw.indexOf('#')\n const filePath = hashAt === -1 ? raw : raw.slice(0, hashAt)\n const section = hashAt === -1 ? undefined : raw.slice(hashAt + 1)\n if (!SAFE_PATH_RE.test(filePath)) {\n throw new Error(`invalid knowledge ref: unsafe characters in \"${filePath}\"`)\n }\n if (filePath.split('/').some((seg) => seg === '..' || seg === '.' || seg === '')) {\n throw new Error(`invalid knowledge ref: traversal in \"${filePath}\"`)\n }\n if (section !== undefined) {\n if (section.length > 0 && !/^[a-zA-Z0-9_-]+$/.test(section)) {\n throw new Error(`invalid knowledge ref: unsafe characters in section \"${section}\"`)\n }\n return { kind: 'section', target: filePath, section }\n }\n return { kind: 'file', target: filePath }\n}\n\n/**\n * Check that a parsed file ref is within at least one of the\n * scoped folders. Used by ReadKnowledge.\n */\nexport function refInScope(folders: ReadonlyArray<ScopedFolder>, filePath: string): boolean {\n return folders.some((f) => {\n if (filePath === f.base || filePath.startsWith(`${f.base}/`)) {\n const relInBase = filePath === f.base ? '' : filePath.slice(f.base.length + 1)\n return relPathInScope(f, relInBase)\n }\n return false\n })\n}\n","/**\n * ReadKnowledge — built-in tool (Plan 023 §5).\n *\n * Resolves a `ref` to its content. Three cases:\n * - `ext:{name}` → fetch the registered external link's URL,\n * run format extraction, return text\n * - `{base}/{path}.ext#{slug}` → load the owning base's index,\n * find the section, slice the lines from the file\n * - `{base}/{path}.ext` → whole-file read + format extraction\n *\n * All paths run through `parseKnowledgeRef` + `refInScope` for\n * safety. Per-agent isolation: each agent's tool instance is bound\n * to its own folder list + index cache.\n */\n\nimport { z } from 'zod'\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { defineTool, type Tool } from './contract.js'\nimport { getExtractor } from '../knowledge/extractors.js'\nimport { buildKnowledgeIndex } from '../knowledge/indexer.js'\nimport {\n parseFolderRef,\n parseKnowledgeRef,\n refInScope,\n type ScopedFolder,\n} from '../knowledge/scope.js'\nimport type {\n KnowledgeExternalLinkV1,\n KnowledgeFormatV1,\n KnowledgeIndexV1,\n} from '../knowledge/types.js'\n\nexport interface CreateReadKnowledgeToolOptions {\n /** Knowledge-side adapter rooted at `workspaces/{wid}/knowledge/`. */\n readonly adapter: StorageAdapter\n readonly folders: readonly string[]\n readonly external: readonly KnowledgeExternalLinkV1[]\n readonly maxReadBytes?: number\n /** Override fetch (Workers / tests). Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch\n}\n\nconst DEFAULT_MAX_READ_BYTES = 10_000\n\nconst inputSchema = z.object({\n ref: z.string().min(1),\n})\n\nexport function createReadKnowledgeTool(opts: CreateReadKnowledgeToolOptions): Tool {\n const scoped = opts.folders.map(parseFolderRef)\n const indexCache = new Map<string, KnowledgeIndexV1>()\n const fileCache = new Map<string, string>()\n const cap = opts.maxReadBytes ?? DEFAULT_MAX_READ_BYTES\n const externalsByName = new Map(opts.external.map((e) => [e.name, e]))\n const fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis)\n\n return defineTool({\n name: 'ReadKnowledge',\n description:\n 'Load the full content of a knowledge ref returned by SearchKnowledge. ' +\n 'Use the `ref` value verbatim from the search results — section refs ' +\n 'return one section, file refs return the whole file (with format-specific ' +\n 'extraction for non-markdown formats), and `ext:{name}` refs fetch a ' +\n 'pre-registered external file.',\n inputSchema,\n execute: async ({ ref }) => {\n let parsed\n try {\n parsed = parseKnowledgeRef(ref)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_REF_INVALID: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n\n if (parsed.kind === 'ext') {\n return readExternal(parsed.target, externalsByName, fetchFn, cap)\n }\n\n // file or section ref — must be in scope\n if (!refInScope(scoped, parsed.target)) {\n return {\n content: `ERR_KNOWLEDGE_FOLDER_NOT_ALLOWED: ref \"${parsed.target}\" is outside the run's allowed folders`,\n isError: true,\n }\n }\n\n // Identify the owning base\n const base = parsed.target.split('/')[0]!\n const relPath = parsed.target.slice(base.length + 1)\n\n // For section refs: load the index, look up the section.\n // `loadIndex` falls back to an in-memory build when no\n // `_index.json` exists, so a null here means the base is\n // genuinely empty / unreadable, not just unindexed.\n if (parsed.kind === 'section') {\n const idx = await loadIndex(opts.adapter, base, indexCache)\n if (idx === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: base \"${base}\" has no readable files`,\n isError: true,\n }\n }\n const sectionSlug = parsed.section ?? ''\n const section = idx.sections.find(\n (s) => s.relPath === relPath && extractAnchor(s.slug) === sectionSlug,\n )\n if (section === undefined) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: section ${parsed.target}#${sectionSlug} not in index for \"${base}\"`,\n isError: true,\n }\n }\n const fullContent = await readFile(opts.adapter, parsed.target, fileCache)\n if (fullContent === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: file ${parsed.target} not found in storage`,\n isError: true,\n }\n }\n const sliced = sliceLines(fullContent, section.startLine, section.endLine)\n return wrapResult(`[knowledge] ${parsed.target}#${sectionSlug}`, sliced, cap)\n }\n\n // file ref → whole file + format extraction\n const fmt = inferFormat(parsed.target)\n if (fmt === null) {\n return {\n content: `ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: cannot infer format for \"${parsed.target}\"`,\n isError: true,\n }\n }\n const raw = await readFile(opts.adapter, parsed.target, fileCache)\n if (raw === null) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: file ${parsed.target} not found in storage`,\n isError: true,\n }\n }\n let extracted: string\n try {\n extracted = await getExtractor(fmt).extract(raw)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_EXTRACTOR_FAILED: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n }\n }\n return wrapResult(`[knowledge] ${parsed.target} (${fmt})`, extracted, cap)\n },\n })\n}\n\n// ────────────────────────────────────────────────────────────────\n// Helpers\n// ────────────────────────────────────────────────────────────────\n\nasync function readExternal(\n name: string,\n registry: Map<string, KnowledgeExternalLinkV1>,\n fetchFn: typeof globalThis.fetch,\n cap: number,\n) {\n const link = registry.get(name)\n if (link === undefined) {\n return {\n content: `ERR_KNOWLEDGE_REF_NOT_FOUND: no external link named \"${name}\"`,\n isError: true as const,\n }\n }\n let res\n try {\n res = await fetchFn(link.url, {\n headers: (link.headers ?? {}) as Record<string, string>,\n })\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n return {\n content: `ERR_KNOWLEDGE_NETWORK: ${msg.slice(0, 200)}`,\n isError: true as const,\n }\n }\n if (!res.ok) {\n return {\n content: `ERR_KNOWLEDGE_NETWORK: HTTP ${res.status} fetching ext:${name}`,\n isError: true as const,\n }\n }\n const raw = await res.text()\n let extracted: string\n try {\n extracted = await getExtractor(link.format).extract(raw)\n } catch (err) {\n return {\n content: `ERR_KNOWLEDGE_EXTRACTOR_FAILED: ${err instanceof Error ? err.message : String(err)}`,\n isError: true as const,\n }\n }\n return wrapResult(`[external] ${name} (${link.format})`, extracted, cap)\n}\n\nfunction wrapResult(header: string, body: string, cap: number) {\n // Truncate at cap to keep tool_results bounded; offload (Plan 021)\n // takes over for the actual context-relief tier above this.\n let payload = body\n if (body.length > cap) {\n payload = body.slice(0, cap) + `\\n…[+${body.length - cap} more chars truncated]`\n }\n return {\n content: `${header}\\n\\n${payload}`,\n isError: false as const,\n metadata: { bytes: body.length },\n }\n}\n\n/**\n * Same fallback policy as SearchKnowledge.loadIndex — see that\n * helper's docstring. Pre-built `_index.json` is the fast path;\n * absent or corrupted index falls through to an in-memory build.\n * Section refs against unindexed bases now succeed instead of\n * returning ERR_KNOWLEDGE_INDEX_MISSING.\n */\nasync function loadIndex(\n adapter: StorageAdapter,\n base: string,\n cache: Map<string, KnowledgeIndexV1>,\n): Promise<KnowledgeIndexV1 | null> {\n const cached = cache.get(base)\n if (cached !== undefined) return cached\n\n let raw: string | null = null\n try {\n raw = await adapter.readFile(`${base}/_index.json`)\n } catch {\n raw = null\n }\n if (raw !== null) {\n try {\n const idx = JSON.parse(raw) as KnowledgeIndexV1\n cache.set(base, idx)\n return idx\n } catch {\n // Corrupted — fall through to build\n }\n }\n\n try {\n const built = await buildKnowledgeIndex({ adapter, base })\n cache.set(base, built)\n return built\n } catch {\n return null\n }\n}\n\nasync function readFile(\n adapter: StorageAdapter,\n path: string,\n cache: Map<string, string>,\n): Promise<string | null> {\n const cached = cache.get(path)\n if (cached !== undefined) return cached\n const content = await adapter.readFile(path).catch(() => null)\n if (content === null) return null\n cache.set(path, content)\n return content\n}\n\nfunction sliceLines(content: string, start: number, end: number): string {\n const lines = content.split(/\\r?\\n/)\n return lines.slice(start - 1, end).join('\\n')\n}\n\nfunction extractAnchor(slug: string): string {\n const i = slug.indexOf('#')\n return i === -1 ? '' : slug.slice(i + 1)\n}\n\nfunction inferFormat(filePath: string): KnowledgeFormatV1 | null {\n const ext = (filePath.split('.').pop() ?? '').toLowerCase()\n switch (ext) {\n case 'md':\n case 'markdown':\n return 'md'\n case 'txt':\n return 'txt'\n case 'json':\n return 'json'\n case 'csv':\n return 'csv'\n case 'html':\n case 'htm':\n return 'html'\n case 'pdf':\n return 'pdf'\n case 'docx':\n return 'docx'\n }\n return null\n}\n\nexport type { ScopedFolder }\n","/**\n * Format extractors for the knowledge subsystem (Plan 023 §5).\n *\n * Each extractor turns raw bytes (or a UTF-8 string) into the text\n * the model will see. Native formats are pure functions; pdf and\n * docx lazily import optional deps and are flagged `requiresNode`\n * (Plan 019's capability stub fires on Workers).\n */\n\nimport type { KnowledgeFormatV1 } from './types.js'\n\nexport interface KnowledgeExtractorV1 {\n readonly format: KnowledgeFormatV1\n /** True if this extractor uses `node:`-only deps (PDF, DOCX). */\n readonly requiresNode: boolean\n extract(raw: string): Promise<string>\n}\n\nconst CSV_MAX_ROWS = 100\nconst HTML_TAG_RE = /<[^>]+>/g\nconst HTML_ENTITIES: Record<string, string> = {\n '&amp;': '&',\n '&lt;': '<',\n '&gt;': '>',\n '&quot;': '\"',\n '&#39;': \"'\",\n '&nbsp;': ' ',\n}\n\nfunction decodeHtmlEntities(s: string): string {\n return s.replace(/&(amp|lt|gt|quot|#39|nbsp);/g, (m) => HTML_ENTITIES[m] ?? m)\n}\n\nconst text: KnowledgeExtractorV1 = {\n format: 'txt',\n requiresNode: false,\n extract: async (raw) => raw,\n}\n\nconst md: KnowledgeExtractorV1 = {\n format: 'md',\n requiresNode: false,\n extract: async (raw) => raw,\n}\n\nconst json: KnowledgeExtractorV1 = {\n format: 'json',\n requiresNode: false,\n extract: async (raw) => {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2)\n } catch {\n return raw // fall back to raw text on parse failure\n }\n },\n}\n\nconst csv: KnowledgeExtractorV1 = {\n format: 'csv',\n requiresNode: false,\n extract: async (raw) => {\n const lines = raw.split(/\\r?\\n/).filter((l) => l.length > 0)\n if (lines.length === 0) return ''\n if (lines.length <= CSV_MAX_ROWS + 1) return lines.join('\\n')\n const head = lines.slice(0, CSV_MAX_ROWS + 1) // header + first N rows\n const remaining = lines.length - head.length\n return `${head.join('\\n')}\\n…[${remaining.toLocaleString()} more row${remaining === 1 ? '' : 's'} truncated]`\n },\n}\n\nconst html: KnowledgeExtractorV1 = {\n format: 'html',\n requiresNode: false,\n extract: async (raw) => {\n // Strip <script> and <style> bodies, then strip tags.\n const stripped = raw\n .replace(/<script\\b[^>]*>[\\s\\S]*?<\\/script>/gi, '')\n .replace(/<style\\b[^>]*>[\\s\\S]*?<\\/style>/gi, '')\n .replace(HTML_TAG_RE, ' ')\n return decodeHtmlEntities(stripped).replace(/\\s+/g, ' ').trim()\n },\n}\n\nconst pdf: KnowledgeExtractorV1 = {\n format: 'pdf',\n requiresNode: true,\n extract: async (raw) => {\n let pdfParse: unknown\n try {\n // pdf-parse exposes either a CJS-style default export or a\n // namespace whose default IS the parser; access via `any` to\n // tolerate either shape (the package's d.ts shape varies by\n // version).\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const mod: any = await import('pdf-parse')\n pdfParse = (mod.default ?? mod) as unknown\n } catch {\n throw new Error(\n 'ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: pdf-parse is not installed. ' +\n 'Run `npm install pdf-parse` to enable PDF extraction.',\n )\n }\n const buf = Buffer.from(raw, 'binary')\n const result = await (pdfParse as (b: Buffer) => Promise<{ text: string }>)(buf)\n return result.text\n },\n}\n\nconst docx: KnowledgeExtractorV1 = {\n format: 'docx',\n requiresNode: true,\n extract: async (raw) => {\n let mammoth: unknown\n try {\n // mammoth has no @types package; access via dynamic any so the\n // optional dep can stay un-installed without tripping tsc.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n mammoth = await import('mammoth' as any)\n } catch {\n throw new Error(\n 'ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: mammoth is not installed. ' +\n 'Run `npm install mammoth` to enable DOCX extraction.',\n )\n }\n const buf = Buffer.from(raw, 'binary')\n const result = await (\n mammoth as { extractRawText: (opts: { buffer: Buffer }) => Promise<{ value: string }> }\n ).extractRawText({ buffer: buf })\n return result.value\n },\n}\n\nconst EXTRACTORS: Record<KnowledgeFormatV1, KnowledgeExtractorV1> = {\n md,\n txt: text,\n json,\n csv,\n html,\n pdf,\n docx,\n}\n\nexport function getExtractor(format: KnowledgeFormatV1): KnowledgeExtractorV1 {\n const e = EXTRACTORS[format]\n if (e === undefined) throw new Error(`ERR_KNOWLEDGE_FORMAT_UNSUPPORTED: ${format}`)\n return e\n}\n","/**\n * StorageSkillSource — the default `SkillSource`.\n *\n * Reads `SKILL.md` files (and optional `pages/*.md`) from the\n * workspace storage adapter. Empty/missing `baseDir` → `list()`\n * returns `[]` (equivalent to \"no skills configured\"). `autoload:\n * false` at the config layer is handled upstream — this source does\n * not read that flag.\n *\n * Plan 022: the previous workspace-then-global fallback lookup was\n * removed along with the global scope. The workspace IS the tenant\n * root; no cross-tenant merging.\n */\n\nimport { loadSkills } from './loader.js'\nimport type { EngineStorage, StorageAdapter } from '../storage/interface.js'\nimport type { ResolvedSkill, SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\n\nexport interface StorageSkillSourceOptions {\n readonly storage: EngineStorage\n /** Directory under the workspace adapter root. Default: `'skills'`. */\n readonly baseDir?: string\n}\n\nexport class StorageSkillSource implements SkillSource {\n private readonly storage: EngineStorage\n private readonly baseDir: string\n\n constructor(options: StorageSkillSourceOptions) {\n this.storage = options.storage\n this.baseDir = options.baseDir ?? 'skills'\n }\n\n async list(): Promise<ReadonlyArray<ResolvedSkill>> {\n const loaded = await loadSkills(this.storage.workspace, this.baseDir)\n return loaded.map((s) => ({\n name: s.name,\n description: s.description,\n hasPages: s.hasPages,\n }))\n }\n\n async getSkillFile(skill: string): Promise<string | null> {\n if (!SAFE_NAME.test(skill)) return null\n return this.findFile(skill, 'SKILL.md')\n }\n\n async getPage(skill: string, page: string): Promise<string | null> {\n if (!SAFE_NAME.test(skill)) return null\n if (!SAFE_NAME.test(page)) return null\n return this.findFile(skill, `pages/${page}.md`)\n }\n\n async listPages(skill: string): Promise<ReadonlyArray<string>> {\n if (!SAFE_NAME.test(skill)) return []\n return this.listPagesIn(this.storage.workspace, skill)\n }\n\n private async listPagesIn(\n adapter: StorageAdapter,\n skill: string,\n ): Promise<ReadonlyArray<string>> {\n const pagesDir = `${this.baseDir}/${skill}/pages`\n try {\n const entries = await adapter.listDir(pagesDir)\n return entries\n .filter((f) => f.endsWith('.md'))\n .map((f) => f.replace(/\\.md$/, ''))\n .sort()\n } catch {\n return []\n }\n }\n\n private async findFile(skill: string, relative: string): Promise<string | null> {\n const path = `${this.baseDir}/${skill}/${relative}`\n return this.readIfExists(this.storage.workspace, path)\n }\n\n private async readIfExists(adapter: StorageAdapter, path: string): Promise<string | null> {\n try {\n return await adapter.readFile(path)\n } catch {\n return null\n }\n }\n}\n","/**\n * InlineSkillSource — the per-run override `SkillSource`.\n *\n * Takes a list of `SkillOverride` records and resolves bodies from\n * inline `body` (fast path, no network) or `url` (HTTPS fetch on\n * demand, cached per instance). Designed for Cloudflare Workers —\n * zero `node:*` imports, plain `fetch`.\n *\n * Security:\n * - Optional `allowedHosts` gate. When set, URL fetches outside the\n * allowlist throw before making the request. When unset (default),\n * any URL is allowed — fine for local dev, risky for production.\n * - `timeoutMs` aborts stuck fetches (default: 15s).\n *\n * Caching:\n * - Bodies (main + each page) are memoized within the instance, so\n * repeated `SkillPage` calls within one run never refetch.\n * - No cross-run cache. Each run constructs a fresh InlineSkillSource.\n */\n\nimport { ConfigError } from '../engine/errors.js'\nimport type { ResolvedSkill, SkillOverride, SkillPageOverride, SkillSource } from './source.js'\n\nconst SAFE_NAME = /^[a-zA-Z0-9_-]+$/\nconst DEFAULT_TIMEOUT_MS = 15_000\n\nexport interface InlineSkillSourceOptions {\n /** Fetch implementation. Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch\n /**\n * Host allowlist for URL fetches. When empty/undefined, any URL is\n * allowed. When set, each URL's host must exactly match an entry or\n * be a subdomain of one (`api.example.com` matches `example.com`).\n */\n readonly allowedHosts?: ReadonlyArray<string>\n /** Per-request fetch timeout. Default 15_000 ms. */\n readonly timeoutMs?: number\n}\n\nexport class InlineSkillSource implements SkillSource {\n private readonly byName = new Map<string, SkillOverride>()\n private readonly cache = new Map<string, string>()\n private readonly fetchImpl: typeof globalThis.fetch\n private readonly allowedHosts: ReadonlyArray<string> | undefined\n private readonly timeoutMs: number\n\n constructor(overrides: ReadonlyArray<SkillOverride>, options: InlineSkillSourceOptions = {}) {\n for (const override of overrides) {\n if (!SAFE_NAME.test(override.name)) {\n throw new ConfigError(\n `InlineSkillSource: invalid skill name \"${override.name}\". Must match [A-Za-z0-9_-]+`,\n )\n }\n if (override.pages !== undefined) {\n for (const pageName of Object.keys(override.pages)) {\n if (!SAFE_NAME.test(pageName)) {\n throw new ConfigError(\n `InlineSkillSource: invalid page name \"${pageName}\" in skill \"${override.name}\"`,\n )\n }\n }\n }\n if (this.byName.has(override.name)) {\n // Duplicate — last wins, matching disk behavior where a\n // later-loaded file would overwrite an earlier one.\n if (typeof console !== 'undefined') {\n console.warn(\n `[la-machina/engine] duplicate skill override \"${override.name}\" — later entry wins`,\n )\n }\n }\n this.byName.set(override.name, override)\n }\n this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis)\n this.allowedHosts = options.allowedHosts\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n }\n\n async list(): Promise<ReadonlyArray<ResolvedSkill>> {\n return Array.from(this.byName.values()).map((s) => ({\n name: s.name,\n description: s.description,\n hasPages: s.pages !== undefined && Object.keys(s.pages).length > 0,\n }))\n }\n\n async getSkillFile(skill: string): Promise<string | null> {\n const entry = this.byName.get(skill)\n if (entry === undefined) return null\n return this.resolve(`skill:${skill}`, entry.body, entry.url, entry.headers)\n }\n\n async getPage(skill: string, page: string): Promise<string | null> {\n const entry = this.byName.get(skill)\n if (entry === undefined) return null\n const pageEntry: SkillPageOverride | undefined = entry.pages?.[page]\n if (pageEntry === undefined) return null\n return this.resolve(`page:${skill}/${page}`, pageEntry.body, pageEntry.url, entry.headers)\n }\n\n async listPages(skill: string): Promise<ReadonlyArray<string>> {\n const entry = this.byName.get(skill)\n if (entry === undefined || entry.pages === undefined) return []\n return Object.keys(entry.pages).sort()\n }\n\n private async resolve(\n cacheKey: string,\n inline: string | undefined,\n url: string | undefined,\n headers: Readonly<Record<string, string>> | undefined,\n ): Promise<string | null> {\n if (inline !== undefined) return inline\n if (url === undefined) return null\n\n const cached = this.cache.get(cacheKey)\n if (cached !== undefined) return cached\n\n this.assertUrlAllowed(url)\n\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), this.timeoutMs)\n let response: Response\n try {\n response = await this.fetchImpl(url, {\n method: 'GET',\n ...(headers !== undefined ? { headers } : {}),\n signal: controller.signal,\n })\n } finally {\n clearTimeout(timer)\n }\n\n if (!response.ok) {\n throw new Error(\n `InlineSkillSource: fetch ${url} → HTTP ${String(response.status)} ${response.statusText}`,\n )\n }\n const text = await response.text()\n this.cache.set(cacheKey, text)\n return text\n }\n\n private assertUrlAllowed(url: string): void {\n const hosts = this.allowedHosts\n if (hosts === undefined || hosts.length === 0) return\n let host: string\n try {\n host = new URL(url).host\n } catch {\n throw new Error(`InlineSkillSource: malformed URL \"${url}\"`)\n }\n const ok = hosts.some((h) => host === h || host.endsWith(`.${h}`))\n if (!ok) {\n throw new Error(`InlineSkillSource: host \"${host}\" not in allowedHosts [${hosts.join(', ')}]`)\n }\n }\n}\n","/**\n * Storage factory — turns a `ResolvedStorageConfig` into an\n * `EngineStorage` bundle with a single workspace-scoped adapter.\n *\n * Unlike La-Machina's original factory (which read `process.env`\n * directly), this version takes a fully-resolved config object as its\n * only input. Env resolution is the caller's responsibility (done\n * inside `initEngine()`). Keeping the factory pure makes it\n * trivially testable.\n *\n * Path layout (identical on local + r2 + r2-binding):\n *\n * {rootPath}/\n * └── workspaces/\n * └── {workspaceId}/\n * └── .claude/ ← tenant root\n * ├── memory/…\n * ├── projects/{runId}/nodes/{nodeId}/…\n * └── skills/…\n *\n * The `workspaces/` segment is a namespace guard (keeps engine data\n * separated from anything else in a shared bucket/filesystem); the\n * `.claude/` segment is a convention marker — \"engine-owned data,\n * don't touch.\" Both cost one directory level and pay off.\n *\n * Plan 022 removed the previous `global` scope (rooted at\n * `{rootPath}/.claude/`). Cross-tenant data sharing isn't a feature\n * real deployments want; the workspace IS the tenant boundary.\n */\n\nimport type { ResolvedStorageConfig } from '../config/types.js'\nimport type { EngineStorage } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { LocalStorageAdapter } from './localAdapter.js'\nimport { R2StorageAdapter } from './r2Adapter.js'\nimport { R2BindingStorageAdapter } from './r2BindingAdapter.js'\n\n/** The subfolder used for all engine data inside a workspace. */\nconst ENGINE_DATA_FOLDER = '.claude'\n\n/** The subfolder name that holds one folder per workspace (tenant). */\nconst WORKSPACES_FOLDER = 'workspaces'\n\n/**\n * The user-owned knowledge folder (Plan 023). Sibling to `.claude/`,\n * NOT inside it — clean separation between engine-managed state\n * and user-authored content.\n */\nconst KNOWLEDGE_FOLDER = 'knowledge'\n\nexport interface CreateEngineStorageOptions {\n /**\n * When true, builds a second `StorageAdapter` rooted at\n * `{rootPath}/workspaces/{workspaceId}/knowledge/` and exposes\n * it on `EngineStorage.knowledge`. Plan 023.\n */\n readonly withKnowledge?: boolean\n}\n\nexport async function createEngineStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions = {},\n): Promise<EngineStorage> {\n switch (config.provider) {\n case 'local':\n return createLocalStorage(config, options)\n case 'r2':\n return createR2Storage(config, options)\n case 'r2-binding':\n return createR2BindingStorage(config, options)\n }\n}\n\nasync function createLocalStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): Promise<EngineStorage> {\n // Lazy path import — only needed for local provider (Node.js only)\n const path = await import('node:path')\n const tenantRoot = path.join(config.rootPath, WORKSPACES_FOLDER, config.workspaceId)\n const workspaceRoot = path.join(tenantRoot, ENGINE_DATA_FOLDER)\n const out: EngineStorage = { workspace: new LocalStorageAdapter(workspaceRoot) }\n if (options.withKnowledge) {\n const knowledgeRoot = path.join(tenantRoot, KNOWLEDGE_FOLDER)\n return { ...out, knowledge: new LocalStorageAdapter(knowledgeRoot) }\n }\n return out\n}\n\nfunction createR2Storage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): EngineStorage {\n if (!config.r2) {\n throw new StorageError('storage.r2 is required when storage.provider === \"r2\"')\n }\n // Strip leading/trailing slashes so the prefix joins cleanly.\n const rootPrefix = config.rootPath.replace(/^\\/+|\\/+$/g, '')\n const tenantPrefix = `${rootPrefix}/${WORKSPACES_FOLDER}/${config.workspaceId}`\n const workspacePrefix = `${tenantPrefix}/${ENGINE_DATA_FOLDER}`\n const out: EngineStorage = { workspace: new R2StorageAdapter(config.r2, workspacePrefix) }\n if (options.withKnowledge) {\n const knowledgePrefix = `${tenantPrefix}/${KNOWLEDGE_FOLDER}`\n return { ...out, knowledge: new R2StorageAdapter(config.r2, knowledgePrefix) }\n }\n return out\n}\n\nfunction createR2BindingStorage(\n config: ResolvedStorageConfig,\n options: CreateEngineStorageOptions,\n): EngineStorage {\n if (!config.r2Binding) {\n throw new StorageError('storage.r2Binding is required when storage.provider === \"r2-binding\"')\n }\n const rootPrefix = config.rootPath.replace(/^\\/+|\\/+$/g, '')\n const tenantPrefix = `${rootPrefix}/${WORKSPACES_FOLDER}/${config.workspaceId}`\n const workspacePrefix = `${tenantPrefix}/${ENGINE_DATA_FOLDER}`\n const out: EngineStorage = {\n workspace: new R2BindingStorageAdapter(config.r2Binding, workspacePrefix),\n }\n if (options.withKnowledge) {\n const knowledgePrefix = `${tenantPrefix}/${KNOWLEDGE_FOLDER}`\n return {\n ...out,\n knowledge: new R2BindingStorageAdapter(config.r2Binding, knowledgePrefix),\n }\n }\n return out\n}\n","/**\n * StorageAdapter — abstract filesystem interface for la-machina-engine.\n *\n * All paths are relative to the adapter's root. The adapter enforces\n * path safety (no traversal, no absolute paths, no null bytes) and\n * provides a filesystem-shaped API that subsystems can use without\n * knowing whether the backend is local disk, R2, or any other\n * S3-compatible object store.\n *\n * Implementations ship in this package:\n * - `LocalStorageAdapter` (src/storage/localAdapter.ts) — fs-backed\n * - `R2StorageAdapter` (src/storage/r2Adapter.ts) — S3-compatible\n *\n * Users may supply custom adapters implementing this interface.\n */\n\nexport interface FileStat {\n readonly size: number\n readonly mtime: Date\n}\n\nexport interface StorageAdapter {\n /** Read a file as UTF-8 text. Returns null if file doesn't exist. */\n readFile(relativePath: string): Promise<string | null>\n\n /** Write a file atomically. Creates parent directories if needed. */\n writeFile(relativePath: string, content: string): Promise<void>\n\n /** Append to a file. Creates it if it doesn't exist. */\n appendFile(relativePath: string, content: string): Promise<void>\n\n /** Delete a file. No-op if it doesn't exist. */\n deleteFile(relativePath: string): Promise<void>\n\n /** Check if a file or directory exists. */\n exists(relativePath: string): Promise<boolean>\n\n /**\n * List entries in a directory. Returns just the names (not full paths).\n * Returns an empty array if the directory doesn't exist.\n */\n listDir(relativePath: string): Promise<string[]>\n\n /** Create a directory (recursive). No-op on S3-like backends. */\n mkdir(relativePath: string): Promise<void>\n\n /** Check if a path is a directory. */\n isDirectory(relativePath: string): Promise<boolean>\n\n /** Get file metadata. Returns null if file doesn't exist. */\n stat(relativePath: string): Promise<FileStat | null>\n}\n\n/**\n * Single-root storage model (Plan 022).\n *\n * - `workspace`: rooted at `{rootPath}/workspaces/{workspaceId}/.claude/`.\n * The workspace IS the tenant root — every memory, skill, run,\n * transcript, snapshot, and offloaded tool result for a tenant\n * lives under this path.\n *\n * The previous `global` scope (rooted at `{rootPath}/.claude/`) was\n * removed: cross-tenant data sharing isn't a feature real\n * deployments want — it's a security problem.\n */\nexport interface EngineStorage {\n readonly workspace: StorageAdapter\n /**\n * Optional knowledge-base adapter (Plan 023). Built by the\n * factory only when `config.knowledge?.enabled === true`.\n * Rooted at `{rootPath}/workspaces/{workspaceId}/knowledge/` —\n * a sibling of the workspace adapter's `.claude/` root.\n */\n readonly knowledge?: StorageAdapter\n}\n\n/**\n * Error thrown by all storage operations. `cause` is preserved as-is\n * (usually an `ErrnoException` or AWS SDK error) so callers can inspect\n * the underlying failure.\n */\nexport class StorageError extends Error {\n override readonly cause?: unknown\n\n constructor(message: string, cause?: unknown) {\n super(message)\n this.name = 'StorageError'\n if (cause !== undefined) this.cause = cause\n }\n}\n","/**\n * LocalStorageAdapter — filesystem-backed `StorageAdapter`.\n *\n * Ported from La-Machina's production implementation. Wraps Node\n * `fs/promises` with:\n *\n * - **Atomic writes** (temp file + rename pattern)\n * - **Path safety** via `validateRelativePath` — blocks traversal, absolute\n * paths, null bytes at every entrypoint\n * - **Null-on-missing semantics** — `readFile`/`stat` return `null` instead\n * of throwing `ENOENT`; `listDir` returns `[]` for missing directories\n * - **Recursive directory creation** on all write operations\n *\n * Errors from the underlying `fs` module are wrapped in `StorageError` with\n * the original error preserved as `.cause`.\n */\n\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\n// Lazy imports — `node:fs` and `node:path` are not available in\n// Cloudflare Workers. LocalStorageAdapter is only instantiated when\n// `storage.provider === 'local'` (Node.js only), but the top-level\n// import would crash Workers at module load time.\nlet _fs: typeof import('node:fs/promises') | null = null\nlet _path: typeof import('node:path') | null = null\nlet _existsSync: typeof import('node:fs').existsSync | null = null\n\nasync function getFs(): Promise<typeof import('node:fs/promises')> {\n if (_fs === null) _fs = await import('node:fs/promises')\n return _fs\n}\n\nasync function getPath(): Promise<typeof import('node:path')> {\n if (_path === null) _path = await import('node:path')\n return _path\n}\n\nasync function getExistsSync(): Promise<typeof import('node:fs').existsSync> {\n if (_existsSync === null) {\n const fsModule = await import('node:fs')\n _existsSync = fsModule.existsSync\n }\n return _existsSync\n}\n\nfunction errnoCode(err: unknown): string | undefined {\n return (err as { code?: string } | null)?.code\n}\n\nexport class LocalStorageAdapter implements StorageAdapter {\n private readonly root: string\n\n constructor(root: string) {\n if (typeof root !== 'string' || root.length === 0) {\n throw new StorageError('LocalStorageAdapter: root must be a non-empty string')\n }\n this.root = root\n }\n\n private async resolve(rel: string): Promise<string> {\n validateRelativePath(rel)\n const p = await getPath()\n return p.join(this.root, rel)\n }\n\n async readFile(rel: string): Promise<string | null> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n return await fs.readFile(full, 'utf-8')\n } catch (err) {\n const code = errnoCode(err)\n if (code === 'ENOENT' || code === 'EISDIR') return null\n throw new StorageError(`Failed to read file: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const [fs, p, full] = await Promise.all([getFs(), getPath(), this.resolve(rel)])\n try {\n await fs.mkdir(p.dirname(full), { recursive: true })\n const tmp = `${full}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`\n await fs.writeFile(tmp, content, 'utf-8')\n await fs.rename(tmp, full)\n } catch (err) {\n throw new StorageError(`Failed to write file: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n const [fs, p, full] = await Promise.all([getFs(), getPath(), this.resolve(rel)])\n try {\n await fs.mkdir(p.dirname(full), { recursive: true })\n await fs.appendFile(full, content, 'utf-8')\n } catch (err) {\n throw new StorageError(`Failed to append to file: ${rel}`, err)\n }\n }\n\n async deleteFile(rel: string): Promise<void> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.unlink(full)\n } catch (err) {\n if (errnoCode(err) === 'ENOENT') return\n throw new StorageError(`Failed to delete file: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.access(full)\n return true\n } catch {\n return false\n }\n }\n\n async listDir(rel: string): Promise<string[]> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n return await fs.readdir(full)\n } catch (err) {\n const code = errnoCode(err)\n if (code === 'ENOENT' || code === 'ENOTDIR') return []\n throw new StorageError(`Failed to list directory: ${rel}`, err)\n }\n }\n\n async mkdir(rel: string): Promise<void> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n await fs.mkdir(full, { recursive: true })\n } catch (err) {\n throw new StorageError(`Failed to create directory: ${rel}`, err)\n }\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n const s = await fs.stat(full)\n return s.isDirectory()\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const [fs, full] = await Promise.all([getFs(), this.resolve(rel)])\n try {\n const s = await fs.stat(full)\n return { size: s.size, mtime: s.mtime }\n } catch (err) {\n if (errnoCode(err) === 'ENOENT') return null\n throw new StorageError(`Failed to stat file: ${rel}`, err)\n }\n }\n\n getRoot(): string {\n return this.root\n }\n\n async rootExists(): Promise<boolean> {\n const existsSync = await getExistsSync()\n return existsSync(this.root)\n }\n}\n","/**\n * Path-safety validation for all StorageAdapter entrypoints.\n *\n * Every adapter method (read, write, delete, list, stat, exists, mkdir,\n * isDirectory, appendFile) calls `validateRelativePath(path)` as its first\n * step. This is the single gate that enforces:\n *\n * - paths are non-empty strings\n * - paths are relative (no leading `/` or `\\`)\n * - paths contain no `..` segments (no parent traversal)\n * - paths contain no null bytes (defensive against C-string injection)\n *\n * The adapter trusts nothing from the caller — config files, tool inputs,\n * subagent outputs, and caller-supplied paths all funnel through this.\n */\n\nimport { StorageError } from './interface.js'\n\nexport function validateRelativePath(path: unknown): asserts path is string {\n if (typeof path !== 'string') {\n throw new StorageError('Invalid path: must be a string')\n }\n // Empty string is allowed and means \"the adapter root\" — used by\n // recursive walkers and glob tools that need to start at the top.\n // For non-list operations the underlying fs will reject root reads\n // with a clear error (EISDIR for readFile, etc.).\n if (path.startsWith('/') || path.startsWith('\\\\')) {\n throw new StorageError(`Invalid path: absolute paths not allowed: ${path}`)\n }\n if (path.includes('..')) {\n throw new StorageError(`Invalid path: parent traversal (..) not allowed: ${path}`)\n }\n if (path.includes('\\0')) {\n throw new StorageError('Invalid path: null bytes not allowed')\n }\n}\n","/**\n * R2StorageAdapter — Cloudflare R2 (S3-compatible) implementation.\n *\n * Ported from La-Machina. Uses `@aws-sdk/client-s3` since R2 speaks the S3\n * protocol. Path semantics:\n *\n * - Files become objects keyed at `${rootPrefix}/${relativePath}`\n * - Directories are synthetic — S3 has no real directory concept. `mkdir`\n * is a no-op; `listDir` uses `Delimiter: '/'` to separate files from\n * \"subdirectories\" (common prefixes).\n * - `appendFile` is read-modify-write (S3 has no native append primitive).\n * OK for small files (JSONL episode logs); prohibitively expensive for\n * large files.\n * - `writeFile` is a single atomic PutObject — no temp+rename dance.\n *\n * The backing S3Client is constructed from config. Tests use\n * `aws-sdk-client-mock` to intercept `.send()` without needing DI.\n */\n\nimport {\n DeleteObjectCommand,\n GetObjectCommand,\n HeadObjectCommand,\n ListObjectsV2Command,\n PutObjectCommand,\n S3Client,\n} from '@aws-sdk/client-s3'\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\nexport interface R2ClientConfig {\n readonly bucket: string\n readonly region: string\n readonly accessKeyId: string\n readonly secretAccessKey: string\n readonly endpoint?: string | undefined\n}\n\nexport class R2StorageAdapter implements StorageAdapter {\n private readonly client: S3Client\n private readonly bucket: string\n private readonly rootPrefix: string\n\n constructor(config: R2ClientConfig, rootPrefix: string) {\n if (!config.bucket || !config.accessKeyId || !config.secretAccessKey) {\n throw new StorageError(\n 'R2StorageAdapter: bucket, accessKeyId, and secretAccessKey are all required',\n )\n }\n\n const clientConfig: ConstructorParameters<typeof S3Client>[0] = {\n region: config.region,\n credentials: {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n },\n forcePathStyle: true, // R2/MinIO compatibility\n }\n if (config.endpoint !== undefined) {\n clientConfig.endpoint = config.endpoint\n }\n\n this.client = new S3Client(clientConfig)\n this.bucket = config.bucket\n // Normalize prefix: no leading or trailing slashes\n this.rootPrefix = rootPrefix.replace(/^\\/+|\\/+$/g, '')\n }\n\n private key(rel: string): string {\n validateRelativePath(rel)\n const normalized = rel.replace(/^\\/+/, '')\n return this.rootPrefix ? `${this.rootPrefix}/${normalized}` : normalized\n }\n\n async readFile(rel: string): Promise<string | null> {\n const Key = this.key(rel)\n try {\n const resp = await this.client.send(new GetObjectCommand({ Bucket: this.bucket, Key }))\n if (!resp.Body) return null\n return await resp.Body.transformToString('utf-8')\n } catch (err) {\n if (isNotFound(err)) return null\n throw new StorageError(`Failed to read R2 object: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const Key = this.key(rel)\n try {\n await this.client.send(\n new PutObjectCommand({\n Bucket: this.bucket,\n Key,\n Body: content,\n ContentType: 'text/plain; charset=utf-8',\n }),\n )\n } catch (err) {\n throw new StorageError(`Failed to write R2 object: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n // S3/R2 has no native append — read-modify-write.\n const existing = await this.readFile(rel)\n const next = (existing ?? '') + content\n await this.writeFile(rel, next)\n }\n\n async deleteFile(rel: string): Promise<void> {\n const Key = this.key(rel)\n try {\n await this.client.send(new DeleteObjectCommand({ Bucket: this.bucket, Key }))\n } catch (err) {\n if (isNotFound(err)) return\n throw new StorageError(`Failed to delete R2 object: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const Key = this.key(rel)\n try {\n await this.client.send(new HeadObjectCommand({ Bucket: this.bucket, Key }))\n return true\n } catch (err) {\n if (isNotFound(err)) {\n // Could still be a synthetic directory — check by prefix\n return this.isDirectory(rel)\n }\n throw new StorageError(`Failed to check R2 object: ${rel}`, err)\n }\n }\n\n async listDir(rel: string): Promise<string[]> {\n const prefix = this.key(rel) + '/'\n const results: string[] = []\n let continuationToken: string | undefined\n\n try {\n do {\n const resp = await this.client.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n Delimiter: '/',\n ContinuationToken: continuationToken,\n }),\n )\n\n // Files directly under this prefix\n for (const obj of resp.Contents ?? []) {\n if (!obj.Key) continue\n const name = obj.Key.slice(prefix.length)\n if (name && !name.includes('/')) {\n results.push(name)\n }\n }\n\n // \"Subdirectories\" (common prefixes)\n for (const cp of resp.CommonPrefixes ?? []) {\n if (!cp.Prefix) continue\n const name = cp.Prefix.slice(prefix.length).replace(/\\/$/, '')\n if (name) results.push(name)\n }\n\n continuationToken = resp.IsTruncated ? resp.NextContinuationToken : undefined\n } while (continuationToken)\n\n return results\n } catch (err) {\n if (isNotFound(err)) return []\n throw new StorageError(`Failed to list R2 directory: ${rel}`, err)\n }\n }\n\n mkdir(rel: string): Promise<void> {\n // S3/R2 has no real directories — no-op. Directories are created\n // implicitly when files are written beneath them. But we still\n // validate the path so the contract with LocalStorageAdapter holds:\n // every method rejects traversal at its entrypoint. The validation\n // must be wrapped in a promise so sync throws become rejections.\n return Promise.resolve().then(() => validateRelativePath(rel))\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const prefix = this.key(rel) + '/'\n try {\n const resp = await this.client.send(\n new ListObjectsV2Command({\n Bucket: this.bucket,\n Prefix: prefix,\n MaxKeys: 1,\n }),\n )\n return (resp.KeyCount ?? 0) > 0\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const Key = this.key(rel)\n try {\n const resp = await this.client.send(new HeadObjectCommand({ Bucket: this.bucket, Key }))\n return {\n size: resp.ContentLength ?? 0,\n mtime: resp.LastModified ?? new Date(),\n }\n } catch (err) {\n if (isNotFound(err)) return null\n throw new StorageError(`Failed to stat R2 object: ${rel}`, err)\n }\n }\n}\n\n/**\n * S3 \"not found\" errors come in several shapes depending on the client\n * version and whether HEAD or GET was used.\n */\nfunction isNotFound(err: unknown): boolean {\n if (err === null || typeof err !== 'object') return false\n const e = err as {\n name?: unknown\n Code?: unknown\n $metadata?: { httpStatusCode?: unknown }\n }\n if (e.name === 'NoSuchKey' || e.name === 'NotFound') return true\n if (e.Code === 'NoSuchKey' || e.Code === 'NotFound') return true\n if (e.$metadata?.httpStatusCode === 404) return true\n return false\n}\n","/**\n * R2BindingStorageAdapter — Cloudflare Workers R2 binding (NOT S3 SDK).\n *\n * Unlike `R2StorageAdapter` which talks to R2 over the S3 REST protocol,\n * this adapter uses the native R2 binding exposed to Workers runtime:\n *\n * [[r2_buckets]]\n * binding = \"BUCKET\"\n * bucket_name = \"my-bucket\"\n *\n * // In code:\n * new R2BindingStorageAdapter(env.BUCKET, 'tenant/acme')\n *\n * Why use this over `R2StorageAdapter` on Workers?\n * - `@aws-sdk/client-s3` is heavy (~500 KB) and the Workers-compatibility\n * story for ListObjectsV2 XML parsing is brittle; CommonPrefixes come\n * back empty in some runtimes, silently breaking `listDir`.\n * - The R2 binding API (`bucket.list`, `bucket.get`, `bucket.put`,\n * `bucket.delete`) is native, typed, and uses native JSON responses.\n * - No AWS credentials, no endpoint URL — the binding handles auth.\n *\n * Use `R2StorageAdapter` on Node or anywhere you don't have a Workers\n * binding (local dev with Miniflare's S3 endpoint, backfills, etc).\n * Use this adapter inside Workers for reliability and bundle size.\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { FileStat, StorageAdapter } from './interface.js'\nimport { StorageError } from './interface.js'\nimport { validateRelativePath } from './pathSafety.js'\n\n// ---------- Minimal R2 binding types ----------\n// We don't depend on `@cloudflare/workers-types` here to keep this adapter\n// usable outside Workers (e.g., for testing with a mock). These match the\n// shape of the native R2Bucket interface.\n\ninterface R2Object {\n key: string\n size: number\n uploaded: Date\n httpMetadata?: R2HTTPMetadata\n customMetadata?: Record<string, string>\n}\n\ninterface R2ObjectBody extends R2Object {\n text(): Promise<string>\n arrayBuffer(): Promise<ArrayBuffer>\n blob?(): Promise<Blob>\n}\n\ninterface R2Objects {\n objects: R2Object[]\n truncated: boolean\n cursor?: string\n delimitedPrefixes?: string[]\n}\n\ninterface R2HTTPMetadata {\n contentType?: string\n contentLanguage?: string\n contentDisposition?: string\n contentEncoding?: string\n cacheControl?: string\n cacheExpiry?: Date\n}\n\ninterface R2ListOptions {\n prefix?: string\n delimiter?: string\n cursor?: string\n limit?: number\n include?: Array<'httpMetadata' | 'customMetadata'>\n}\n\ninterface R2PutOptions {\n httpMetadata?: R2HTTPMetadata\n customMetadata?: Record<string, string>\n}\n\n/**\n * Structural type for `env.BUCKET` — intentionally not imported from\n * `@cloudflare/workers-types` so this adapter has no extra peer deps.\n */\nexport interface R2BucketBinding {\n head(key: string): Promise<R2Object | null>\n get(key: string): Promise<R2ObjectBody | null>\n put(\n key: string,\n value: string | ArrayBuffer | ArrayBufferView | ReadableStream | Blob | null,\n options?: R2PutOptions,\n ): Promise<R2Object>\n delete(keys: string | string[]): Promise<void>\n list(options?: R2ListOptions): Promise<R2Objects>\n}\n\n// ---------- Adapter ----------\n\nexport class R2BindingStorageAdapter implements StorageAdapter {\n private readonly bucket: R2BucketBinding\n private readonly rootPrefix: string\n\n constructor(bucket: R2BucketBinding, rootPrefix: string) {\n if (bucket === undefined || bucket === null) {\n throw new StorageError(\n 'R2BindingStorageAdapter: bucket binding is required (pass env.BUCKET)',\n )\n }\n this.bucket = bucket\n // Normalize: no leading or trailing slashes\n this.rootPrefix = rootPrefix.replace(/^\\/+|\\/+$/g, '')\n }\n\n private key(rel: string): string {\n validateRelativePath(rel)\n const normalized = rel.replace(/^\\/+/, '')\n return this.rootPrefix ? `${this.rootPrefix}/${normalized}` : normalized\n }\n\n async readFile(rel: string): Promise<string | null> {\n const key = this.key(rel)\n try {\n const obj = await this.bucket.get(key)\n if (obj === null) return null\n return await obj.text()\n } catch (err) {\n throw new StorageError(`Failed to read R2 object: ${rel}`, err)\n }\n }\n\n async writeFile(rel: string, content: string): Promise<void> {\n const key = this.key(rel)\n try {\n await this.bucket.put(key, content, {\n httpMetadata: { contentType: 'text/plain; charset=utf-8' },\n })\n } catch (err) {\n throw new StorageError(`Failed to write R2 object: ${rel}`, err)\n }\n }\n\n async appendFile(rel: string, content: string): Promise<void> {\n // R2 has no native append — read-modify-write. This is O(size+len)\n // per append; fine for small JSONL files, expensive for big blobs.\n const existing = await this.readFile(rel)\n const next = (existing ?? '') + content\n await this.writeFile(rel, next)\n }\n\n async deleteFile(rel: string): Promise<void> {\n const key = this.key(rel)\n try {\n await this.bucket.delete(key)\n } catch (err) {\n throw new StorageError(`Failed to delete R2 object: ${rel}`, err)\n }\n }\n\n async exists(rel: string): Promise<boolean> {\n const key = this.key(rel)\n try {\n const head = await this.bucket.head(key)\n if (head !== null) return true\n } catch {\n /* fall through to directory check */\n }\n // Not a file — check if it's a \"directory\" (any object with this prefix)\n try {\n const listing = await this.bucket.list({ prefix: `${key}/`, limit: 1 })\n return listing.objects.length > 0 || (listing.delimitedPrefixes?.length ?? 0) > 0\n } catch {\n return false\n }\n }\n\n /**\n * List direct children of `rel` (files + subdirectory names). Returns\n * just the names (not full keys). Empty array if path doesn't exist.\n *\n * Uses the native R2 list API with `delimiter: '/'` which returns\n * `delimitedPrefixes` for \"subdirectories\" and `objects` for files —\n * equivalent to S3's CommonPrefixes + Contents but parsed by the\n * binding itself (no XML, no SDK).\n */\n async listDir(rel: string): Promise<string[]> {\n const prefix = this.key(rel) + '/'\n const results: string[] = []\n let cursor: string | undefined\n\n try {\n do {\n const listing = await this.bucket.list({\n prefix,\n delimiter: '/',\n ...(cursor !== undefined ? { cursor } : {}),\n })\n\n // Files directly under this prefix\n for (const obj of listing.objects) {\n const name = obj.key.slice(prefix.length)\n if (name && !name.includes('/')) {\n results.push(name)\n }\n }\n\n // \"Subdirectories\" — delimitedPrefixes come back as full paths\n // ending in '/'. Slice off the parent prefix and trailing slash.\n for (const dp of listing.delimitedPrefixes ?? []) {\n const name = dp.slice(prefix.length).replace(/\\/$/, '')\n if (name) results.push(name)\n }\n\n cursor = listing.truncated ? listing.cursor : undefined\n } while (cursor !== undefined)\n\n return results\n } catch (err) {\n throw new StorageError(`Failed to list R2 directory: ${rel}`, err)\n }\n }\n\n mkdir(rel: string): Promise<void> {\n // No-op — R2 has no directories. Validate path shape for parity with\n // other adapters so traversal attempts are rejected at the entrypoint.\n return Promise.resolve().then(() => validateRelativePath(rel))\n }\n\n async isDirectory(rel: string): Promise<boolean> {\n const prefix = this.key(rel) + '/'\n try {\n const listing = await this.bucket.list({ prefix, limit: 1 })\n return listing.objects.length > 0 || (listing.delimitedPrefixes?.length ?? 0) > 0\n } catch {\n return false\n }\n }\n\n async stat(rel: string): Promise<FileStat | null> {\n const key = this.key(rel)\n try {\n const head = await this.bucket.head(key)\n if (head === null) return null\n return { size: head.size, mtime: head.uploaded }\n } catch (err) {\n throw new StorageError(`Failed to stat R2 object: ${rel}`, err)\n }\n }\n}\n","/**\n * TranscriptReader — reconstructs a transcript from its sharded form.\n *\n * The reader locates shards in `{logPath}/`, sorts them numerically, and\n * streams the parsed `Entry` objects back in their original order. Two\n * strategies are used to enumerate shards:\n *\n * 1. **Meta-guided** (fast path): if `meta.json` exists, use its\n * `lastShardIndex + 1` as the shard count and read `000000.jsonl` …\n * `{lastShardIndex}.jsonl` in order.\n * 2. **Directory scan** (fallback): list the log directory and filter\n * entries matching `/^\\d{6}\\.jsonl$/`, sort by the numeric prefix.\n *\n * The second mode handles recovery scenarios where `meta.json` is missing\n * or corrupted, and also makes the reader robust against partial writes\n * during a crash (we still read whatever shards landed on disk).\n *\n * Corrupt lines raise an error that identifies the shard filename and\n * the 1-indexed line number, so callers can investigate.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport { parseEntryLine, type Entry } from './entries.js'\nimport { readMeta } from './meta.js'\n\nconst SHARD_PATTERN = /^(\\d{6})\\.jsonl$/\n\nexport class TranscriptReader {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logPath: string,\n ) {}\n\n /**\n * Async iterator over entries, streamed shard by shard. Use this when\n * the transcript might be large — it avoids materializing everything\n * into memory at once.\n */\n async *entries(): AsyncGenerator<Entry, void, void> {\n const shardNames = await this.discoverShards()\n for (const shardName of shardNames) {\n const key = `${this.logPath}/${shardName}`\n const content = await this.storage.readFile(key)\n if (content === null || content.length === 0) continue\n const lines = content.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]\n if (line === undefined || line.length === 0) continue\n try {\n yield parseEntryLine(line)\n } catch {\n // Corrupted line — skip with warning instead of crashing.\n // A single bad line should not block resume of the entire transcript.\n if (typeof console !== 'undefined') {\n console.warn(`TranscriptReader: skipping corrupted line in ${shardName}:${i + 1}`)\n }\n }\n }\n }\n }\n\n /** Collect every entry into an array. Convenient for small transcripts. */\n async readAll(): Promise<Entry[]> {\n const out: Entry[] = []\n for await (const e of this.entries()) out.push(e)\n return out\n }\n\n // ---------- shard discovery ----------\n\n private async discoverShards(): Promise<string[]> {\n // Fast path: if meta exists, we know exactly how many shards to read.\n const meta = await readMeta(this.storage, this.logPath)\n if (meta && meta.lastShardIndex !== null) {\n const names: string[] = []\n for (let i = 0; i <= meta.lastShardIndex; i++) {\n names.push(`${String(i).padStart(6, '0')}.jsonl`)\n }\n return names\n }\n\n // Fallback: scan the directory, filter, sort numerically.\n const all = await this.storage.listDir(this.logPath)\n const shards: Array<{ name: string; index: number }> = []\n for (const name of all) {\n const match = SHARD_PATTERN.exec(name)\n if (!match || match[1] === undefined) continue\n shards.push({ name, index: parseInt(match[1], 10) })\n }\n shards.sort((a, b) => a.index - b.index)\n return shards.map((s) => s.name)\n }\n}\n","/**\n * rehydrate — reconstruct an Anthropic Messages API conversation\n * (`MessageParam[]`) from a stream of `Entry` objects read from a\n * transcript on resume.\n *\n * The transcript is the source of truth for what happened during a\n * paused run. The snapshot only stores counters and pointers; the\n * messages themselves come from replaying the JSONL shards.\n *\n * Reconstruction rules:\n * - `user` entry → push as a user message with the original content blocks\n * - `assistant` entry → push as an assistant message with the original blocks\n * - `tool_result` entry → wrap in a user message with a `tool_result`\n * content block. If the previous message was already a tool-result-only\n * user message, append to it (matching the Anthropic API contract for\n * batched tool results in one turn).\n * - `meta` and `error` entries → not part of the conversation; skipped\n * - `subagent_spawn` and `subagent_done` → not part of the conversation\n * (the parent's transcript only stores the tool_use + tool_result;\n * the spawn/done entries are auxiliary metadata)\n */\n\nimport type {\n ContentBlockParam,\n MessageParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { Entry } from '../transcript/entries.js'\n\nexport function rebuildMessagesFromEntries(entries: ReadonlyArray<Entry>): MessageParam[] {\n const messages: MessageParam[] = []\n\n for (const entry of entries) {\n if (entry.type === 'user') {\n messages.push({\n role: 'user',\n content: entry.message.content as ContentBlockParam[],\n })\n } else if (entry.type === 'assistant') {\n messages.push({\n role: 'assistant',\n content: entry.message.content as ContentBlockParam[],\n })\n } else if (entry.type === 'tool_result') {\n const block: ToolResultBlockParam = {\n type: 'tool_result',\n tool_use_id: entry.toolUseId,\n content: typeof entry.content === 'string' ? entry.content : JSON.stringify(entry.content),\n ...(entry.isError === true ? { is_error: true } : {}),\n }\n const prev = messages[messages.length - 1]\n if (\n prev !== undefined &&\n prev.role === 'user' &&\n Array.isArray(prev.content) &&\n prev.content.every(\n (b) => typeof b === 'object' && (b as { type: string }).type === 'tool_result',\n )\n ) {\n prev.content.push(block)\n } else {\n messages.push({ role: 'user', content: [block] })\n }\n }\n // Other entry types (meta, error, subagent_*) are not replayed\n // into the conversation history.\n }\n\n return messages\n}\n","/**\n * EngineResponse — unified response shape for the public API.\n *\n * Every engine.run() and engine.resume() returns this single flat shape.\n * Internal code uses RunResult (the discriminated union); this module\n * converts it to the client-facing format.\n *\n * {\n * status: 'done' | 'paused' | 'failed',\n * data: any, // user-defined — text or JSON from outputSchema\n * meta: { ... }, // tokens, turns, timing, snapshot, transcript\n * errors: [], // structured error array\n * timestamp: number, // unix ms\n * }\n */\n\nimport type {\n RunResult,\n TokenUsage,\n RunSnapshot,\n PauseReason,\n TranscriptLocation,\n} from './types.js'\nimport type { EngineError } from './errors.js'\n\nexport interface ResponseError {\n readonly code: string\n readonly message: string\n readonly details?: unknown\n}\n\nexport interface ResponseMeta {\n readonly nodeId: string\n readonly turns?: number\n readonly tokensUsed?: TokenUsage\n readonly durationMs?: number\n readonly output?: string\n readonly snapshot?: RunSnapshot\n readonly pendingToolCall?: RunSnapshot['pendingToolCall']\n readonly pauseReason?: PauseReason\n readonly transcript?: TranscriptLocation\n /**\n * Plan 019 — names of tools whose capability-stub fired during this\n * run (deduped). Callers can detect \"this run ran against a runtime\n * that couldn't execute these tools\" and retry as async with a\n * runner configured. Absent when no stub fired.\n */\n readonly capabilitiesMissing?: readonly string[]\n /** Additional context-specific fields (e.g., activity, lastTool, cancelled). */\n readonly [key: string]: unknown\n}\n\nexport interface EngineResponse {\n /** Unique run identifier — client's primary handle. Use this for resume. */\n readonly runId: string\n readonly status: 'done' | 'paused' | 'failed' | 'queued' | 'running' | 'cancelled' | 'not_found'\n readonly data: unknown\n readonly meta: ResponseMeta\n readonly errors: readonly ResponseError[]\n readonly timestamp: number\n}\n\n/**\n * Convert internal RunResult to the unified EngineResponse shape.\n */\nexport function toResponse(\n result: RunResult,\n extra: {\n runId: string\n nodeId: string\n durationMs: number\n logPath?: string\n /** Plan 019 — capability-stub names observed during the run. */\n capabilitiesMissing?: readonly string[]\n },\n): EngineResponse {\n const timestamp = Date.now()\n const capsField =\n extra.capabilitiesMissing !== undefined && extra.capabilitiesMissing.length > 0\n ? { capabilitiesMissing: extra.capabilitiesMissing }\n : {}\n\n if (result.status === 'done') {\n return {\n runId: extra.runId,\n status: 'done',\n data: result.data !== undefined ? result.data : result.output,\n meta: {\n nodeId: extra.nodeId,\n turns: result.turns,\n tokensUsed: result.tokensUsed,\n durationMs: extra.durationMs,\n output: result.output,\n ...(extra.logPath !== undefined\n ? { transcript: { path: extra.logPath, lastShardIndex: 0 } }\n : {}),\n ...capsField,\n },\n errors: [],\n timestamp,\n }\n }\n\n if (result.status === 'paused') {\n return {\n runId: extra.runId,\n status: 'paused',\n data: extractPausedData(result.snapshot.pendingToolCall),\n meta: {\n nodeId: extra.nodeId,\n turns: result.snapshot.turnsUsed,\n tokensUsed: result.snapshot.tokensUsedSoFar,\n durationMs: extra.durationMs,\n snapshot: result.snapshot,\n ...(result.snapshot.pendingToolCall !== undefined\n ? { pendingToolCall: result.snapshot.pendingToolCall }\n : {}),\n pauseReason: result.reason,\n ...(extra.logPath !== undefined\n ? { transcript: { path: extra.logPath, lastShardIndex: result.snapshot.lastShardIndex } }\n : {}),\n ...capsField,\n },\n errors: [],\n timestamp,\n }\n }\n\n // failed\n const err = result.error\n return {\n runId: extra.runId,\n status: 'failed',\n data: null,\n meta: {\n nodeId: extra.nodeId,\n turns: 0,\n tokensUsed: { input: 0, output: 0 },\n durationMs: extra.durationMs,\n transcript: result.transcript,\n },\n errors: [\n {\n code: (err as EngineError).code ?? 'ERR_UNKNOWN',\n message: err.message,\n ...(err.cause !== undefined ? { details: err.cause } : {}),\n },\n ],\n timestamp,\n }\n}\n\n/**\n * Extract the user-facing data from a pending tool call.\n *\n * For Write/Edit tools, the client only cares about the content —\n * the path is internal engine detail (available in meta.pendingToolCall).\n * For other tools, return the full input.\n */\nfunction extractPausedData(pending?: RunSnapshot['pendingToolCall']): unknown {\n if (!pending) return null\n const input = pending.input as Record<string, unknown> | undefined\n if (!input) return null\n\n // Write tool: data = content (the text being written)\n if (pending.toolName === 'Write' && typeof input.content === 'string') {\n return input.content\n }\n\n // Edit tool: data = { old_string, new_string } (the change being made)\n if (pending.toolName === 'Edit' && input.old_string !== undefined) {\n return { old_string: input.old_string, new_string: input.new_string }\n }\n\n // Bash tool: data = command\n if (pending.toolName === 'Bash' && typeof input.command === 'string') {\n return input.command\n }\n\n // Everything else: return full input\n return input\n}\n","/**\n * RunState — durable per-run state stored in state.json.\n *\n * Lives alongside transcript shards and snapshot.json:\n * projects/{runId}/nodes/{nodeId}/state.json\n *\n * Enables:\n * - Async run tracking (getStatus, waitFor)\n * - Crash recovery (detect orphaned running runs via stale heartbeat)\n * - Webhook delivery history (retry tracking)\n * - Full response persistence (data + meta + errors) — getStatus returns\n * the same shape as sync engine.run()\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport type { StorageAdapter } from '../storage/interface.js'\nimport type { EngineResponse } from './response.js'\nimport type { TokenUsage } from './types.js'\n\n// ---------- types ----------\n\nexport type RunStatus = 'queued' | 'running' | 'paused' | 'done' | 'failed' | 'cancelled'\n\nexport interface RunProgress {\n readonly turns: number\n readonly tokensUsed: TokenUsage\n readonly currentActivity: 'idle' | 'streaming' | 'tool_dispatch' | 'compacting'\n readonly lastTool?: string\n}\n\nexport type WebhookEvent = 'paused' | 'done' | 'failed'\n\nexport interface WebhookDelivery {\n readonly id: string\n readonly event: WebhookEvent\n readonly attempt: number\n readonly scheduledAt: number\n readonly deliveredAt?: number\n readonly status: 'pending' | 'delivered' | 'failed'\n readonly httpCode?: number\n readonly error?: string\n}\n\nexport interface WebhookConfig {\n readonly url: string\n readonly events: readonly WebhookEvent[]\n readonly secret?: string\n readonly headers?: Readonly<Record<string, string>>\n readonly deliveries: readonly WebhookDelivery[]\n}\n\nexport interface RunState {\n readonly version: 1\n readonly runId: string\n readonly nodeId: string\n readonly status: RunStatus\n readonly startedAt: number\n readonly lastHeartbeat: number\n readonly progress: RunProgress\n readonly response: EngineResponse | null\n readonly webhook?: WebhookConfig\n}\n\n// ---------- manager ----------\n\n/**\n * Reads, writes, and updates state.json files via the storage adapter.\n * Concurrent writes are NOT synchronized — callers are responsible for\n * serializing updates (in practice: only one process writes per run).\n */\nexport class RunStateManager {\n constructor(private readonly storage: StorageAdapter) {}\n\n private path(runId: string, nodeId: string): string {\n return `projects/${runId}/nodes/${nodeId}/state.json`\n }\n\n async write(state: RunState): Promise<void> {\n const content = JSON.stringify(state, null, 2)\n await this.storage.writeFile(this.path(state.runId, state.nodeId), content)\n }\n\n async read(runId: string, nodeId: string): Promise<RunState | null> {\n try {\n const content = await this.storage.readFile(this.path(runId, nodeId))\n if (content === null) return null\n return JSON.parse(content) as RunState\n } catch {\n return null\n }\n }\n\n /**\n * Merge patch into current state and write back. Returns the new state.\n * If no state exists, throws — use `write()` for initial creation.\n */\n async update(runId: string, nodeId: string, patch: Partial<RunState>): Promise<RunState> {\n const current = await this.read(runId, nodeId)\n if (current === null) {\n throw new Error(`RunStateManager.update: no state found for ${runId}/${nodeId}`)\n }\n const next: RunState = { ...current, ...patch }\n await this.write(next)\n return next\n }\n\n /**\n * Update just the heartbeat + progress (cheap, called every turn).\n */\n async heartbeat(runId: string, nodeId: string, progress: Partial<RunProgress>): Promise<void> {\n const current = await this.read(runId, nodeId)\n if (current === null) return\n const next: RunState = {\n ...current,\n lastHeartbeat: Date.now(),\n progress: { ...current.progress, ...progress },\n }\n await this.write(next)\n }\n\n /**\n * Mark terminal state with response. Used at end of run/resume.\n */\n async finalize(runId: string, nodeId: string, response: EngineResponse): Promise<RunState> {\n return this.update(runId, nodeId, {\n status:\n response.status === 'done' ? 'done' : response.status === 'paused' ? 'paused' : 'failed',\n lastHeartbeat: Date.now(),\n response,\n })\n }\n\n /**\n * List all state files under a runId (one per node). Returns empty array\n * if the runId directory doesn't exist.\n */\n async scanRun(runId: string): Promise<RunState[]> {\n const nodesDir = `projects/${runId}/nodes`\n try {\n const nodeNames = await this.storage.listDir(nodesDir)\n const states: RunState[] = []\n for (const name of nodeNames) {\n const state = await this.read(runId, name)\n if (state !== null) states.push(state)\n }\n return states\n } catch {\n return []\n }\n }\n\n /**\n * Scan all state files and return those with stale heartbeats.\n * Used by recoverOrphanedRuns().\n */\n async findOrphaned(staleThresholdMs: number): Promise<RunState[]> {\n const projectsRoot = 'projects'\n const orphaned: RunState[] = []\n const now = Date.now()\n try {\n const runIds = await this.storage.listDir(projectsRoot)\n for (const runId of runIds) {\n const states = await this.scanRun(runId)\n for (const state of states) {\n if (state.status === 'running' && now - state.lastHeartbeat > staleThresholdMs) {\n orphaned.push(state)\n }\n }\n }\n } catch {\n // projects/ doesn't exist yet — no runs to recover\n }\n return orphaned\n }\n\n /** Helper to build a fresh state for a new run. */\n static initial(runId: string, nodeId: string, webhook?: WebhookConfig): RunState {\n const now = Date.now()\n return {\n version: 1,\n runId,\n nodeId,\n status: 'queued',\n startedAt: now,\n lastHeartbeat: now,\n progress: {\n turns: 0,\n tokensUsed: { input: 0, output: 0 },\n currentActivity: 'idle',\n },\n response: null,\n ...(webhook !== undefined ? { webhook } : {}),\n }\n }\n}\n","/**\n * BackgroundExecutor — abstracts how async runs are dispatched.\n *\n * Node.js: NodeBackgroundExecutor uses `void Promise` fire-and-forget.\n * Cloudflare Workers: user provides a DurableObjectExecutor (Worker-side\n * code that dispatches to a DO with a longer execution budget).\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\n/**\n * Contract for async run dispatch. Engine calls `schedule()` with a work\n * function; executor is responsible for running it eventually.\n */\nexport interface BackgroundExecutor {\n /**\n * Schedule a work function to run in the background. Must return\n * immediately — the function will be invoked asynchronously.\n *\n * The returned AbortSignal fires if `cancel(runId)` is called.\n * Work functions should pass this to agentLoop for early termination.\n */\n schedule(runId: string, work: (signal: AbortSignal) => Promise<void>): void\n\n /**\n * Cancel a scheduled/running execution. Fires the AbortSignal so the\n * work function can exit gracefully.\n */\n cancel(runId: string): Promise<void>\n\n /** True if this executor is currently tracking a run. */\n isActive(runId: string): boolean\n}\n\n/**\n * Default Node.js implementation — fire-and-forget via `void` Promise.\n * Works in Node, Bun, Deno. Does NOT work on Cloudflare Workers because\n * the Worker instance terminates when the request handler returns.\n */\nexport class NodeBackgroundExecutor implements BackgroundExecutor {\n private readonly running = new Map<string, AbortController>()\n\n schedule(runId: string, work: (signal: AbortSignal) => Promise<void>): void {\n if (this.running.has(runId)) {\n // Already running — abort the old one before starting a new\n this.running.get(runId)!.abort()\n }\n const ctl = new AbortController()\n this.running.set(runId, ctl)\n\n void work(ctl.signal)\n .catch((err) => {\n // Background errors are logged via state.json updates in the engine.\n // Last-resort: log to stderr so it's not completely silent.\n if (typeof console !== 'undefined') {\n console.error(`[la-machina/engine] Background run ${runId} threw:`, err)\n }\n })\n .finally(() => {\n this.running.delete(runId)\n })\n }\n\n async cancel(runId: string): Promise<void> {\n const ctl = this.running.get(runId)\n if (ctl !== undefined) {\n ctl.abort()\n this.running.delete(runId)\n }\n }\n\n isActive(runId: string): boolean {\n return this.running.has(runId)\n }\n\n /** For tests/observability — current count of running tasks. */\n size(): number {\n return this.running.size\n }\n}\n","/**\n * WebhookDispatcher — delivers status changes to client URLs.\n *\n * Features:\n * - HMAC-SHA256 signing via Web Crypto API (works everywhere)\n * - Exponential backoff retries: 10s → 60s → 5min → 30min → give up\n * - HTTP 4xx → no retry (client bug); 5xx/network → retry\n * - HTTP 410 Gone → give up immediately (resource deliberately removed)\n * - Delivery tracking: each attempt recorded in state.json\n *\n * All pure JS — no `node:` imports, Workers-compatible.\n */\n\nimport { randomUUID } from '../runtime/uuid.js'\nimport type { EngineResponse } from './response.js'\nimport type { WebhookDelivery, WebhookEvent } from './state.js'\n\n// ---------- retry schedule ----------\n\n/** Milliseconds to wait before attempt N (1-indexed). */\nexport const RETRY_DELAYS_MS = [\n 0, // attempt 1: immediate\n 10_000, // attempt 2: 10s after failure\n 60_000, // attempt 3: 60s after failure\n 5 * 60_000, // attempt 4: 5min after failure\n 30 * 60_000, // attempt 5: 30min after failure\n] as const\n\nexport const MAX_ATTEMPTS = RETRY_DELAYS_MS.length\n\n// ---------- HMAC signing ----------\n\n/**\n * Sign a webhook payload with HMAC-SHA256 using Web Crypto API.\n * Returns the full header value: `sha256=<hex>`.\n */\nexport async function signPayload(\n secret: string,\n timestamp: number,\n body: string,\n): Promise<string> {\n const data = `${timestamp}.${body}`\n const key = await globalThis.crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n const sig = await globalThis.crypto.subtle.sign('HMAC', key, new TextEncoder().encode(data))\n const hex = Array.from(new Uint8Array(sig))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return `sha256=${hex}`\n}\n\n// ---------- retryability ----------\n\nfunction isRetryableHttpStatus(code: number): boolean {\n if (code === 410) return false // Gone — give up permanently\n if (code >= 500 && code < 600) return true // 5xx server errors\n if (code === 408) return true // Request Timeout\n if (code === 429) return true // Rate limited\n // Other 4xx → no retry (client bug in payload/auth)\n return false\n}\n\n// ---------- dispatcher ----------\n\nexport interface DeliverOptions {\n readonly url: string\n readonly event: WebhookEvent\n readonly payload: EngineResponse\n readonly secret?: string\n readonly headers?: Readonly<Record<string, string>>\n readonly attempt?: number\n readonly deliveryId?: string\n readonly timeoutMs?: number\n readonly fetch?: typeof globalThis.fetch\n}\n\nexport interface DeliverResult {\n readonly delivery: WebhookDelivery\n readonly shouldRetry: boolean\n readonly nextRetryDelayMs?: number\n}\n\nexport class WebhookDispatcher {\n constructor(\n private readonly fetchImpl: typeof globalThis.fetch = globalThis.fetch.bind(globalThis),\n ) {}\n\n /**\n * Attempt one delivery. Returns a delivery record and whether to retry.\n */\n async deliver(options: DeliverOptions): Promise<DeliverResult> {\n const attempt = options.attempt ?? 1\n const deliveryId = options.deliveryId ?? randomUUID()\n const scheduledAt = Date.now()\n const timestamp = scheduledAt\n const body = JSON.stringify(options.payload)\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-LaMachina-Event': `status.${options.event}`,\n 'X-LaMachina-RunId': options.payload.runId,\n 'X-LaMachina-Delivery': deliveryId,\n 'X-LaMachina-Timestamp': String(timestamp),\n ...(options.headers ?? {}),\n }\n\n if (options.secret !== undefined && options.secret.length > 0) {\n headers['X-LaMachina-Signature'] = await signPayload(options.secret, timestamp, body)\n }\n\n const controller = new AbortController()\n const timeout = options.timeoutMs ?? 30_000\n const timer = setTimeout(() => controller.abort(), timeout)\n\n const fetchImpl = options.fetch ?? this.fetchImpl\n\n try {\n const response = await fetchImpl(options.url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n })\n\n const delivery: WebhookDelivery = {\n id: deliveryId,\n event: options.event,\n attempt,\n scheduledAt,\n deliveredAt: Date.now(),\n status: response.ok ? 'delivered' : 'failed',\n httpCode: response.status,\n ...(response.ok ? {} : { error: `HTTP ${response.status}` }),\n }\n\n if (response.ok) {\n return { delivery, shouldRetry: false }\n }\n\n const shouldRetry = attempt < MAX_ATTEMPTS && isRetryableHttpStatus(response.status)\n return {\n delivery,\n shouldRetry,\n ...(shouldRetry ? { nextRetryDelayMs: RETRY_DELAYS_MS[attempt] ?? 0 } : {}),\n }\n } catch (err) {\n // Network error, timeout, etc. — retry if attempts remain.\n const errorMsg = err instanceof Error ? err.message : String(err)\n const delivery: WebhookDelivery = {\n id: deliveryId,\n event: options.event,\n attempt,\n scheduledAt,\n deliveredAt: Date.now(),\n status: 'failed',\n error: errorMsg,\n }\n const shouldRetry = attempt < MAX_ATTEMPTS\n return {\n delivery,\n shouldRetry,\n ...(shouldRetry ? { nextRetryDelayMs: RETRY_DELAYS_MS[attempt] ?? 0 } : {}),\n }\n } finally {\n clearTimeout(timer)\n }\n }\n}\n"],"mappings":"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","names":["z","path","z","json","text","runAgent","path","failed","z","z","z","text","path","text","text","inputSchema","text","isSubagentPausedError","z","z","createFetchDataTool","inputSchema","z","spawn","result","t","z","inputSchema","z","inputSchema","z","inputSchema","path","z","inputSchema","path","base64","z","inputSchema","path","z","inputSchema","z","picomatch","z","inputSchema","z","picomatch","z","inputSchema","MAX_OUTPUT_BYTES","text","html","path","z","inputSchema","html","text","htmlToText","z","inputSchema","z","inputSchema","z","inputSchema","text","z","inputSchema","z","inputSchema","z","text","safeText","parsed","inputSchema","z","z","picomatch","text","text","SAFE_NAME","zodToJsonSchema","jsonSchema","tryParseJSON","text","z","SAFE_NAME","inputSchema","z","inputSchema","byteLength","raw","path","z","text","byteLength","text","inputSchema","z","cached","z","inputSchema","z","loadIndex","cached","path","SAFE_NAME","path","SAFE_NAME","DEFAULT_TIMEOUT_MS","cached","text","path","path","tryParseJSON","resolveAuth"]}