noumen 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -16
- package/dist/a2a/index.d.ts +5 -5
- package/dist/a2a/index.js +3 -3
- package/dist/a2a/index.js.map +1 -1
- package/dist/acp/index.d.ts +5 -5
- package/dist/acp/index.js +4 -4
- package/dist/acp/index.js.map +1 -1
- package/dist/{agent-BrkbZyOT.d.ts → agent-1nFVUP9E.d.ts} +319 -15
- package/dist/{cache-DVqaCX8v.d.ts → cache-DsRqxx6v.d.ts} +1 -1
- package/dist/{chunk-BGG2E6JD.js → chunk-3HEYCV26.js} +1 -1
- package/dist/chunk-3SK5GCI6.js +75 -0
- package/dist/chunk-3SK5GCI6.js.map +1 -0
- package/dist/{chunk-NBDFQYUZ.js → chunk-4HW6LN6D.js} +4784 -2411
- package/dist/chunk-4HW6LN6D.js.map +1 -0
- package/dist/{chunk-7ZMN7XJE.js → chunk-5JN4SPI7.js} +6 -6
- package/dist/chunk-5JN4SPI7.js.map +1 -0
- package/dist/{chunk-CPFHEPW4.js → chunk-CS6WNDCF.js} +73 -41
- package/dist/chunk-CS6WNDCF.js.map +1 -0
- package/dist/chunk-EKOGVTBT.js +472 -0
- package/dist/chunk-EKOGVTBT.js.map +1 -0
- package/dist/{chunk-KY6ZPWHO.js → chunk-HEQQQGK5.js} +47 -28
- package/dist/chunk-HEQQQGK5.js.map +1 -0
- package/dist/{chunk-QTJ7VTJY.js → chunk-HL6JCRZJ.js} +1599 -481
- package/dist/chunk-HL6JCRZJ.js.map +1 -0
- package/dist/chunk-L3L3FG5T.js +16 -0
- package/dist/chunk-L3L3FG5T.js.map +1 -0
- package/dist/cli/index.js +36 -30
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.d.ts +2 -2
- package/dist/{headless-Q7XHHZIW.js → headless-FFU2DESQ.js} +3 -4
- package/dist/headless-FFU2DESQ.js.map +1 -0
- package/dist/index.d.ts +218 -68
- package/dist/index.js +37 -23
- package/dist/lsp/index.d.ts +4 -4
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/index.js +2 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/{provider-factory-34MSWJZ3.js → provider-factory-KCLIF34X.js} +2 -2
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +5 -3
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/bedrock.d.ts +2 -2
- package/dist/providers/bedrock.js +5 -3
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/gemini.d.ts +2 -1
- package/dist/providers/gemini.js +133 -95
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/ollama.d.ts +13 -0
- package/dist/{ollama-YNXAYP3R.js → providers/ollama.js} +6 -4
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +4 -1
- package/dist/providers/openai.js +2 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/openrouter.js +2 -1
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/vertex.d.ts +4 -2
- package/dist/providers/vertex.js +6 -3
- package/dist/providers/vertex.js.map +1 -1
- package/dist/{resolve-XM52G7YE.js → resolve-4JA2BBDA.js} +2 -2
- package/dist/server/index.d.ts +35 -20
- package/dist/server/index.js +276 -207
- package/dist/server/index.js.map +1 -1
- package/dist/{server-Cg1yWGaV.d.ts → server-CHMxuWKq.d.ts} +1 -1
- package/dist/{types-DwdzmXfs.d.ts → types-CD0rUKKT.d.ts} +2 -0
- package/dist/{types-3c88cRKH.d.ts → types-LrU4LRmX.d.ts} +28 -0
- package/dist/{types-CwKKucOF.d.ts → types-RPKUTu1k.d.ts} +27 -2
- package/dist/uuid-RVN2T26F.js +8 -0
- package/dist/uuid-RVN2T26F.js.map +1 -0
- package/dist/zod-7YXKWYMC.js +12 -0
- package/dist/zod-7YXKWYMC.js.map +1 -0
- package/package.json +22 -13
- package/dist/chunk-2ZTGQLYK.js +0 -356
- package/dist/chunk-2ZTGQLYK.js.map +0 -1
- package/dist/chunk-7ZMN7XJE.js.map +0 -1
- package/dist/chunk-CPFHEPW4.js.map +0 -1
- package/dist/chunk-KY6ZPWHO.js.map +0 -1
- package/dist/chunk-NBDFQYUZ.js.map +0 -1
- package/dist/chunk-QTJ7VTJY.js.map +0 -1
- package/dist/headless-Q7XHHZIW.js.map +0 -1
- package/dist/ollama-YNXAYP3R.js.map +0 -1
- /package/dist/{chunk-BGG2E6JD.js.map → chunk-3HEYCV26.js.map} +0 -0
- /package/dist/{provider-factory-34MSWJZ3.js.map → provider-factory-KCLIF34X.js.map} +0 -0
- /package/dist/{resolve-XM52G7YE.js.map → resolve-4JA2BBDA.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/virtual/local-fs.ts","../src/virtual/local-computer.ts","../src/virtual/sandboxed-local-computer.ts","../src/virtual/sprites-fs.ts","../src/virtual/sprites-computer.ts","../src/virtual/docker-fs.ts","../src/virtual/docker-computer.ts","../src/virtual/e2b-fs.ts","../src/virtual/e2b-computer.ts","../src/virtual/sandbox.ts","../src/checkpoint/manager.ts","../src/checkpoint/types.ts","../src/hooks/runner.ts","../src/tools/prompts/agent.ts","../src/tools/agent.ts","../src/tools/prompts/web-search.ts","../src/tools/web-search.ts","../src/tools/task-create.ts","../src/tools/task-list.ts","../src/tools/task-get.ts","../src/tools/task-update.ts","../src/tools/plan-mode.ts","../src/utils/worktree.ts","../src/tools/worktree.ts","../src/cost/pricing.ts","../src/cost/tracker.ts","../src/utils/json.ts","../src/session/storage.ts","../src/tasks/store.ts","../src/context/prompts.ts","../src/skills/frontmatter.ts","../src/context/loader.ts","../src/tracing/types.ts","../src/tracing/noop.ts","../src/memory/prompts.ts","../src/memory/extraction.ts","../src/providers/cache-safe-params.ts","../src/session/recovery.ts","../src/session/resume.ts","../src/utils/generators.ts","../src/tools/orchestration.ts","../src/tools/streaming-executor.ts","../src/prompt/system.ts","../src/utils/tokens.ts","../src/compact/compact.ts","../src/compact/auto-compact.ts","../src/compact/microcompact.ts","../src/compact/tool-result-budget.ts","../src/compact/tool-result-storage.ts","../src/compact/reactive-compact.ts","../src/file-state/cache.ts","../src/skills/activation.ts","../src/tools/skill.ts","../src/permissions/rules.ts","../src/permissions/types.ts","../src/permissions/classifier.ts","../src/permissions/pipeline.ts","../src/permissions/denial-tracking.ts","../src/retry/classify.ts","../src/retry/backoff.ts","../src/retry/engine.ts","../src/tools/structured-output.ts","../src/thread.ts","../src/skills/loader.ts","../src/prompt/context.ts","../src/retry/types.ts","../src/agent.ts","../src/presets.ts","../src/providers/types.ts","../src/swarm/mailbox.ts","../src/swarm/manager.ts","../src/swarm/backends/in-process.ts","../src/permissions/updates.ts","../src/tracing/otel.ts","../src/memory/file-provider.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\n\nexport interface LocalFsOptions {\n basePath?: string;\n}\n\n/**\n * Unsandboxed VirtualFs backed by `node:fs/promises` on the host machine.\n * Paths resolve relative to `basePath`. Suitable for local development and\n * trusted environments. For production or untrusted agents, use a sandboxed\n * implementation like `SpritesFs` (remote container) or a custom\n * Docker/E2B adapter instead.\n */\nexport class LocalFs implements VirtualFs {\n private basePath: string;\n\n constructor(opts?: LocalFsOptions) {\n this.basePath = opts?.basePath ?? process.cwd();\n }\n\n private resolve(p: string): string {\n if (path.isAbsolute(p)) return p;\n return path.resolve(this.basePath, p);\n }\n\n async readFile(filePath: string, opts?: ReadOptions): Promise<string> {\n const encoding = opts?.encoding ?? \"utf-8\";\n return fs.readFile(this.resolve(filePath), { encoding });\n }\n\n async readFileBytes(filePath: string, maxBytes?: number): Promise<Buffer> {\n const resolved = this.resolve(filePath);\n if (maxBytes === undefined) {\n return fs.readFile(resolved);\n }\n const fh = await fs.open(resolved, \"r\");\n try {\n const buf = Buffer.alloc(maxBytes);\n const { bytesRead } = await fh.read(buf, 0, maxBytes, 0);\n return buf.subarray(0, bytesRead);\n } finally {\n await fh.close();\n }\n }\n\n async writeFile(filePath: string, content: string): Promise<void> {\n const resolved = this.resolve(filePath);\n await fs.mkdir(path.dirname(resolved), { recursive: true });\n await fs.writeFile(resolved, content, \"utf-8\");\n }\n\n async appendFile(filePath: string, content: string): Promise<void> {\n const resolved = this.resolve(filePath);\n await fs.mkdir(path.dirname(resolved), { recursive: true });\n await fs.appendFile(resolved, content, \"utf-8\");\n }\n\n async deleteFile(\n filePath: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n await fs.rm(this.resolve(filePath), {\n recursive: opts?.recursive ?? false,\n force: true,\n });\n }\n\n async mkdir(dirPath: string, opts?: { recursive?: boolean }): Promise<void> {\n await fs.mkdir(this.resolve(dirPath), {\n recursive: opts?.recursive ?? false,\n });\n }\n\n async readdir(\n dirPath: string,\n opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const resolved = this.resolve(dirPath);\n const entries = await fs.readdir(resolved, { withFileTypes: true });\n const results: FileEntry[] = [];\n\n for (const entry of entries) {\n const entryPath = path.join(resolved, entry.name);\n results.push({\n name: entry.name,\n path: entryPath,\n isDirectory: entry.isDirectory(),\n isFile: entry.isFile(),\n });\n\n if (opts?.recursive && entry.isDirectory()) {\n const subEntries = await this.readdir(entryPath, { recursive: true });\n results.push(...subEntries);\n }\n }\n\n return results;\n }\n\n async exists(filePath: string): Promise<boolean> {\n try {\n await fs.access(this.resolve(filePath));\n return true;\n } catch {\n return false;\n }\n }\n\n async stat(filePath: string): Promise<FileStat> {\n const stats = await fs.stat(this.resolve(filePath));\n return {\n size: stats.size,\n isDirectory: stats.isDirectory(),\n isFile: stats.isFile(),\n createdAt: stats.birthtime,\n modifiedAt: stats.mtime,\n };\n }\n}\n","import { exec as execCb } from \"node:child_process\";\nimport type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\n\nexport interface LocalComputerOptions {\n defaultCwd?: string;\n defaultTimeout?: number;\n}\n\n/**\n * Unsandboxed VirtualComputer that runs commands directly on the host via\n * `node:child_process`. Suitable for local development and trusted\n * environments. For production or untrusted agents, use a sandboxed\n * implementation like `SpritesComputer` (remote container) or a custom\n * Docker/E2B adapter instead.\n */\nexport class LocalComputer implements VirtualComputer {\n private defaultCwd: string;\n private defaultTimeout: number;\n\n constructor(opts?: LocalComputerOptions) {\n this.defaultCwd = opts?.defaultCwd ?? process.cwd();\n this.defaultTimeout = opts?.defaultTimeout ?? 30_000;\n }\n\n executeCommand(command: string, opts?: ExecOptions): Promise<CommandResult> {\n return new Promise((resolve) => {\n const child = execCb(\n command,\n {\n cwd: opts?.cwd ?? this.defaultCwd,\n timeout: opts?.timeout ?? this.defaultTimeout,\n env: opts?.env\n ? { ...process.env, ...opts.env }\n : process.env,\n maxBuffer: 10 * 1024 * 1024,\n shell: process.env.SHELL || \"/bin/sh\",\n },\n (error, stdout, stderr) => {\n resolve({\n exitCode:\n error && \"code\" in error\n ? (error.code as number) ?? 1\n : child.exitCode ?? 0,\n stdout: stdout ?? \"\",\n stderr: stderr ?? \"\",\n });\n },\n );\n });\n }\n}\n","import { exec as execCb } from \"node:child_process\";\nimport type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\nimport {\n SandboxManager,\n type SandboxRuntimeConfig,\n} from \"@anthropic-ai/sandbox-runtime\";\n\n/**\n * Filesystem and network restriction config passed to `@anthropic-ai/sandbox-runtime`.\n */\nexport interface SandboxConfig {\n filesystem?: {\n /** Paths the agent may write to (default: `[cwd]`). Write is denied everywhere else. */\n allowWrite?: string[];\n /** Paths to explicitly deny writes within allowed regions. */\n denyWrite?: string[];\n /** Paths to deny reading. By default everything is readable. */\n denyRead?: string[];\n /** Paths to re-allow reading within denyRead regions. Takes precedence over denyRead. */\n allowRead?: string[];\n };\n network?: {\n /** Domains the agent may reach via HTTP/HTTPS/SOCKS. */\n allowedDomains?: string[];\n /** Domains to explicitly block. */\n deniedDomains?: string[];\n };\n}\n\nexport interface SandboxedLocalComputerOptions {\n defaultCwd?: string;\n defaultTimeout?: number;\n sandbox?: SandboxConfig;\n}\n\n/**\n * `VirtualComputer` that wraps every command with OS-level sandboxing via\n * `@anthropic-ai/sandbox-runtime`. Uses macOS Seatbelt (`sandbox-exec`) or\n * Linux bubblewrap (`bwrap`) under the hood.\n */\nexport class SandboxedLocalComputer implements VirtualComputer {\n private defaultCwd: string;\n private defaultTimeout: number;\n private sandboxConfig: SandboxConfig;\n private initPromise: Promise<void> | null = null;\n private initialized = false;\n\n constructor(opts?: SandboxedLocalComputerOptions) {\n this.defaultCwd = opts?.defaultCwd ?? process.cwd();\n this.defaultTimeout = opts?.defaultTimeout ?? 30_000;\n this.sandboxConfig = opts?.sandbox ?? {};\n }\n\n private buildRuntimeConfig(): SandboxRuntimeConfig {\n const fs = this.sandboxConfig.filesystem;\n const net = this.sandboxConfig.network;\n return {\n filesystem: {\n allowWrite: fs?.allowWrite ?? [this.defaultCwd],\n denyWrite: fs?.denyWrite ?? [],\n denyRead: fs?.denyRead ?? [],\n allowRead: fs?.allowRead ?? [],\n },\n network: {\n allowedDomains: net?.allowedDomains ?? [],\n deniedDomains: net?.deniedDomains ?? [],\n },\n };\n }\n\n private async ensureInitialized(): Promise<void> {\n if (this.initialized) return;\n\n if (!this.initPromise) {\n this.initPromise = (async () => {\n await SandboxManager.initialize(this.buildRuntimeConfig());\n this.initialized = true;\n })();\n }\n\n await this.initPromise;\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n await this.ensureInitialized();\n\n const wrappedCommand = await SandboxManager.wrapWithSandbox(command);\n\n return new Promise((resolve) => {\n const child = execCb(\n wrappedCommand,\n {\n cwd: opts?.cwd ?? this.defaultCwd,\n timeout: opts?.timeout ?? this.defaultTimeout,\n env: opts?.env ? { ...process.env, ...opts.env } : process.env,\n maxBuffer: 10 * 1024 * 1024,\n shell: process.env.SHELL || \"/bin/sh\",\n },\n (error, stdout, stderr) => {\n SandboxManager.cleanupAfterCommand();\n resolve({\n exitCode:\n error && \"code\" in error\n ? (error.code as number) ?? 1\n : child.exitCode ?? 0,\n stdout: stdout ?? \"\",\n stderr: stderr ?? \"\",\n });\n },\n );\n });\n }\n\n /**\n * Tear down the sandbox runtime. Call when the agent is done.\n */\n async dispose(): Promise<void> {\n if (this.initialized) {\n await SandboxManager.reset();\n this.initialized = false;\n this.initPromise = null;\n }\n }\n}\n","import type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\n\nexport interface SpritesFsOptions {\n /** sprites.dev API token */\n token: string;\n /** Name of the sprite container */\n spriteName: string;\n /** Base URL for sprites API (default: https://api.sprites.dev) */\n baseURL?: string;\n /** Working directory inside the sprite (default: /home/sprite) */\n workingDir?: string;\n}\n\n/**\n * Sandboxed VirtualFs backed by a remote sprites.dev container. All file\n * operations are executed over the sprites.dev HTTP API — the agent has no\n * access to the host filesystem. This is the recommended VirtualFs for\n * production deployments and untrusted agents. See `LocalFs` for an\n * unsandboxed local alternative.\n */\nexport class SpritesFs implements VirtualFs {\n private token: string;\n private spriteName: string;\n private baseURL: string;\n private workingDir: string;\n\n constructor(opts: SpritesFsOptions) {\n this.token = opts.token;\n this.spriteName = opts.spriteName;\n this.baseURL = (opts.baseURL ?? \"https://api.sprites.dev\").replace(\n /\\/$/,\n \"\",\n );\n this.workingDir = opts.workingDir ?? \"/home/sprite\";\n }\n\n private fsUrl(endpoint: string, params?: Record<string, string>): string {\n const url = new URL(\n `${this.baseURL}/v1/sprites/${this.spriteName}/fs${endpoint}`,\n );\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n url.searchParams.set(k, v);\n }\n }\n return url.toString();\n }\n\n private resolvePath(p: string): string {\n if (p.startsWith(\"/\")) return p;\n return `${this.workingDir}/${p}`;\n }\n\n private headers(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n };\n }\n\n async readFile(filePath: string, _opts?: ReadOptions): Promise<string> {\n const url = this.fsUrl(\"/read\", { path: this.resolvePath(filePath) });\n const res = await fetch(url, { headers: this.headers() });\n if (!res.ok) {\n throw new Error(\n `SpritesFs readFile failed (${res.status}): ${await res.text()}`,\n );\n }\n return res.text();\n }\n\n async readFileBytes(filePath: string, maxBytes?: number): Promise<Buffer> {\n const url = this.fsUrl(\"/read\", {\n path: this.resolvePath(filePath),\n binary: \"true\",\n });\n const res = await fetch(url, { headers: this.headers() });\n if (!res.ok) {\n throw new Error(\n `SpritesFs readFileBytes failed (${res.status}): ${await res.text()}`,\n );\n }\n const arrayBuf = await res.arrayBuffer();\n const buf = Buffer.from(arrayBuf);\n if (maxBytes !== undefined && buf.length > maxBytes) {\n return buf.subarray(0, maxBytes);\n }\n return buf;\n }\n\n async writeFile(filePath: string, content: string): Promise<void> {\n const url = this.fsUrl(\"/write\");\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n ...this.headers(),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n path: this.resolvePath(filePath),\n content,\n }),\n });\n if (!res.ok) {\n throw new Error(\n `SpritesFs writeFile failed (${res.status}): ${await res.text()}`,\n );\n }\n }\n\n async appendFile(filePath: string, content: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await this.readFile(filePath);\n } catch {\n // file may not exist yet\n }\n await this.writeFile(filePath, existing + content);\n }\n\n async deleteFile(\n filePath: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n const url = this.fsUrl(\"/remove\");\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n ...this.headers(),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n path: this.resolvePath(filePath),\n recursive: opts?.recursive ?? false,\n }),\n });\n if (!res.ok) {\n throw new Error(\n `SpritesFs deleteFile failed (${res.status}): ${await res.text()}`,\n );\n }\n }\n\n async mkdir(\n dirPath: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n const url = this.fsUrl(\"/mkdir\");\n const res = await fetch(url, {\n method: \"POST\",\n headers: {\n ...this.headers(),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n path: this.resolvePath(dirPath),\n recursive: opts?.recursive ?? false,\n }),\n });\n if (!res.ok) {\n throw new Error(\n `SpritesFs mkdir failed (${res.status}): ${await res.text()}`,\n );\n }\n }\n\n async readdir(\n dirPath: string,\n _opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const url = this.fsUrl(\"/readdir\", { path: this.resolvePath(dirPath) });\n const res = await fetch(url, { headers: this.headers() });\n if (!res.ok) {\n throw new Error(\n `SpritesFs readdir failed (${res.status}): ${await res.text()}`,\n );\n }\n const data = (await res.json()) as Array<{\n name: string;\n path: string;\n is_dir: boolean;\n size?: number;\n }>;\n return data.map((entry) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: entry.is_dir,\n isFile: !entry.is_dir,\n size: entry.size,\n }));\n }\n\n async exists(filePath: string): Promise<boolean> {\n try {\n await this.stat(filePath);\n return true;\n } catch {\n return false;\n }\n }\n\n async stat(filePath: string): Promise<FileStat> {\n const url = this.fsUrl(\"/stat\", { path: this.resolvePath(filePath) });\n const res = await fetch(url, { headers: this.headers() });\n if (!res.ok) {\n throw new Error(\n `SpritesFs stat failed (${res.status}): ${await res.text()}`,\n );\n }\n const data = (await res.json()) as {\n size: number;\n is_dir: boolean;\n created_at?: string;\n modified_at?: string;\n };\n return {\n size: data.size,\n isDirectory: data.is_dir,\n isFile: !data.is_dir,\n createdAt: data.created_at ? new Date(data.created_at) : undefined,\n modifiedAt: data.modified_at ? new Date(data.modified_at) : undefined,\n };\n }\n}\n","import type {\n VirtualComputer,\n ExecOptions,\n CommandResult,\n} from \"./computer.js\";\n\nexport interface SpritesComputerOptions {\n /** sprites.dev API token */\n token: string;\n /** Name of the sprite container */\n spriteName: string;\n /** Base URL for sprites API (default: https://api.sprites.dev) */\n baseURL?: string;\n /** Working directory inside the sprite (default: /home/sprite) */\n workingDir?: string;\n}\n\n/**\n * Sandboxed VirtualComputer that executes commands inside a remote\n * sprites.dev container. All shell execution is fully isolated — the agent\n * has no access to the host machine's processes, filesystem, or network.\n *\n * This is the recommended VirtualComputer for production deployments and\n * untrusted agents. See `LocalComputer` for an unsandboxed local alternative.\n *\n * Uses the non-interactive exec REST endpoint (POST command, receive\n * stdout/stderr/exit_code). The WebSocket exec endpoint can be used for\n * streaming/TTY use cases, but REST is sufficient for tool calls.\n */\nexport class SpritesComputer implements VirtualComputer {\n private token: string;\n private spriteName: string;\n private baseURL: string;\n private workingDir: string;\n\n constructor(opts: SpritesComputerOptions) {\n this.token = opts.token;\n this.spriteName = opts.spriteName;\n this.baseURL = (opts.baseURL ?? \"https://api.sprites.dev\").replace(\n /\\/$/,\n \"\",\n );\n this.workingDir = opts.workingDir ?? \"/home/sprite\";\n }\n\n private headers(): Record<string, string> {\n return {\n Authorization: `Bearer ${this.token}`,\n \"Content-Type\": \"application/json\",\n };\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n const cwd = opts?.cwd ?? this.workingDir;\n const wrappedCommand = `cd ${this.shellEscape(cwd)} && ${command}`;\n\n const url = `${this.baseURL}/v1/sprites/${this.spriteName}/exec`;\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.headers(),\n body: JSON.stringify({\n command: [\"bash\", \"-c\", wrappedCommand],\n timeout: opts?.timeout ?? 30_000,\n env: opts?.env,\n }),\n });\n\n if (!res.ok) {\n const text = await res.text();\n return {\n exitCode: 1,\n stdout: \"\",\n stderr: `Sprites exec failed (${res.status}): ${text}`,\n };\n }\n\n const data = (await res.json()) as {\n exit_code: number;\n stdout: string;\n stderr: string;\n };\n\n return {\n exitCode: data.exit_code,\n stdout: data.stdout ?? \"\",\n stderr: data.stderr ?? \"\",\n };\n }\n\n private shellEscape(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n }\n}\n","import type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\nimport type { DockerContainer } from \"./docker-computer.js\";\n\nexport interface DockerFsOptions {\n /** A dockerode Container instance for the target container. */\n container: DockerContainer;\n /** Working directory for relative path resolution (default: /). */\n workingDir?: string;\n}\n\n/**\n * VirtualFs backed by file operations inside a Docker container.\n *\n * Uses `container.exec()` to run filesystem commands (cat, tee, rm, mkdir,\n * stat, etc.) inside the container. File writes use exec + tee to avoid\n * tar archive overhead for text content.\n *\n * Requires `dockerode` as an optional peer dependency.\n * The user is responsible for container lifecycle.\n */\nexport class DockerFs implements VirtualFs {\n private container: DockerContainer;\n private workingDir: string;\n\n constructor(opts: DockerFsOptions) {\n this.container = opts.container;\n this.workingDir = opts.workingDir ?? \"/\";\n }\n\n private resolvePath(p: string): string {\n if (p.startsWith(\"/\")) return p;\n const base = this.workingDir.endsWith(\"/\")\n ? this.workingDir\n : this.workingDir + \"/\";\n return base + p;\n }\n\n private async exec(\n cmd: string[],\n ): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n const execInstance = await this.container.exec({\n Cmd: cmd,\n AttachStdout: true,\n AttachStderr: true,\n Tty: false,\n });\n const stream = await execInstance.start({ hijack: true, stdin: false });\n const result = await collectExecStream(stream);\n const inspection = await execInstance.inspect();\n return { exitCode: inspection.ExitCode, ...result };\n }\n\n async readFile(path: string, _opts?: ReadOptions): Promise<string> {\n const resolved = this.resolvePath(path);\n const { exitCode, stdout, stderr } = await this.exec([\n \"cat\",\n resolved,\n ]);\n if (exitCode !== 0) {\n throw new Error(`DockerFs readFile failed: ${stderr.trim() || `exit code ${exitCode}`}`);\n }\n return stdout;\n }\n\n async readFileBytes(path: string, maxBytes?: number): Promise<Buffer> {\n const resolved = this.resolvePath(path);\n const cmd = maxBytes !== undefined\n ? [\"head\", \"-c\", String(maxBytes), resolved]\n : [\"cat\", resolved];\n const { exitCode, stdout, stderr } = await this.exec([\n \"bash\", \"-c\",\n `${cmd.map(shellEscape).join(\" \")} | base64`,\n ]);\n if (exitCode !== 0) {\n throw new Error(`DockerFs readFileBytes failed: ${stderr.trim() || `exit code ${exitCode}`}`);\n }\n return Buffer.from(stdout.trim(), \"base64\");\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n const resolved = this.resolvePath(path);\n const dir = resolved.substring(0, resolved.lastIndexOf(\"/\"));\n if (dir) {\n await this.exec([\"mkdir\", \"-p\", dir]);\n }\n\n const encoded = Buffer.from(content, \"utf-8\").toString(\"base64\");\n\n const MAX_INLINE_LEN = 100_000;\n if (encoded.length <= MAX_INLINE_LEN) {\n const { exitCode, stderr } = await this.exec([\n \"bash\",\n \"-c\",\n `echo '${encoded}' | base64 -d > ${shellEscape(resolved)}`,\n ]);\n if (exitCode !== 0) {\n throw new Error(`DockerFs writeFile failed: ${stderr.trim()}`);\n }\n } else {\n const execInstance = await this.container.exec({\n Cmd: [\"bash\", \"-c\", `base64 -d > ${shellEscape(resolved)}`],\n AttachStdout: true,\n AttachStderr: true,\n AttachStdin: true,\n Tty: false,\n });\n const stream = await execInstance.start({ hijack: true, stdin: true });\n const writable = stream as unknown as NodeJS.WritableStream;\n writable.write(encoded);\n writable.end();\n const result = await collectExecStream(stream as unknown as NodeJS.ReadableStream);\n const inspection = await execInstance.inspect();\n if (inspection.ExitCode !== 0) {\n throw new Error(`DockerFs writeFile failed: ${result.stderr.trim()}`);\n }\n }\n }\n\n async appendFile(path: string, content: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await this.readFile(path);\n } catch {\n // file may not exist yet\n }\n await this.writeFile(path, existing + content);\n }\n\n async deleteFile(\n path: string,\n opts?: { recursive?: boolean },\n ): Promise<void> {\n const resolved = this.resolvePath(path);\n const args = opts?.recursive ? [\"rm\", \"-rf\", resolved] : [\"rm\", \"-f\", resolved];\n await this.exec(args);\n }\n\n async mkdir(path: string, opts?: { recursive?: boolean }): Promise<void> {\n const resolved = this.resolvePath(path);\n const args = opts?.recursive\n ? [\"mkdir\", \"-p\", resolved]\n : [\"mkdir\", resolved];\n await this.exec(args);\n }\n\n async readdir(\n path: string,\n _opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const resolved = this.resolvePath(path);\n const { exitCode, stdout, stderr } = await this.exec([\n \"bash\",\n \"-c\",\n `find ${shellEscape(resolved)} -maxdepth 1 -mindepth 1 -printf '%y %p\\\\n' 2>/dev/null`,\n ]);\n if (exitCode !== 0 && stderr.trim()) {\n throw new Error(`DockerFs readdir failed: ${stderr.trim()}`);\n }\n\n const entries: FileEntry[] = [];\n for (const line of stdout.trim().split(\"\\n\")) {\n if (!line) continue;\n const spaceIdx = line.indexOf(\" \");\n const type = line.substring(0, spaceIdx);\n const fullPath = line.substring(spaceIdx + 1);\n const name = fullPath.substring(fullPath.lastIndexOf(\"/\") + 1);\n entries.push({\n name,\n path: fullPath,\n isDirectory: type === \"d\",\n isFile: type === \"f\",\n });\n }\n return entries;\n }\n\n async exists(path: string): Promise<boolean> {\n const resolved = this.resolvePath(path);\n const { exitCode } = await this.exec([\"test\", \"-e\", resolved]);\n return exitCode === 0;\n }\n\n async stat(path: string): Promise<FileStat> {\n const resolved = this.resolvePath(path);\n const { exitCode, stdout, stderr } = await this.exec([\n \"stat\",\n \"-c\",\n \"%s\\t%F\\t%W\\t%Y\",\n resolved,\n ]);\n if (exitCode !== 0) {\n throw new Error(`DockerFs stat failed: ${stderr.trim() || `exit code ${exitCode}`}`);\n }\n\n const parts = stdout.trim().split(\"\\t\");\n const size = parseInt(parts[0], 10);\n const fileType = parts[1];\n const createdEpoch = parseInt(parts[2], 10);\n const modifiedEpoch = parseInt(parts[3], 10);\n\n return {\n size,\n isDirectory: fileType === \"directory\",\n isFile: fileType.startsWith(\"regular\"),\n createdAt: createdEpoch > 0 ? new Date(createdEpoch * 1000) : undefined,\n modifiedAt: modifiedEpoch > 0 ? new Date(modifiedEpoch * 1000) : undefined,\n };\n }\n}\n\nfunction shellEscape(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction collectExecStream(\n stream: NodeJS.ReadableStream,\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const stdoutBufs: Buffer[] = [];\n const stderrBufs: Buffer[] = [];\n let pending: Buffer = Buffer.alloc(0);\n\n stream.on(\"data\", (chunk: Buffer) => {\n let buf = pending.length > 0 ? Buffer.concat([pending, chunk]) : chunk;\n let offset = 0;\n while (offset + 8 <= buf.length) {\n const payloadLen = buf.readUInt32BE(offset + 4);\n if (offset + 8 + payloadLen > buf.length) break;\n const streamType = buf[offset];\n const payload = buf.subarray(offset + 8, offset + 8 + payloadLen);\n if (streamType === 2) {\n stderrBufs.push(payload);\n } else {\n stdoutBufs.push(payload);\n }\n offset += 8 + payloadLen;\n }\n pending = offset < buf.length ? buf.subarray(offset) : Buffer.alloc(0);\n });\n\n stream.on(\"end\", () => {\n resolve({\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr: Buffer.concat(stderrBufs).toString(\"utf-8\"),\n });\n });\n\n stream.on(\"error\", (err: Error) => reject(err));\n });\n}\n","import type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\n\n/**\n * Minimal subset of the dockerode Container interface used by DockerComputer.\n * Avoids a hard import of dockerode at the module level.\n */\nexport interface DockerContainer {\n exec(\n options: Record<string, unknown>,\n ): Promise<{ start(opts?: Record<string, unknown>): Promise<NodeJS.ReadableStream>; inspect(): Promise<{ ExitCode: number }> }>;\n}\n\nexport interface DockerComputerOptions {\n /** A dockerode Container instance for the target container. */\n container: DockerContainer;\n /** Default working directory for commands (default: /). */\n defaultCwd?: string;\n /** Default timeout in ms for commands (default: 30000). */\n defaultTimeout?: number;\n}\n\n/**\n * VirtualComputer backed by command execution inside a Docker container.\n *\n * Requires `dockerode` as an optional peer dependency.\n * The user is responsible for container lifecycle (create, start, stop).\n */\nexport class DockerComputer implements VirtualComputer {\n private container: DockerContainer;\n private defaultCwd: string;\n private defaultTimeout: number;\n\n constructor(opts: DockerComputerOptions) {\n this.container = opts.container;\n this.defaultCwd = opts.defaultCwd ?? \"/\";\n this.defaultTimeout = opts.defaultTimeout ?? 30_000;\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n const cwd = opts?.cwd ?? this.defaultCwd;\n const timeout = opts?.timeout ?? this.defaultTimeout;\n\n const execOpts: Record<string, unknown> = {\n Cmd: [\"bash\", \"-c\", `cd ${shellEscape(cwd)} && ${command}`],\n AttachStdout: true,\n AttachStderr: true,\n Tty: false,\n };\n if (opts?.env) {\n execOpts.Env = Object.entries(opts.env).map(\n ([k, v]) => `${k}=${v}`,\n );\n }\n\n const exec = await this.container.exec(execOpts);\n const stream = await exec.start({ hijack: true, stdin: false });\n\n const { stdout, stderr } = await collectStream(stream, timeout);\n const inspection = await exec.inspect();\n\n return {\n exitCode: inspection.ExitCode,\n stdout,\n stderr,\n };\n }\n}\n\nfunction shellEscape(s: string): string {\n return `'${s.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction collectStream(\n stream: NodeJS.ReadableStream,\n timeout: number,\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n const stdoutBufs: Buffer[] = [];\n const stderrBufs: Buffer[] = [];\n let pending: Buffer = Buffer.alloc(0);\n\n const timer = setTimeout(() => {\n (stream as unknown as { destroy?: () => void }).destroy?.();\n resolve({\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr: Buffer.concat(stderrBufs).toString(\"utf-8\") +\n \"\\n[timeout after \" + timeout + \"ms]\",\n });\n }, timeout);\n\n stream.on(\"data\", (chunk: Buffer) => {\n let buf = pending.length > 0 ? Buffer.concat([pending, chunk]) : chunk;\n let offset = 0;\n while (offset + 8 <= buf.length) {\n const payloadLen = buf.readUInt32BE(offset + 4);\n if (offset + 8 + payloadLen > buf.length) break;\n const streamType = buf[offset];\n const payload = buf.subarray(offset + 8, offset + 8 + payloadLen);\n if (streamType === 2) {\n stderrBufs.push(payload);\n } else {\n stdoutBufs.push(payload);\n }\n offset += 8 + payloadLen;\n }\n pending = offset < buf.length ? buf.subarray(offset) : Buffer.alloc(0);\n });\n\n stream.on(\"end\", () => {\n clearTimeout(timer);\n resolve({\n stdout: Buffer.concat(stdoutBufs).toString(\"utf-8\"),\n stderr: Buffer.concat(stderrBufs).toString(\"utf-8\"),\n });\n });\n\n stream.on(\"error\", (err: Error) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n}\n","import type { VirtualFs, FileEntry, FileStat, ReadOptions } from \"./fs.js\";\nimport type { E2BSandboxInstance } from \"./e2b-computer.js\";\n\nexport interface E2BFsOptions {\n /** An E2B Sandbox instance created via `Sandbox.create()`. */\n sandbox: E2BSandboxInstance;\n /** Working directory for relative path resolution. */\n workingDir?: string;\n}\n\n/**\n * VirtualFs backed by the E2B cloud sandbox filesystem.\n *\n * Requires `e2b` as an optional peer dependency.\n * The user is responsible for sandbox lifecycle (create, close).\n */\nexport class E2BFs implements VirtualFs {\n private sandbox: E2BSandboxInstance;\n private workingDir: string | undefined;\n\n constructor(opts: E2BFsOptions) {\n this.sandbox = opts.sandbox;\n this.workingDir = opts.workingDir;\n }\n\n private resolvePath(p: string): string {\n if (p.startsWith(\"/\")) return p;\n if (!this.workingDir) return p;\n const base = this.workingDir.endsWith(\"/\")\n ? this.workingDir\n : this.workingDir + \"/\";\n return base + p;\n }\n\n async readFile(path: string, _opts?: ReadOptions): Promise<string> {\n return this.sandbox.files.read(this.resolvePath(path), {\n format: \"text\",\n });\n }\n\n async readFileBytes(path: string, maxBytes?: number): Promise<Buffer> {\n const data = await this.sandbox.files.read(this.resolvePath(path), {\n format: \"bytes\",\n } as Record<string, unknown>);\n const buf = Buffer.from(data as unknown as ArrayBuffer);\n if (maxBytes !== undefined && buf.length > maxBytes) {\n return buf.subarray(0, maxBytes);\n }\n return buf;\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n await this.sandbox.files.write(this.resolvePath(path), content);\n }\n\n async appendFile(path: string, content: string): Promise<void> {\n let existing = \"\";\n try {\n existing = await this.readFile(path);\n } catch {\n // file may not exist yet\n }\n await this.writeFile(path, existing + content);\n }\n\n async deleteFile(\n path: string,\n _opts?: { recursive?: boolean },\n ): Promise<void> {\n await this.sandbox.files.remove(this.resolvePath(path));\n }\n\n async mkdir(path: string, _opts?: { recursive?: boolean }): Promise<void> {\n await this.sandbox.files.makeDir(this.resolvePath(path));\n }\n\n async readdir(\n path: string,\n _opts?: { recursive?: boolean },\n ): Promise<FileEntry[]> {\n const entries = await this.sandbox.files.list(this.resolvePath(path));\n return entries.map((entry) => ({\n name: entry.name,\n path: entry.path,\n isDirectory: entry.type === \"dir\",\n isFile: entry.type === \"file\" || entry.type !== \"dir\",\n size: entry.size,\n }));\n }\n\n async exists(path: string): Promise<boolean> {\n return this.sandbox.files.exists(this.resolvePath(path));\n }\n\n async stat(path: string): Promise<FileStat> {\n const info = await this.sandbox.files.getInfo(this.resolvePath(path));\n return {\n size: info.size ?? 0,\n isDirectory: info.type === \"dir\",\n isFile: info.type === \"file\" || info.type !== \"dir\",\n modifiedAt: info.modifiedTime,\n };\n }\n}\n","import type { VirtualComputer, ExecOptions, CommandResult } from \"./computer.js\";\n\n/**\n * Minimal subset of the E2B Sandbox interface used by E2BComputer and E2BFs.\n * Avoids a hard import of `e2b` at the module level.\n */\nexport interface E2BSandboxInstance {\n commands: {\n run(\n cmd: string,\n opts?: {\n cwd?: string;\n timeout?: number;\n envs?: Record<string, string>;\n },\n ): Promise<{\n exitCode: number;\n stdout: string;\n stderr: string;\n }>;\n };\n files: {\n read(path: string, opts?: { format?: string }): Promise<string>;\n write(path: string, data: string): Promise<unknown>;\n remove(path: string): Promise<void>;\n makeDir(path: string): Promise<unknown>;\n list(path: string): Promise<\n Array<{\n name: string;\n path: string;\n type?: string;\n size?: number;\n modifiedTime?: Date;\n }>\n >;\n exists(path: string): Promise<boolean>;\n getInfo(path: string): Promise<{\n name: string;\n path: string;\n type?: string;\n size?: number;\n modifiedTime?: Date;\n }>;\n };\n}\n\nexport interface E2BComputerOptions {\n /** An E2B Sandbox instance created via `Sandbox.create()`. */\n sandbox: E2BSandboxInstance;\n /** Default working directory for commands. */\n defaultCwd?: string;\n /** Default timeout in ms for commands (default: 30000). */\n defaultTimeout?: number;\n}\n\n/**\n * VirtualComputer backed by command execution in an E2B cloud sandbox.\n *\n * Requires `e2b` as an optional peer dependency.\n * The user is responsible for sandbox lifecycle (create, close).\n */\nexport class E2BComputer implements VirtualComputer {\n private sandbox: E2BSandboxInstance;\n private defaultCwd: string | undefined;\n private defaultTimeout: number;\n\n constructor(opts: E2BComputerOptions) {\n this.sandbox = opts.sandbox;\n this.defaultCwd = opts.defaultCwd;\n this.defaultTimeout = opts.defaultTimeout ?? 30_000;\n }\n\n async executeCommand(\n command: string,\n opts?: ExecOptions,\n ): Promise<CommandResult> {\n const result = await this.sandbox.commands.run(command, {\n cwd: opts?.cwd ?? this.defaultCwd,\n timeout: opts?.timeout ?? this.defaultTimeout,\n envs: opts?.env,\n });\n\n return {\n exitCode: result.exitCode,\n stdout: result.stdout ?? \"\",\n stderr: result.stderr ?? \"\",\n };\n }\n}\n","import type { VirtualFs } from \"./fs.js\";\nimport type { VirtualComputer } from \"./computer.js\";\nimport { LocalFs } from \"./local-fs.js\";\nimport { LocalComputer } from \"./local-computer.js\";\nimport { SandboxedLocalComputer, type SandboxConfig } from \"./sandboxed-local-computer.js\";\nimport { SpritesFs } from \"./sprites-fs.js\";\nimport { SpritesComputer } from \"./sprites-computer.js\";\nimport { DockerFs } from \"./docker-fs.js\";\nimport { DockerComputer, type DockerContainer } from \"./docker-computer.js\";\nimport { E2BFs } from \"./e2b-fs.js\";\nimport { E2BComputer, type E2BSandboxInstance } from \"./e2b-computer.js\";\n\nexport type { SandboxConfig } from \"./sandboxed-local-computer.js\";\n\n/**\n * Bundled sandbox: a `VirtualFs` and `VirtualComputer` paired together.\n *\n * Use one of the built-in factories (`LocalSandbox`, `UnsandboxedLocal`,\n * `SpritesSandbox`) or supply any object that satisfies this shape for\n * custom sandboxes (Docker, E2B, Daytona, in-memory, etc.).\n */\nexport interface Sandbox {\n fs: VirtualFs;\n computer: VirtualComputer;\n}\n\n// ---------------------------------------------------------------------------\n// UnsandboxedLocal — raw host access, no isolation\n// ---------------------------------------------------------------------------\n\nexport interface UnsandboxedLocalOptions {\n /** Working directory for both file resolution and command execution. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n}\n\n/**\n * Create a `Sandbox` backed by the host filesystem and shell with **no\n * OS-level isolation**. The agent can access anything the host process can.\n *\n * Use this for development or fully-trusted environments where sandboxing\n * overhead is unwanted. For production use, prefer `LocalSandbox()` (which\n * wraps commands with `@anthropic-ai/sandbox-runtime`).\n */\nexport function UnsandboxedLocal(opts?: UnsandboxedLocalOptions): Sandbox {\n const cwd = opts?.cwd;\n return {\n fs: new LocalFs({ basePath: cwd }),\n computer: new LocalComputer({\n defaultCwd: cwd,\n defaultTimeout: opts?.defaultTimeout,\n }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// LocalSandbox — OS-level sandboxing via @anthropic-ai/sandbox-runtime\n// ---------------------------------------------------------------------------\n\nexport interface LocalSandboxOptions {\n /** Working directory for both file resolution and command execution. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n /**\n * Sandbox restrictions. Defaults: writes allowed only in `cwd`,\n * reads allowed everywhere, network unrestricted.\n */\n sandbox?: SandboxConfig;\n}\n\n/**\n * Create a `Sandbox` with OS-level isolation via `@anthropic-ai/sandbox-runtime`.\n *\n * - **macOS**: Seatbelt (`sandbox-exec`) profiles restrict filesystem and network.\n * - **Linux**: bubblewrap (`bwrap`) + socat for namespace-based isolation.\n *\n * Filesystem operations (`VirtualFs`) use the host `node:fs` — the sandbox\n * boundary is enforced on shell commands (`VirtualComputer`), which is where\n * the agent executes arbitrary code.\n *\n * Requires `@anthropic-ai/sandbox-runtime` as a peer dependency.\n */\nexport function LocalSandbox(opts?: LocalSandboxOptions): Sandbox {\n const cwd = opts?.cwd ?? process.cwd();\n return {\n fs: new LocalFs({ basePath: cwd }),\n computer: new SandboxedLocalComputer({\n defaultCwd: cwd,\n defaultTimeout: opts?.defaultTimeout,\n sandbox: {\n filesystem: {\n allowWrite: [cwd],\n ...opts?.sandbox?.filesystem,\n },\n network: opts?.sandbox?.network,\n },\n }),\n };\n}\n\nexport interface SpritesSandboxOptions {\n /** sprites.dev API token. */\n token: string;\n /** Name of the sprite container. */\n spriteName: string;\n /** Base URL for sprites API (default: https://api.sprites.dev). */\n baseURL?: string;\n /** Working directory inside the sprite (default: /home/sprite). */\n workingDir?: string;\n}\n\n/**\n * Create a `Sandbox` backed by a remote sprites.dev container.\n * Full isolation — the agent has no access to the host machine.\n */\nexport function SpritesSandbox(opts: SpritesSandboxOptions): Sandbox {\n return {\n fs: new SpritesFs(opts),\n computer: new SpritesComputer(opts),\n };\n}\n\nexport interface DockerSandboxOptions {\n /** A dockerode Container instance for the target container. */\n container: DockerContainer;\n /** Working directory inside the container. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n}\n\n/**\n * Create a `Sandbox` backed by a Docker container.\n * Requires `dockerode` as an optional peer dependency.\n */\nexport function DockerSandbox(opts: DockerSandboxOptions): Sandbox {\n return {\n fs: new DockerFs({ container: opts.container, workingDir: opts.cwd }),\n computer: new DockerComputer({\n container: opts.container,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n };\n}\n\nexport interface E2BSandboxOptions {\n /** An E2B Sandbox instance created via `Sandbox.create()`. */\n sandbox: E2BSandboxInstance;\n /** Working directory inside the sandbox. */\n cwd?: string;\n /** Default timeout (ms) for shell commands. */\n defaultTimeout?: number;\n}\n\n/**\n * Create a `Sandbox` backed by an E2B cloud sandbox.\n * Requires `e2b` as an optional peer dependency.\n */\nexport function E2BSandbox(opts: E2BSandboxOptions): Sandbox {\n return {\n fs: new E2BFs({ sandbox: opts.sandbox, workingDir: opts.cwd }),\n computer: new E2BComputer({\n sandbox: opts.sandbox,\n defaultCwd: opts.cwd,\n defaultTimeout: opts.defaultTimeout,\n }),\n };\n}\n","import { createHash } from \"node:crypto\";\nimport type { VirtualFs } from \"../virtual/fs.js\";\nimport type {\n FileCheckpointBackup,\n FileCheckpointSnapshot,\n FileCheckpointState,\n CheckpointConfig,\n DiffStats,\n} from \"./types.js\";\nimport { createCheckpointState } from \"./types.js\";\n\nconst DEFAULT_MAX_SNAPSHOTS = 100;\nconst DEFAULT_BACKUP_DIR = \".noumen/checkpoints\";\n\nfunction hashFilePath(filePath: string): string {\n return createHash(\"sha256\").update(filePath).digest(\"hex\").slice(0, 16);\n}\n\nfunction backupFileName(filePath: string, version: number): string {\n return `${hashFilePath(filePath)}@v${version}`;\n}\n\nexport class FileCheckpointManager {\n private fs: VirtualFs;\n private maxSnapshots: number;\n private backupDir: string;\n private state: FileCheckpointState;\n\n constructor(fs: VirtualFs, config: CheckpointConfig) {\n this.fs = fs;\n this.maxSnapshots = config.maxSnapshots ?? DEFAULT_MAX_SNAPSHOTS;\n this.backupDir = config.backupDir ?? DEFAULT_BACKUP_DIR;\n this.state = createCheckpointState();\n }\n\n getState(): FileCheckpointState {\n return this.state;\n }\n\n private sessionBackupDir(sessionId: string): string {\n return `${this.backupDir}/${sessionId}`;\n }\n\n private resolveBackupPath(sessionId: string, bkFileName: string): string {\n return `${this.sessionBackupDir(sessionId)}/${bkFileName}`;\n }\n\n private async ensureBackupDir(sessionId: string): Promise<void> {\n const dir = this.sessionBackupDir(sessionId);\n const exists = await this.fs.exists(dir);\n if (!exists) {\n await this.fs.mkdir(dir, { recursive: true });\n }\n }\n\n private async createBackup(\n filePath: string,\n version: number,\n sessionId: string,\n ): Promise<FileCheckpointBackup> {\n const exists = await this.fs.exists(filePath);\n if (!exists) {\n return {\n backupFileName: null,\n version,\n backupTime: new Date().toISOString(),\n };\n }\n\n await this.ensureBackupDir(sessionId);\n const bkName = backupFileName(filePath, version);\n const bkPath = this.resolveBackupPath(sessionId, bkName);\n const content = await this.fs.readFile(filePath);\n await this.fs.writeFile(bkPath, content);\n\n return {\n backupFileName: bkName,\n version,\n backupTime: new Date().toISOString(),\n };\n }\n\n private async restoreBackup(\n filePath: string,\n bkFileName: string,\n sessionId: string,\n ): Promise<void> {\n const bkPath = this.resolveBackupPath(sessionId, bkFileName);\n const exists = await this.fs.exists(bkPath);\n if (!exists) return;\n\n const content = await this.fs.readFile(bkPath);\n await this.fs.writeFile(filePath, content);\n }\n\n private async hasFileChanged(\n filePath: string,\n backup: FileCheckpointBackup,\n sessionId: string,\n ): Promise<boolean> {\n const fileExists = await this.fs.exists(filePath);\n\n if (backup.backupFileName === null) {\n return fileExists;\n }\n\n if (!fileExists) return true;\n\n const bkPath = this.resolveBackupPath(sessionId, backup.backupFileName);\n const bkExists = await this.fs.exists(bkPath);\n if (!bkExists) return true;\n\n const currentContent = await this.fs.readFile(filePath);\n const backupContent = await this.fs.readFile(bkPath);\n return currentContent !== backupContent;\n }\n\n /**\n * Create a new snapshot at the start of a user turn.\n * For each tracked file, checks if it changed since the last backup and\n * creates a new versioned backup if so.\n */\n async makeSnapshot(messageId: string, sessionId: string): Promise<void> {\n const state = this.state;\n const mostRecent = state.snapshots.at(-1);\n\n const newBackups: Record<string, FileCheckpointBackup> = {};\n\n if (mostRecent) {\n for (const trackingPath of state.trackedFiles) {\n const lastBackup = mostRecent.trackedFileBackups[trackingPath];\n if (!lastBackup) continue;\n\n const changed = await this.hasFileChanged(trackingPath, lastBackup, sessionId);\n if (changed) {\n const nextVersion = lastBackup.version + 1;\n newBackups[trackingPath] = await this.createBackup(\n trackingPath,\n nextVersion,\n sessionId,\n );\n } else {\n newBackups[trackingPath] = lastBackup;\n }\n }\n }\n\n const snapshot: FileCheckpointSnapshot = {\n messageId,\n trackedFileBackups: newBackups,\n timestamp: new Date().toISOString(),\n };\n\n state.snapshots.push(snapshot);\n if (state.snapshots.length > this.maxSnapshots) {\n state.snapshots = state.snapshots.slice(-this.maxSnapshots);\n }\n state.snapshotSequence++;\n }\n\n /**\n * Track a file before it is edited. Creates the v1 backup (pre-edit state)\n * and attaches it to the current (latest) snapshot.\n * Called by write/edit tools before mutation.\n */\n async trackEdit(\n filePath: string,\n messageId: string,\n sessionId: string,\n ): Promise<void> {\n const state = this.state;\n const mostRecent = state.snapshots.at(-1);\n if (!mostRecent) return;\n\n if (mostRecent.trackedFileBackups[filePath]) return;\n\n const backup = await this.createBackup(filePath, 1, sessionId);\n mostRecent.trackedFileBackups[filePath] = backup;\n state.trackedFiles.add(filePath);\n }\n\n /**\n * Restore all tracked files to the state captured in the snapshot\n * matching the given messageId. Files that didn't exist at that point\n * are deleted; files that existed are restored from backups.\n */\n async rewind(messageId: string, sessionId: string): Promise<void> {\n const state = this.state;\n\n let targetSnapshot: FileCheckpointSnapshot | undefined;\n for (let i = state.snapshots.length - 1; i >= 0; i--) {\n if (state.snapshots[i].messageId === messageId) {\n targetSnapshot = state.snapshots[i];\n break;\n }\n }\n\n if (!targetSnapshot) {\n throw new Error(`No checkpoint snapshot found for messageId: ${messageId}`);\n }\n\n for (const trackingPath of state.trackedFiles) {\n const backup = targetSnapshot.trackedFileBackups[trackingPath];\n if (!backup) continue;\n\n if (backup.backupFileName === null) {\n const exists = await this.fs.exists(trackingPath);\n if (exists) {\n await this.fs.deleteFile(trackingPath);\n }\n } else {\n const changed = await this.hasFileChanged(trackingPath, backup, sessionId);\n if (changed) {\n await this.restoreBackup(trackingPath, backup.backupFileName, sessionId);\n }\n }\n }\n }\n\n canRestore(messageId: string): boolean {\n return this.state.snapshots.some((s) => s.messageId === messageId);\n }\n\n async getDiffStats(\n messageId: string,\n sessionId: string,\n ): Promise<DiffStats> {\n const state = this.state;\n\n let targetSnapshot: FileCheckpointSnapshot | undefined;\n for (let i = state.snapshots.length - 1; i >= 0; i--) {\n if (state.snapshots[i].messageId === messageId) {\n targetSnapshot = state.snapshots[i];\n break;\n }\n }\n\n if (!targetSnapshot) return undefined;\n\n let insertions = 0;\n let deletions = 0;\n const filesChanged: string[] = [];\n\n for (const trackingPath of state.trackedFiles) {\n const backup = targetSnapshot.trackedFileBackups[trackingPath];\n if (!backup) continue;\n\n const currentExists = await this.fs.exists(trackingPath);\n const currentContent = currentExists\n ? await this.fs.readFile(trackingPath)\n : \"\";\n\n let backupContent = \"\";\n if (backup.backupFileName !== null) {\n const bkPath = this.resolveBackupPath(sessionId, backup.backupFileName);\n const bkExists = await this.fs.exists(bkPath);\n if (bkExists) {\n backupContent = await this.fs.readFile(bkPath);\n }\n }\n\n if (currentContent === backupContent) continue;\n\n filesChanged.push(trackingPath);\n const currentLines = currentContent.split(\"\\n\");\n const backupLines = backupContent.split(\"\\n\");\n\n const maxLen = Math.max(currentLines.length, backupLines.length);\n for (let i = 0; i < maxLen; i++) {\n const cur = currentLines[i];\n const bak = backupLines[i];\n if (cur !== bak) {\n if (cur !== undefined && bak === undefined) {\n insertions++;\n } else if (cur === undefined && bak !== undefined) {\n deletions++;\n } else {\n insertions++;\n deletions++;\n }\n }\n }\n }\n\n return { filesChanged, insertions, deletions };\n }\n\n /**\n * Rebuild checkpoint state from persisted JSONL entries (for session resume).\n * Mirrors claude-code's buildFileHistorySnapshotChain + fileHistoryRestoreStateFromLog.\n */\n restoreStateFromEntries(snapshots: FileCheckpointSnapshot[]): void {\n const trackedFiles = new Set<string>();\n for (const snap of snapshots) {\n for (const path of Object.keys(snap.trackedFileBackups)) {\n trackedFiles.add(path);\n }\n }\n\n this.state = {\n snapshots: [...snapshots],\n trackedFiles,\n snapshotSequence: snapshots.length,\n };\n }\n}\n","/**\n * File checkpointing types.\n *\n * Adapted from claude-code's fileHistory system. Key difference: all I/O\n * routes through VirtualFs so checkpointing works in any sandbox (Docker,\n * E2B, Sprites, local).\n */\n\nexport interface FileCheckpointBackup {\n /** Backup filename under the session backup dir, or null if the file did not exist at this version. */\n backupFileName: string | null;\n version: number;\n backupTime: string;\n}\n\nexport interface FileCheckpointSnapshot {\n messageId: string;\n /** Map of tracked file paths → their backup at this snapshot. */\n trackedFileBackups: Record<string, FileCheckpointBackup>;\n timestamp: string;\n}\n\nexport interface FileCheckpointState {\n snapshots: FileCheckpointSnapshot[];\n trackedFiles: Set<string>;\n /**\n * Monotonically-increasing counter incremented on every snapshot, even when\n * old snapshots are evicted. Useful as an activity signal (snapshots.length\n * plateaus once the cap is reached).\n */\n snapshotSequence: number;\n}\n\nexport interface CheckpointConfig {\n enabled: boolean;\n /** Maximum number of snapshots to retain before evicting oldest. Default: 100. */\n maxSnapshots?: number;\n /** Base directory for backup files. Default: \".noumen/checkpoints\". */\n backupDir?: string;\n}\n\nexport type DiffStats =\n | {\n filesChanged?: string[];\n insertions: number;\n deletions: number;\n }\n | undefined;\n\nexport function createCheckpointState(): FileCheckpointState {\n return {\n snapshots: [],\n trackedFiles: new Set(),\n snapshotSequence: 0,\n };\n}\n","import type {\n HookEvent,\n HookDefinition,\n HookInput,\n HookOutput,\n PreToolUseHookInput,\n PreToolUseHookOutput,\n PostToolUseHookInput,\n PostToolUseHookOutput,\n PostToolUseFailureHookInput,\n PostToolUseFailureHookOutput,\n} from \"./types.js\";\n\nconst DEFAULT_HOOK_TIMEOUT_MS = 30_000;\n\nfunction withTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n label: string,\n): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`Hook \"${label}\" timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n promise.then(\n (v) => { clearTimeout(timer); resolve(v); },\n (e) => { clearTimeout(timer); reject(e); },\n );\n });\n}\n\n/**\n * Match a tool name against an optional glob-like matcher.\n * Supports '*' as a wildcard prefix/suffix (e.g. \"mcp__*\", \"*File\").\n */\nfunction matchesPattern(toolName: string, matcher: string): boolean {\n if (matcher === \"*\") return true;\n if (matcher.endsWith(\"*\")) {\n return toolName.startsWith(matcher.slice(0, -1));\n }\n if (matcher.startsWith(\"*\")) {\n return toolName.endsWith(matcher.slice(1));\n }\n return toolName === matcher;\n}\n\nfunction getMatchingHooks(\n hooks: HookDefinition[],\n event: HookEvent,\n toolName?: string,\n): HookDefinition[] {\n return hooks.filter((h) => {\n if (h.event !== event) return false;\n if (h.matcher && toolName) {\n return matchesPattern(toolName, h.matcher);\n }\n return !h.matcher;\n });\n}\n\n/**\n * Run pre-tool-use hooks. Returns a merged output where later hooks override\n * earlier ones. A 'deny' decision from any hook short-circuits.\n */\nexport async function runPreToolUseHooks(\n hooks: HookDefinition[],\n input: PreToolUseHookInput,\n): Promise<PreToolUseHookOutput> {\n const matching = getMatchingHooks(hooks, \"PreToolUse\", input.toolName);\n let merged: PreToolUseHookOutput = {};\n\n for (const hook of matching) {\n try {\n const label = hook.matcher ?? \"PreToolUse\";\n const output = (await withTimeout(\n Promise.resolve(hook.handler(input)),\n DEFAULT_HOOK_TIMEOUT_MS,\n label,\n )) as PreToolUseHookOutput | void;\n if (!output) continue;\n\n if (output.decision === \"deny\") {\n return output;\n }\n if (output.updatedInput !== undefined) {\n merged.updatedInput = output.updatedInput;\n input = { ...input, toolInput: output.updatedInput };\n }\n if (output.decision !== undefined) merged.decision = output.decision;\n if (output.message !== undefined) merged.message = output.message;\n if (output.preventContinuation !== undefined) {\n merged.preventContinuation = output.preventContinuation;\n }\n } catch (err) {\n console.warn(`[noumen/hooks] PreToolUse hook failed:`, err instanceof Error ? err.message : err);\n }\n }\n\n return merged;\n}\n\n/**\n * Run post-tool-use hooks. Returns merged output.\n */\nexport async function runPostToolUseHooks(\n hooks: HookDefinition[],\n input: PostToolUseHookInput,\n): Promise<PostToolUseHookOutput> {\n const matching = getMatchingHooks(hooks, \"PostToolUse\", input.toolName);\n let merged: PostToolUseHookOutput = {};\n\n for (const hook of matching) {\n try {\n const label = hook.matcher ?? \"PostToolUse\";\n const output = (await withTimeout(\n Promise.resolve(hook.handler(input)),\n DEFAULT_HOOK_TIMEOUT_MS,\n label,\n )) as PostToolUseHookOutput | void;\n if (!output) continue;\n\n if (output.updatedOutput !== undefined) {\n merged.updatedOutput = output.updatedOutput;\n input = { ...input, toolOutput: output.updatedOutput };\n }\n if (output.preventContinuation !== undefined) {\n merged.preventContinuation = output.preventContinuation;\n }\n } catch (err) {\n console.warn(`[noumen/hooks] PostToolUse hook failed:`, err instanceof Error ? err.message : err);\n }\n }\n\n return merged;\n}\n\n/**\n * Run post-tool-use-failure hooks. Same shape as post-tool-use hooks but\n * triggers on the PostToolUseFailure event, fired only when `isError` is true.\n */\nexport async function runPostToolUseFailureHooks(\n hooks: HookDefinition[],\n input: PostToolUseFailureHookInput,\n): Promise<PostToolUseFailureHookOutput> {\n const matching = getMatchingHooks(hooks, \"PostToolUseFailure\", input.toolName);\n let merged: PostToolUseFailureHookOutput = {};\n\n for (const hook of matching) {\n try {\n const label = hook.matcher ?? \"PostToolUseFailure\";\n const output = (await withTimeout(\n Promise.resolve(hook.handler(input)),\n DEFAULT_HOOK_TIMEOUT_MS,\n label,\n )) as PostToolUseFailureHookOutput | void;\n if (!output) continue;\n\n if (output.updatedOutput !== undefined) {\n merged.updatedOutput = output.updatedOutput;\n input = { ...input, toolOutput: output.updatedOutput };\n }\n if (output.preventContinuation !== undefined) {\n merged.preventContinuation = output.preventContinuation;\n }\n } catch (err) {\n console.warn(`[noumen/hooks] PostToolUseFailure hook failed:`, err instanceof Error ? err.message : err);\n }\n }\n\n return merged;\n}\n\n/**\n * Run notification hooks concurrently (fire-and-forget, no return value).\n */\nexport async function runNotificationHooks(\n hooks: HookDefinition[],\n event: HookEvent,\n input: HookInput,\n): Promise<void> {\n const matching = getMatchingHooks(hooks, event);\n if (matching.length === 0) return;\n\n const results = await Promise.allSettled(\n matching.map((hook) => {\n const label = hook.matcher ?? String(event);\n return withTimeout(\n Promise.resolve(hook.handler(input)),\n DEFAULT_HOOK_TIMEOUT_MS,\n label,\n );\n }),\n );\n\n for (const result of results) {\n if (result.status === \"rejected\") {\n const err = result.reason;\n console.warn(`[noumen/hooks] ${event} notification hook failed:`, err instanceof Error ? err.message : err);\n }\n }\n}\n","/**\n * Model-facing prompt for the Agent (subagent) tool.\n * Adapted from claude-code's AgentTool/prompt.ts — simplified for noumen's\n * library context without coordinator/fork/subscription-specific logic.\n */\n\nexport const AGENT_PROMPT = `Launch a new agent to handle complex, multi-step tasks autonomously.\n\nThe Agent tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent runs with its own conversation context and a configurable subset of tools.\n\nWhen NOT to use the Agent tool:\n- If you want to read a specific file path, use the ReadFile or Glob tool instead to find the match more quickly\n- If you are searching for a specific class definition like \"class Foo\", use the Glob tool instead\n- If you are searching for code within a specific file or set of 2-3 files, use the ReadFile tool instead\n\nUsage notes:\n- Always include a short description (3-5 words) summarizing what the agent will do\n- Launch multiple agents concurrently whenever possible to maximize performance; to do that, use a single message with multiple tool uses\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n- Each Agent invocation starts fresh — provide a complete task description.\n- The agent's outputs should generally be trusted\n- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.)\n\n## Writing the prompt\n\nBrief the agent like a smart colleague who just walked into the room — it hasn't seen this conversation, doesn't know what you've tried, doesn't understand why this task matters.\n- Explain what you're trying to accomplish and why.\n- Describe what you've already learned or ruled out.\n- Give enough context about the surrounding problem that the agent can make judgment calls rather than just following a narrow instruction.\n- If you need a short response, say so (\"report in under 200 words\").\n- Lookups: hand over the exact command. Investigations: hand over the question — prescribed steps become dead weight when the premise is wrong.\n\nTerse command-style prompts produce shallow, generic work.\n\n**Never delegate understanding.** Don't write \"based on your findings, fix the bug\" or \"based on the research, implement it.\" Those phrases push synthesis onto the agent instead of doing it yourself. Write prompts that prove you understood: include file paths, line numbers, what specifically to change.\n`;\n","import type { Tool, ToolResult, ToolContext } from \"./types.js\";\nimport { runNotificationHooks } from \"../hooks/runner.js\";\nimport { AGENT_PROMPT } from \"./prompts/agent.js\";\n\nconst DEFAULT_MAX_TURNS = 25;\n\nexport const agentTool: Tool = {\n name: \"Agent\",\n description:\n \"Spawn an isolated subagent to handle a focused subtask. The subagent \" +\n \"runs in its own conversation context and returns its final response. \" +\n \"Use for tasks that benefit from independent context (research, \" +\n \"code generation, analysis) or when you want to parallelise work.\",\n prompt: AGENT_PROMPT,\n isReadOnly: false,\n isConcurrencySafe: true,\n parameters: {\n type: \"object\",\n properties: {\n prompt: {\n type: \"string\",\n description:\n \"The task description for the subagent. Be specific about what to do and what to return.\",\n },\n systemPrompt: {\n type: \"string\",\n description: \"Optional system prompt override for the subagent.\",\n },\n allowedTools: {\n type: \"string\",\n description:\n \"Comma-separated list of tool names the subagent may use. Omit to inherit all parent tools except Agent.\",\n },\n async: {\n type: \"string\",\n description:\n 'Set to \"true\" to run the agent in the background and return immediately with a taskId. ' +\n \"Check status with TaskGet.\",\n enum: [\"true\", \"false\"],\n },\n },\n required: [\"prompt\"],\n },\n\n async call(\n args: Record<string, unknown>,\n ctx: ToolContext,\n ): Promise<ToolResult> {\n if (!ctx.spawnSubagent) {\n return {\n content: \"Subagents are not enabled. Set enableSubagents: true in AgentOptions.\",\n isError: true,\n };\n }\n\n const prompt = args.prompt as string;\n const systemPrompt = args.systemPrompt as string | undefined;\n const allowedToolsRaw = args.allowedTools as string | undefined;\n const allowedTools = allowedToolsRaw\n ? allowedToolsRaw.split(\",\").map((t) => t.trim()).filter(Boolean)\n : undefined;\n const isAsync = args.async === \"true\";\n\n const maxTurns = DEFAULT_MAX_TURNS;\n const { sessionId, events } = ctx.spawnSubagent({\n prompt,\n systemPrompt,\n allowedTools,\n maxTurns,\n });\n\n // Fire SubagentStart hook\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStart\", {\n event: \"SubagentStart\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n prompt,\n });\n }\n\n if (isAsync && ctx.taskStore) {\n const task = await ctx.taskStore.create({\n subject: `Agent: ${prompt.slice(0, 80)}`,\n description: `Async agent running with sessionId: ${sessionId}`,\n });\n await ctx.taskStore.update(task.id, { status: \"in_progress\" });\n\n // Fire and forget — collect results into task store when done.\n (async () => {\n const assistantTexts: string[] = [];\n try {\n for await (const event of events) {\n if (event.type === \"message_complete\" && event.message.content) {\n assistantTexts.push(event.message.content);\n }\n if (event.type === \"turn_complete\") break;\n }\n const result = assistantTexts.join(\"\\n\\n\") || \"(no output)\";\n await ctx.taskStore!.update(task.id, {\n status: \"completed\",\n description: result.slice(0, 10_000),\n });\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStop\", {\n event: \"SubagentStop\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n result,\n });\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n await ctx.taskStore!.update(task.id, {\n status: \"completed\",\n description: `Error: ${msg}`,\n });\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStop\", {\n event: \"SubagentStop\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n result: `Error: ${msg}`,\n });\n }\n }\n })();\n\n return {\n content: JSON.stringify({\n taskId: task.id,\n sessionId,\n message: \"Agent launched in background. Use TaskGet to check status.\",\n }),\n };\n }\n\n // Synchronous mode (original behavior)\n const assistantTexts: string[] = [];\n let turnCount = 0;\n\n try {\n for await (const event of events) {\n if (event.type === \"message_complete\" && event.message.content) {\n assistantTexts.push(event.message.content);\n }\n if (event.type === \"turn_complete\") {\n turnCount++;\n if (turnCount >= maxTurns) {\n break;\n }\n }\n if (event.type === \"error\") {\n const errorResult = `Subagent error: ${event.error.message}`;\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStop\", {\n event: \"SubagentStop\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n result: errorResult,\n });\n }\n return { content: errorResult, isError: true };\n }\n }\n } catch (err) {\n const errorResult = `Subagent failed: ${err instanceof Error ? err.message : String(err)}`;\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStop\", {\n event: \"SubagentStop\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n result: errorResult,\n });\n }\n return { content: errorResult, isError: true };\n }\n\n const result = assistantTexts.join(\"\\n\\n\");\n\n if (ctx.hooks && ctx.hooks.length > 0) {\n await runNotificationHooks(ctx.hooks, \"SubagentStop\", {\n event: \"SubagentStop\",\n sessionId,\n parentSessionId: ctx.sessionId ?? \"\",\n result: result || \"(subagent produced no output)\",\n });\n }\n\n return {\n content: result || \"(subagent produced no output)\",\n };\n },\n};\n","/**\n * Model-facing prompt for the WebSearch tool.\n * Adapted from claude-code's WebSearchTool/prompt.ts.\n */\n\nfunction getCurrentMonthYear(): string {\n const d = new Date();\n return d.toLocaleString(\"en-US\", { month: \"long\", year: \"numeric\" });\n}\n\nexport function getWebSearchPrompt(): string {\n const currentMonthYear = getCurrentMonthYear();\n return `Search the web for real-time information about any topic. Returns summarized information from search results and relevant URLs.\n\n- Provides up-to-date information for current events and recent data\n- Returns search result information including links as markdown hyperlinks\n- Use this tool for accessing information beyond the model's knowledge cutoff\n\nCRITICAL REQUIREMENT:\n- After answering the user's question, you MUST include a \"Sources:\" section at the end of your response\n- In the Sources section, list all relevant URLs from the search results as markdown hyperlinks: [Title](URL)\n- This is MANDATORY — never skip including sources in your response\n- Example format:\n\n [Your answer here]\n\n Sources:\n - [Source Title 1](https://example.com/1)\n - [Source Title 2](https://example.com/2)\n\nIMPORTANT — Use the correct year in search queries:\n- The current month is ${currentMonthYear}. You MUST use this year when searching for recent information, documentation, or current events.\n- Example: If the user asks for \"latest React docs\", search for \"React documentation\" with the current year, NOT last year.\n`;\n}\n","import type { Tool, ToolResult, ToolContext } from \"./types.js\";\nimport { getWebSearchPrompt } from \"./prompts/web-search.js\";\n\nexport interface WebSearchResult {\n title: string;\n url: string;\n snippet: string;\n}\n\nexport interface WebSearchConfig {\n search: (query: string, domains?: string[]) => Promise<WebSearchResult[]>;\n}\n\n/**\n * Create a WebSearch tool backed by a user-provided search implementation.\n * This keeps noumen provider-agnostic — plug in Tavily, SerpAPI, Brave Search, etc.\n *\n * @example\n * ```ts\n * const webSearch = createWebSearchTool({\n * search: async (query) => {\n * const res = await tavily.search({ query });\n * return res.results.map(r => ({ title: r.title, url: r.url, snippet: r.content }));\n * },\n * });\n * ```\n */\nexport function createWebSearchTool(config: WebSearchConfig): Tool {\n return {\n name: \"WebSearch\",\n description:\n \"Search the web for real-time information. Returns titles, URLs, and \" +\n \"snippets from search results. Use when you need up-to-date information \" +\n \"not available in the local codebase.\",\n prompt: getWebSearchPrompt,\n isReadOnly: true,\n isConcurrencySafe: true,\n parameters: {\n type: \"object\",\n properties: {\n query: {\n type: \"string\",\n description: \"The search query\",\n },\n domains: {\n type: \"string\",\n description:\n \"Comma-separated list of domains to restrict search to (e.g. 'docs.python.org,stackoverflow.com')\",\n },\n },\n required: [\"query\"],\n },\n\n async call(\n args: Record<string, unknown>,\n _ctx: ToolContext,\n ): Promise<ToolResult> {\n const query = args.query as string;\n const domainsRaw = args.domains as string | undefined;\n const domains = domainsRaw\n ? domainsRaw.split(\",\").map((d) => d.trim()).filter(Boolean)\n : undefined;\n\n try {\n const results = await config.search(query, domains);\n\n if (results.length === 0) {\n return { content: \"No search results found.\" };\n }\n\n const formatted = results\n .map(\n (r, i) =>\n `${i + 1}. [${r.title}](${r.url})\\n ${r.snippet}`,\n )\n .join(\"\\n\\n\");\n\n return { content: `Search results for: ${query}\\n\\n${formatted}` };\n } catch (err) {\n return {\n content: `Search error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n }\n },\n };\n}\n\n/**\n * Default WebSearch tool that returns a helpful error when no search provider\n * is configured. Register this as a placeholder; consumers should replace\n * it with `createWebSearchTool(config)`.\n */\nexport const webSearchToolPlaceholder: Tool = {\n name: \"WebSearch\",\n description: \"Search the web (requires configuration — see noumen docs).\",\n isReadOnly: true,\n isConcurrencySafe: true,\n parameters: {\n type: \"object\",\n properties: {\n query: { type: \"string\", description: \"The search query\" },\n },\n required: [\"query\"],\n },\n\n async call(): Promise<ToolResult> {\n return {\n content:\n \"WebSearch is not configured. Provide a search implementation \" +\n \"via AgentOptions.options.webSearch or createWebSearchTool().\",\n isError: true,\n };\n },\n};\n","import type { Tool } from \"./types.js\";\n\nexport const taskCreateTool: Tool = {\n name: \"TaskCreate\",\n description:\n \"Create a new task/todo item for tracking work. Use this to decompose complex work into trackable steps.\",\n parameters: {\n type: \"object\",\n properties: {\n subject: {\n type: \"string\",\n description: \"Short title for the task\",\n },\n description: {\n type: \"string\",\n description: \"Optional detailed description of the task\",\n },\n },\n required: [\"subject\"],\n },\n isReadOnly: false,\n isConcurrencySafe: true,\n\n async call(args, ctx) {\n if (!ctx.taskStore) {\n return { content: \"Task management is not enabled.\", isError: true };\n }\n const subject = args.subject as string;\n const description = args.description as string | undefined;\n\n const task = await ctx.taskStore.create({ subject, description });\n return {\n content: JSON.stringify({ id: task.id, subject: task.subject }),\n };\n },\n};\n","import type { Tool } from \"./types.js\";\n\nexport const taskListTool: Tool = {\n name: \"TaskList\",\n description:\n \"List all tasks with their current status and dependency information.\",\n parameters: {\n type: \"object\",\n properties: {},\n },\n isReadOnly: true,\n isConcurrencySafe: true,\n\n async call(_args, ctx) {\n if (!ctx.taskStore) {\n return { content: \"Task management is not enabled.\", isError: true };\n }\n const tasks = await ctx.taskStore.list();\n\n const filtered = tasks.map((t) => ({\n id: t.id,\n subject: t.subject,\n status: t.status,\n owner: t.owner,\n blockedBy: t.blockedBy.filter((dep) => {\n const blocking = tasks.find((bt) => bt.id === dep);\n return blocking && blocking.status !== \"completed\";\n }),\n }));\n\n return { content: JSON.stringify({ tasks: filtered }, null, 2) };\n },\n};\n","import type { Tool } from \"./types.js\";\n\nexport const taskGetTool: Tool = {\n name: \"TaskGet\",\n description: \"Get details of a specific task by ID.\",\n parameters: {\n type: \"object\",\n properties: {\n taskId: {\n type: \"string\",\n description: \"The task ID to retrieve\",\n },\n },\n required: [\"taskId\"],\n },\n isReadOnly: true,\n isConcurrencySafe: true,\n\n async call(args, ctx) {\n if (!ctx.taskStore) {\n return { content: \"Task management is not enabled.\", isError: true };\n }\n const task = await ctx.taskStore.get(args.taskId as string);\n if (!task) {\n return { content: `Task ${args.taskId} not found.`, isError: true };\n }\n return { content: JSON.stringify({ task }, null, 2) };\n },\n};\n","import type { Tool } from \"./types.js\";\nimport type { TaskStatus } from \"../tasks/types.js\";\n\nexport const taskUpdateTool: Tool = {\n name: \"TaskUpdate\",\n description:\n \"Update a task's status, description, or dependencies. Set status to 'completed' when done, or 'deleted' to remove.\",\n parameters: {\n type: \"object\",\n properties: {\n taskId: {\n type: \"string\",\n description: \"The task ID to update\",\n },\n status: {\n type: \"string\",\n description: \"New status: pending, in_progress, completed, or deleted\",\n enum: [\"pending\", \"in_progress\", \"completed\", \"deleted\"],\n },\n description: {\n type: \"string\",\n description: \"Updated description\",\n },\n owner: {\n type: \"string\",\n description: \"Name of the agent/user that owns this task\",\n },\n blockedBy: {\n type: \"string\",\n description:\n \"Comma-separated list of task IDs that must complete before this task\",\n },\n },\n required: [\"taskId\"],\n },\n isReadOnly: false,\n isConcurrencySafe: true,\n\n async call(args, ctx) {\n if (!ctx.taskStore) {\n return { content: \"Task management is not enabled.\", isError: true };\n }\n\n const taskId = args.taskId as string;\n const status = args.status as string | undefined;\n\n if (status === \"deleted\") {\n const deleted = await ctx.taskStore.delete(taskId);\n if (!deleted) {\n return { content: `Task ${taskId} not found.`, isError: true };\n }\n return { content: JSON.stringify({ success: true, taskId, deleted: true }) };\n }\n\n const blockedByRaw = args.blockedBy as string | undefined;\n const blockedBy = blockedByRaw\n ? blockedByRaw.split(\",\").map((s) => s.trim()).filter(Boolean)\n : undefined;\n\n const task = await ctx.taskStore.update(taskId, {\n status: status as TaskStatus | undefined,\n description: args.description as string | undefined,\n owner: args.owner as string | undefined,\n blockedBy,\n });\n\n if (!task) {\n return { content: `Task ${taskId} not found.`, isError: true };\n }\n\n return {\n content: JSON.stringify({\n success: true,\n taskId,\n updatedFields: Object.keys(args).filter((k) => k !== \"taskId\"),\n }),\n };\n },\n};\n","import type { Tool } from \"./types.js\";\n\nexport const enterPlanModeTool: Tool = {\n name: \"EnterPlanMode\",\n description:\n \"Enter plan mode to explore the codebase and create a plan before making changes. \" +\n \"In plan mode, file writes and edits are restricted. Use this when you need to \" +\n \"understand the codebase structure before implementing changes.\",\n parameters: {\n type: \"object\",\n properties: {},\n },\n isReadOnly: true,\n isConcurrencySafe: true,\n\n async call(_args, ctx) {\n if (!ctx.setPermissionMode || !ctx.getPermissionMode) {\n return {\n content: \"Plan mode is not enabled.\",\n isError: true,\n };\n }\n\n const currentMode = ctx.getPermissionMode();\n if (currentMode === \"plan\") {\n return {\n content: \"Already in plan mode.\",\n isError: true,\n };\n }\n\n ctx.setPermissionMode(\"plan\");\n\n return {\n content: JSON.stringify({\n previousMode: currentMode,\n currentMode: \"plan\",\n message:\n \"Entered plan mode. File writes and edits are now restricted. \" +\n \"Use read-only tools (ReadFile, Glob, Grep, Bash with read-only commands) \" +\n \"to explore the codebase. When you have a plan, use ExitPlanMode to \" +\n \"return to the previous mode and begin implementation.\",\n }),\n };\n },\n};\n\nexport const exitPlanModeTool: Tool = {\n name: \"ExitPlanMode\",\n description:\n \"Exit plan mode and return to the previous permission mode. \" +\n \"Optionally provide a plan summary that will be included in the conversation.\",\n parameters: {\n type: \"object\",\n properties: {\n plan: {\n type: \"string\",\n description:\n \"Optional plan summary describing what you intend to implement\",\n },\n },\n },\n isReadOnly: true,\n isConcurrencySafe: true,\n\n async call(args, ctx) {\n if (!ctx.setPermissionMode || !ctx.getPermissionMode) {\n return {\n content: \"Plan mode is not enabled.\",\n isError: true,\n };\n }\n\n const currentMode = ctx.getPermissionMode();\n if (currentMode !== \"plan\") {\n return {\n content: \"Not currently in plan mode.\",\n isError: true,\n };\n }\n\n // Restore to default mode (the Thread manages prePlanMode state)\n ctx.setPermissionMode(\"default\");\n\n const plan = args.plan as string | undefined;\n const result: Record<string, unknown> = {\n currentMode: \"default\",\n message: \"Exited plan mode. You can now make changes.\",\n };\n if (plan) {\n result.plan = plan;\n }\n\n return { content: JSON.stringify(result) };\n },\n};\n","import type { VirtualComputer } from \"../virtual/computer.js\";\n\nexport interface WorktreeInfo {\n path: string;\n branch: string;\n head?: string;\n}\n\n/**\n * Find the git root directory from a given cwd.\n */\nexport async function findGitRoot(\n computer: VirtualComputer,\n cwd: string,\n): Promise<string | null> {\n const result = await computer.executeCommand(\n \"git rev-parse --show-toplevel\",\n { cwd, timeout: 5000 },\n );\n if (result.exitCode !== 0) return null;\n return result.stdout.trim();\n}\n\n/**\n * Get the default branch name (main/master).\n */\nexport async function getDefaultBranch(\n computer: VirtualComputer,\n cwd: string,\n): Promise<string> {\n const result = await computer.executeCommand(\n \"git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null || echo refs/heads/main\",\n { cwd, timeout: 5000 },\n );\n const ref = result.stdout.trim();\n return ref.replace(\"refs/remotes/origin/\", \"\").replace(\"refs/heads/\", \"\");\n}\n\n/**\n * Create a git worktree at the given path with the given branch name.\n */\nexport async function createWorktree(\n computer: VirtualComputer,\n repoRoot: string,\n worktreePath: string,\n branchName: string,\n baseBranch?: string,\n): Promise<{ success: boolean; error?: string }> {\n const base = baseBranch ?? (await getDefaultBranch(computer, repoRoot));\n const cmd = `git worktree add -B \"${branchName}\" \"${worktreePath}\" \"${base}\"`;\n const result = await computer.executeCommand(cmd, {\n cwd: repoRoot,\n timeout: 30000,\n });\n\n if (result.exitCode !== 0) {\n return { success: false, error: result.stderr.trim() || result.stdout.trim() };\n }\n return { success: true };\n}\n\n/**\n * Remove a git worktree.\n */\nexport async function removeWorktree(\n computer: VirtualComputer,\n repoRoot: string,\n worktreePath: string,\n branchName?: string,\n): Promise<{ success: boolean; error?: string }> {\n const rmResult = await computer.executeCommand(\n `git worktree remove --force \"${worktreePath}\"`,\n { cwd: repoRoot, timeout: 15000 },\n );\n\n if (rmResult.exitCode !== 0) {\n return { success: false, error: rmResult.stderr.trim() };\n }\n\n if (branchName) {\n await computer.executeCommand(`git branch -D \"${branchName}\"`, {\n cwd: repoRoot,\n timeout: 5000,\n });\n }\n\n return { success: true };\n}\n\n/**\n * List existing git worktrees.\n */\nexport async function listWorktrees(\n computer: VirtualComputer,\n cwd: string,\n): Promise<WorktreeInfo[]> {\n const result = await computer.executeCommand(\"git worktree list --porcelain\", {\n cwd,\n timeout: 5000,\n });\n if (result.exitCode !== 0) return [];\n\n const worktrees: WorktreeInfo[] = [];\n let current: Partial<WorktreeInfo> = {};\n\n for (const line of result.stdout.split(\"\\n\")) {\n if (line.startsWith(\"worktree \")) {\n if (current.path) worktrees.push(current as WorktreeInfo);\n current = { path: line.slice(9) };\n } else if (line.startsWith(\"HEAD \")) {\n current.head = line.slice(5);\n } else if (line.startsWith(\"branch \")) {\n current.branch = line.slice(7).replace(\"refs/heads/\", \"\");\n } else if (line === \"\") {\n if (current.path) worktrees.push(current as WorktreeInfo);\n current = {};\n }\n }\n if (current.path) worktrees.push(current as WorktreeInfo);\n\n return worktrees;\n}\n\n/**\n * Check if a worktree has uncommitted changes or unpushed commits.\n */\nexport async function getWorktreeChanges(\n computer: VirtualComputer,\n worktreePath: string,\n): Promise<{ hasChanges: boolean; uncommittedFiles: number; unpushedCommits: number }> {\n const statusResult = await computer.executeCommand(\n \"git status --porcelain\",\n { cwd: worktreePath, timeout: 5000 },\n );\n const uncommittedFiles = statusResult.stdout\n .trim()\n .split(\"\\n\")\n .filter((l) => l.length > 0).length;\n\n const logResult = await computer.executeCommand(\n \"git rev-list --count @{upstream}..HEAD 2>/dev/null || echo 0\",\n { cwd: worktreePath, timeout: 5000 },\n );\n const unpushedCommits = parseInt(logResult.stdout.trim(), 10) || 0;\n\n return {\n hasChanges: uncommittedFiles > 0 || unpushedCommits > 0,\n uncommittedFiles,\n unpushedCommits,\n };\n}\n\n/**\n * Sanitize a name for use as a worktree slug/branch name.\n */\nexport function sanitizeWorktreeSlug(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 50);\n}\n","import type { Tool } from \"./types.js\";\nimport {\n findGitRoot,\n createWorktree,\n removeWorktree,\n getWorktreeChanges,\n sanitizeWorktreeSlug,\n} from \"../utils/worktree.js\";\n\nexport const enterWorktreeTool: Tool = {\n name: \"EnterWorktree\",\n description:\n \"Create an isolated git worktree and switch into it. This creates a separate \" +\n \"working copy on a new branch so you can make changes without affecting the \" +\n \"main working directory. Use this for parallel or experimental work.\",\n parameters: {\n type: \"object\",\n properties: {\n name: {\n type: \"string\",\n description:\n \"Optional name for the worktree (used as branch name suffix). \" +\n \"If omitted, a default name is generated.\",\n },\n },\n },\n isReadOnly: false,\n\n async call(args, ctx) {\n const repoRoot = await findGitRoot(ctx.computer, ctx.cwd);\n if (!repoRoot) {\n return {\n content: \"Not inside a git repository. Worktrees require git.\",\n isError: true,\n };\n }\n\n const slug = sanitizeWorktreeSlug(\n (args.name as string) || `noumen-${Date.now()}`,\n );\n const worktreePath = `${repoRoot}/.noumen/worktrees/${slug}`;\n const branchName = `worktree-${slug}`;\n\n const result = await createWorktree(\n ctx.computer,\n repoRoot,\n worktreePath,\n branchName,\n );\n\n if (!result.success) {\n return {\n content: `Failed to create worktree: ${result.error}`,\n isError: true,\n };\n }\n\n if (ctx.setCwd) {\n ctx.setCwd(worktreePath);\n }\n\n return {\n content: JSON.stringify({\n worktreePath,\n worktreeBranch: branchName,\n previousCwd: ctx.cwd,\n message: `Created worktree at ${worktreePath} on branch ${branchName}. ` +\n \"Working directory switched. Use ExitWorktree when done.\",\n }),\n };\n },\n};\n\nexport const exitWorktreeTool: Tool = {\n name: \"ExitWorktree\",\n description:\n \"Exit the current worktree and return to the original working directory. \" +\n 'Use action \"keep\" to preserve the worktree, or \"remove\" to clean it up.',\n parameters: {\n type: \"object\",\n properties: {\n action: {\n type: \"string\",\n description: 'Whether to \"keep\" the worktree or \"remove\" it',\n enum: [\"keep\", \"remove\"],\n },\n worktreePath: {\n type: \"string\",\n description: \"Path to the worktree to exit (usually the current cwd)\",\n },\n originalCwd: {\n type: \"string\",\n description: \"Original working directory to return to\",\n },\n },\n required: [\"action\", \"worktreePath\", \"originalCwd\"],\n },\n isReadOnly: false,\n\n async call(args, ctx) {\n const action = args.action as \"keep\" | \"remove\";\n const worktreePath = args.worktreePath as string;\n const originalCwd = args.originalCwd as string;\n\n if (action === \"remove\") {\n const changes = await getWorktreeChanges(ctx.computer, worktreePath);\n if (changes.hasChanges) {\n return {\n content: JSON.stringify({\n error: \"Worktree has uncommitted changes or unpushed commits.\",\n uncommittedFiles: changes.uncommittedFiles,\n unpushedCommits: changes.unpushedCommits,\n message:\n \"Cannot remove worktree with pending changes. \" +\n 'Commit/push your changes first, or use action \"keep\".',\n }),\n isError: true,\n };\n }\n\n const repoRoot = await findGitRoot(ctx.computer, originalCwd);\n if (repoRoot) {\n const branchMatch = worktreePath.match(/worktrees\\/(.+)$/);\n const branchName = branchMatch\n ? `worktree-${branchMatch[1]}`\n : undefined;\n const result = await removeWorktree(\n ctx.computer,\n repoRoot,\n worktreePath,\n branchName,\n );\n if (!result.success) {\n return {\n content: `Failed to remove worktree: ${result.error}`,\n isError: true,\n };\n }\n }\n }\n\n if (ctx.setCwd) {\n ctx.setCwd(originalCwd);\n }\n\n return {\n content: JSON.stringify({\n action,\n restoredCwd: originalCwd,\n message:\n action === \"remove\"\n ? \"Worktree removed and working directory restored.\"\n : \"Worktree kept. Working directory restored.\",\n }),\n };\n },\n};\n","import type { ModelPricing, UsageRecord } from \"./types.js\";\n\n// Pricing tiers (USD per 1M tokens), sourced from public pricing docs\nconst TIER_3_15: ModelPricing = { inputTokens: 3, outputTokens: 15, cacheReadTokens: 0.3, cacheWriteTokens: 3.75 };\nconst TIER_5_25: ModelPricing = { inputTokens: 5, outputTokens: 25, cacheReadTokens: 0.5, cacheWriteTokens: 6.25 };\nconst TIER_15_75: ModelPricing = { inputTokens: 15, outputTokens: 75, cacheReadTokens: 1.5, cacheWriteTokens: 18.75 };\nconst TIER_30_150: ModelPricing = { inputTokens: 30, outputTokens: 150, cacheReadTokens: 3, cacheWriteTokens: 37.5 };\nconst TIER_HAIKU_35: ModelPricing = { inputTokens: 0.8, outputTokens: 4, cacheReadTokens: 0.08, cacheWriteTokens: 1 };\nconst TIER_HAIKU_45: ModelPricing = { inputTokens: 1, outputTokens: 5, cacheReadTokens: 0.1, cacheWriteTokens: 1.25 };\n\n// OpenAI tiers\nconst TIER_GPT4O: ModelPricing = { inputTokens: 2.5, outputTokens: 10, cacheReadTokens: 1.25 };\nconst TIER_GPT4O_MINI: ModelPricing = { inputTokens: 0.15, outputTokens: 0.6, cacheReadTokens: 0.075 };\nconst TIER_GPT41: ModelPricing = { inputTokens: 2, outputTokens: 8, cacheReadTokens: 0.5 };\nconst TIER_GPT41_MINI: ModelPricing = { inputTokens: 0.4, outputTokens: 1.6, cacheReadTokens: 0.1 };\nconst TIER_GPT41_NANO: ModelPricing = { inputTokens: 0.1, outputTokens: 0.4, cacheReadTokens: 0.025 };\nconst TIER_O3: ModelPricing = { inputTokens: 2, outputTokens: 8, cacheReadTokens: 0.5 };\nconst TIER_O3_MINI: ModelPricing = { inputTokens: 1.1, outputTokens: 4.4, cacheReadTokens: 0.275 };\nconst TIER_O4_MINI: ModelPricing = { inputTokens: 1.1, outputTokens: 4.4, cacheReadTokens: 0.275 };\n\n// Google Gemini tiers\nconst TIER_GEMINI_FLASH: ModelPricing = { inputTokens: 0.075, outputTokens: 0.3 };\nconst TIER_GEMINI_PRO: ModelPricing = { inputTokens: 1.25, outputTokens: 5 };\nconst TIER_GEMINI_FLASH_LITE: ModelPricing = { inputTokens: 0.0375, outputTokens: 0.15 };\n\n/**\n * Default pricing table for common models. Keys are matched as substrings\n * against the model ID so versioned model strings (e.g. `claude-sonnet-4`)\n * resolve correctly.\n */\nexport const DEFAULT_PRICING: Record<string, ModelPricing> = {\n // Anthropic\n \"claude-sonnet-4\": TIER_5_25,\n \"claude-opus-4\": TIER_15_75,\n \"claude-3-5-sonnet\": TIER_3_15,\n \"claude-3-5-haiku\": TIER_HAIKU_45,\n \"claude-3-haiku\": TIER_HAIKU_35,\n \"claude-3-opus\": TIER_30_150,\n\n // OpenAI\n \"gpt-4o-mini\": TIER_GPT4O_MINI,\n \"gpt-4o\": TIER_GPT4O,\n \"gpt-4.1-mini\": TIER_GPT41_MINI,\n \"gpt-4.1-nano\": TIER_GPT41_NANO,\n \"gpt-4.1\": TIER_GPT41,\n \"o4-mini\": TIER_O4_MINI,\n \"o3-mini\": TIER_O3_MINI,\n \"o3\": TIER_O3,\n\n // Google Gemini\n \"gemini-2.5-flash\": TIER_GEMINI_FLASH,\n \"gemini-2.5-pro\": TIER_GEMINI_PRO,\n \"gemini-2.0-flash\": TIER_GEMINI_FLASH,\n \"gemini-2.0-flash-lite\": TIER_GEMINI_FLASH_LITE,\n \"gemini-1.5-flash\": TIER_GEMINI_FLASH,\n \"gemini-1.5-pro\": TIER_GEMINI_PRO,\n};\n\n/**\n * Find pricing for a model by checking if the model string contains any\n * known pricing key as a substring. More specific keys (longer) are\n * checked first to ensure e.g. \"gpt-4o-mini\" matches before \"gpt-4o\".\n */\nexport function findModelPricing(\n model: string,\n pricing: Record<string, ModelPricing>,\n): ModelPricing | null {\n const sortedKeys = Object.keys(pricing).sort((a, b) => b.length - a.length);\n for (const key of sortedKeys) {\n if (model.includes(key)) {\n return pricing[key];\n }\n }\n return null;\n}\n\n/**\n * Set of models already warned about to avoid log spam.\n */\nconst warnedUnknownModels = new Set<string>();\n\n/**\n * Calculate USD cost for a usage record using the given pricing table.\n * Returns 0 if the model is not found in the pricing table and logs a\n * one-time warning per unknown model.\n */\nexport function calculateCost(\n model: string,\n usage: UsageRecord,\n pricing: Record<string, ModelPricing> = DEFAULT_PRICING,\n): number {\n const p = findModelPricing(model, pricing);\n if (!p) {\n if (!warnedUnknownModels.has(model)) {\n warnedUnknownModels.add(model);\n console.warn(`[noumen/cost] No pricing data for model \"${model}\" — cost will be reported as $0`);\n }\n return 0;\n }\n\n const perMillion = 1_000_000;\n let cost = 0;\n cost += (usage.prompt_tokens / perMillion) * p.inputTokens;\n cost += (usage.completion_tokens / perMillion) * p.outputTokens;\n cost += ((usage.thinking_tokens ?? 0) / perMillion) * p.outputTokens;\n if (usage.cache_read_tokens && p.cacheReadTokens) {\n cost += (usage.cache_read_tokens / perMillion) * p.cacheReadTokens;\n }\n if (usage.cache_creation_tokens && p.cacheWriteTokens) {\n cost += (usage.cache_creation_tokens / perMillion) * p.cacheWriteTokens;\n }\n return cost;\n}\n","import type { ModelPricing, UsageRecord, ModelUsageSummary, CostSummary } from \"./types.js\";\nimport { calculateCost, DEFAULT_PRICING } from \"./pricing.js\";\n\nexport interface StoredCostState {\n byModel: Record<string, ModelUsageSummary>;\n totalApiMs: number;\n wallStartMs: number;\n}\n\nexport class CostTracker {\n private pricing: Record<string, ModelPricing>;\n private byModel: Record<string, ModelUsageSummary> = {};\n private totalApiMs = 0;\n private wallStartMs = Date.now();\n\n constructor(pricing?: Record<string, ModelPricing>) {\n this.pricing = pricing ?? DEFAULT_PRICING;\n }\n\n addUsage(model: string, usage: UsageRecord, apiDurationMs?: number): CostSummary {\n const cost = calculateCost(model, usage, this.pricing);\n\n if (!this.byModel[model]) {\n this.byModel[model] = {\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n costUSD: 0,\n };\n }\n\n const m = this.byModel[model];\n m.inputTokens += usage.prompt_tokens;\n m.outputTokens += usage.completion_tokens;\n m.cacheReadTokens += usage.cache_read_tokens ?? 0;\n m.cacheCreationTokens += usage.cache_creation_tokens ?? 0;\n m.costUSD += cost;\n\n if (apiDurationMs !== undefined) {\n this.totalApiMs += apiDurationMs;\n }\n\n return this.getSummary();\n }\n\n getSummary(): CostSummary {\n let totalCostUSD = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let totalCacheReadTokens = 0;\n let totalCacheCreationTokens = 0;\n\n for (const m of Object.values(this.byModel)) {\n totalCostUSD += m.costUSD;\n totalInputTokens += m.inputTokens;\n totalOutputTokens += m.outputTokens;\n totalCacheReadTokens += m.cacheReadTokens;\n totalCacheCreationTokens += m.cacheCreationTokens;\n }\n\n return {\n totalCostUSD,\n totalInputTokens,\n totalOutputTokens,\n totalCacheReadTokens,\n totalCacheCreationTokens,\n byModel: { ...this.byModel },\n duration: {\n apiMs: this.totalApiMs,\n wallMs: Date.now() - this.wallStartMs,\n },\n };\n }\n\n reset(): void {\n this.byModel = {};\n this.totalApiMs = 0;\n this.wallStartMs = Date.now();\n }\n\n getState(): StoredCostState {\n return {\n byModel: structuredClone(this.byModel),\n totalApiMs: this.totalApiMs,\n wallStartMs: this.wallStartMs,\n };\n }\n\n restore(state: StoredCostState): void {\n this.byModel = structuredClone(state.byModel);\n this.totalApiMs = state.totalApiMs;\n this.wallStartMs = state.wallStartMs;\n }\n\n formatSummary(): string {\n const s = this.getSummary();\n const costStr = s.totalCostUSD > 0.5\n ? `$${s.totalCostUSD.toFixed(2)}`\n : `$${s.totalCostUSD.toFixed(4)}`;\n\n const lines = [`Total cost: ${costStr}`];\n\n const models = Object.entries(s.byModel);\n if (models.length > 0) {\n lines.push(\"Usage by model:\");\n for (const [model, m] of models) {\n const parts = [\n `${formatNum(m.inputTokens)} input`,\n `${formatNum(m.outputTokens)} output`,\n ];\n if (m.cacheReadTokens > 0) parts.push(`${formatNum(m.cacheReadTokens)} cache read`);\n if (m.cacheCreationTokens > 0) parts.push(`${formatNum(m.cacheCreationTokens)} cache write`);\n parts.push(`($${m.costUSD.toFixed(4)})`);\n lines.push(` ${model}: ${parts.join(\", \")}`);\n }\n }\n\n return lines.join(\"\\n\");\n }\n}\n\nfunction formatNum(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;\n return String(n);\n}\n","export function jsonStringify(value: unknown): string {\n return JSON.stringify(value);\n}\n\nexport function parseJSONL<T = unknown>(text: string): T[] {\n const results: T[] = [];\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n results.push(JSON.parse(trimmed) as T);\n } catch {\n // skip malformed lines\n }\n }\n return results;\n}\n","import type { VirtualFs } from \"../virtual/fs.js\";\nimport type {\n ChatMessage,\n Entry,\n MessageEntry,\n CompactBoundaryEntry,\n SummaryEntry,\n MetadataEntry,\n ToolResultOverflowEntry,\n FileCheckpointEntry,\n ContentReplacementEntry,\n ContentReplacementRecord,\n SnipBoundaryEntry,\n SessionInfo,\n} from \"./types.js\";\nimport type { FileCheckpointSnapshot } from \"../checkpoint/types.js\";\nimport { generateUUID } from \"../utils/uuid.js\";\nimport type { UUID } from \"../utils/uuid.js\";\nimport { jsonStringify, parseJSONL } from \"../utils/json.js\";\n\nexport class SessionStorage {\n private fs: VirtualFs;\n private sessionDir: string;\n\n constructor(fs: VirtualFs, sessionDir: string) {\n this.fs = fs;\n this.sessionDir = sessionDir;\n }\n\n private getTranscriptPath(sessionId: string): string {\n return `${this.sessionDir}/${sessionId}.jsonl`;\n }\n\n async ensureDir(): Promise<void> {\n const exists = await this.fs.exists(this.sessionDir);\n if (!exists) {\n await this.fs.mkdir(this.sessionDir, { recursive: true });\n }\n }\n\n async appendEntry(sessionId: string, entry: Entry): Promise<void> {\n await this.ensureDir();\n const line = jsonStringify(entry) + \"\\n\";\n await this.fs.appendFile(this.getTranscriptPath(sessionId), line);\n }\n\n async appendMessage(\n sessionId: string,\n message: ChatMessage,\n parentUuid: UUID | null = null,\n ): Promise<UUID> {\n const uuid = generateUUID();\n const entry: MessageEntry = {\n type: \"message\",\n uuid,\n parentUuid,\n sessionId,\n timestamp: new Date().toISOString(),\n message,\n };\n await this.appendEntry(sessionId, entry);\n return uuid;\n }\n\n async appendCompactBoundary(sessionId: string): Promise<UUID> {\n const uuid = generateUUID();\n const entry: CompactBoundaryEntry = {\n type: \"compact-boundary\",\n uuid,\n sessionId,\n timestamp: new Date().toISOString(),\n };\n await this.appendEntry(sessionId, entry);\n return uuid;\n }\n\n async appendSummary(\n sessionId: string,\n summaryMessage: ChatMessage,\n parentUuid: UUID | null = null,\n ): Promise<UUID> {\n const uuid = generateUUID();\n const entry: SummaryEntry = {\n type: \"summary\",\n uuid,\n parentUuid,\n sessionId,\n timestamp: new Date().toISOString(),\n message: summaryMessage,\n };\n await this.appendEntry(sessionId, entry);\n return uuid;\n }\n\n async appendToolResultOverflow(\n sessionId: string,\n toolCallId: string,\n originalContent: string,\n ): Promise<void> {\n const entry: ToolResultOverflowEntry = {\n type: \"tool-result-overflow\",\n sessionId,\n timestamp: new Date().toISOString(),\n toolCallId,\n originalContent,\n };\n await this.appendEntry(sessionId, entry);\n }\n\n async appendCheckpointEntry(\n sessionId: string,\n messageId: string,\n snapshot: FileCheckpointSnapshot,\n isSnapshotUpdate: boolean,\n ): Promise<void> {\n const entry: FileCheckpointEntry = {\n type: \"file-checkpoint\",\n sessionId,\n timestamp: new Date().toISOString(),\n messageId,\n snapshot,\n isSnapshotUpdate,\n };\n await this.appendEntry(sessionId, entry);\n }\n\n async appendSnipBoundary(\n sessionId: string,\n removedUuids: string[],\n ): Promise<void> {\n if (removedUuids.length === 0) return;\n const entry: SnipBoundaryEntry = {\n type: \"snip-boundary\",\n sessionId,\n timestamp: new Date().toISOString(),\n snipMetadata: { removedUuids },\n };\n await this.appendEntry(sessionId, entry);\n }\n\n async appendContentReplacement(\n sessionId: string,\n replacements: ContentReplacementRecord[],\n ): Promise<void> {\n if (replacements.length === 0) return;\n const entry: ContentReplacementEntry = {\n type: \"content-replacement\",\n sessionId,\n timestamp: new Date().toISOString(),\n replacements,\n };\n await this.appendEntry(sessionId, entry);\n }\n\n async appendMetadata(\n sessionId: string,\n key: string,\n value: unknown,\n ): Promise<void> {\n const entry: MetadataEntry = {\n type: \"metadata\",\n sessionId,\n timestamp: new Date().toISOString(),\n key,\n value,\n };\n await this.appendEntry(sessionId, entry);\n }\n\n async loadMessages(sessionId: string): Promise<ChatMessage[]> {\n const path = this.getTranscriptPath(sessionId);\n\n const exists = await this.fs.exists(path);\n if (!exists) return [];\n\n const content = await this.fs.readFile(path);\n const entries = parseJSONL<Entry>(content);\n\n let lastBoundaryIdx = -1;\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].type === \"compact-boundary\") {\n lastBoundaryIdx = i;\n break;\n }\n }\n\n const activeEntries = entries.slice(lastBoundaryIdx + 1);\n\n const snippedUuids = new Set<string>();\n for (const entry of activeEntries) {\n if (entry.type === \"snip-boundary\") {\n for (const uuid of entry.snipMetadata.removedUuids) {\n snippedUuids.add(uuid);\n }\n }\n }\n\n const messages: ChatMessage[] = [];\n for (const entry of activeEntries) {\n if (entry.type === \"message\" || entry.type === \"summary\") {\n if (!snippedUuids.has(entry.uuid)) {\n messages.push(entry.message);\n }\n }\n }\n\n return messages;\n }\n\n async loadAllEntries(sessionId: string): Promise<Entry[]> {\n const path = this.getTranscriptPath(sessionId);\n\n const exists = await this.fs.exists(path);\n if (!exists) return [];\n\n const content = await this.fs.readFile(path);\n return parseJSONL<Entry>(content);\n }\n\n async sessionExists(sessionId: string): Promise<boolean> {\n return this.fs.exists(this.getTranscriptPath(sessionId));\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n await this.ensureDir();\n\n let entries;\n try {\n entries = await this.fs.readdir(this.sessionDir);\n } catch {\n return [];\n }\n\n const sessions: SessionInfo[] = [];\n\n for (const entry of entries) {\n if (!entry.name.endsWith(\".jsonl\")) continue;\n\n const sessionId = entry.name.replace(\".jsonl\", \"\");\n try {\n const content = await this.fs.readFile(\n this.getTranscriptPath(sessionId),\n );\n const allEntries = parseJSONL<Entry>(content);\n\n // Find last compact boundary to mirror loadMessages behavior\n let lastBoundaryIdx = -1;\n for (let i = allEntries.length - 1; i >= 0; i--) {\n if (allEntries[i].type === \"compact-boundary\") {\n lastBoundaryIdx = i;\n break;\n }\n }\n const activeEntries = allEntries.slice(lastBoundaryIdx + 1);\n\n // Collect snipped UUIDs\n const snippedUuids = new Set<string>();\n for (const e of activeEntries) {\n if (e.type === \"snip-boundary\") {\n for (const uuid of e.snipMetadata.removedUuids) {\n snippedUuids.add(uuid);\n }\n }\n }\n\n let messageCount = 0;\n let title: string | undefined;\n let firstTimestamp: string | undefined;\n let lastTimestamp: string | undefined;\n\n for (const e of activeEntries) {\n if ((e.type === \"message\" || e.type === \"summary\") && !snippedUuids.has(e.uuid)) {\n messageCount++;\n if (!firstTimestamp) firstTimestamp = e.timestamp;\n lastTimestamp = e.timestamp;\n }\n if (e.type === \"custom-title\") {\n title = e.title;\n }\n }\n\n // Fall back to full entries for timestamps if all messages were compacted\n if (!firstTimestamp) {\n for (const e of allEntries) {\n if (e.type === \"message\" || e.type === \"summary\") {\n if (!firstTimestamp) firstTimestamp = e.timestamp;\n lastTimestamp = e.timestamp;\n }\n }\n }\n\n sessions.push({\n sessionId,\n createdAt: firstTimestamp ?? new Date().toISOString(),\n lastMessageAt: lastTimestamp ?? new Date().toISOString(),\n title,\n messageCount,\n });\n } catch {\n // skip corrupt sessions\n }\n }\n\n return sessions.sort(\n (a, b) =>\n new Date(b.lastMessageAt).getTime() -\n new Date(a.lastMessageAt).getTime(),\n );\n }\n}\n","import type { VirtualFs } from \"../virtual/fs.js\";\nimport type { Task, TaskCreateInput, TaskUpdateInput } from \"./types.js\";\n\n/**\n * File-backed task store persisted on a VirtualFs instance.\n * Tasks are stored as individual JSON files under a configurable directory.\n */\nexport class TaskStore {\n private dir: string;\n private fs: VirtualFs;\n private nextId = 1;\n private initialized = false;\n\n constructor(fs: VirtualFs, dir: string) {\n this.fs = fs;\n this.dir = dir;\n }\n\n private async ensureDir(): Promise<void> {\n if (this.initialized) return;\n try {\n await this.fs.mkdir(this.dir, { recursive: true });\n } catch {\n // may already exist\n }\n // Read existing tasks to determine next ID\n try {\n const files = await this.fs.readdir(this.dir);\n let maxId = 0;\n for (const f of files) {\n const match = f.name.match(/^(\\d+)\\.json$/);\n if (match) {\n maxId = Math.max(maxId, parseInt(match[1], 10));\n }\n }\n this.nextId = maxId + 1;\n } catch {\n // empty dir\n }\n this.initialized = true;\n }\n\n private taskPath(id: string): string {\n return `${this.dir}/${id}.json`;\n }\n\n async create(input: TaskCreateInput): Promise<Task> {\n await this.ensureDir();\n\n const id = String(this.nextId++);\n const now = new Date().toISOString();\n const task: Task = {\n id,\n subject: input.subject,\n description: input.description,\n status: \"pending\",\n blocks: [],\n blockedBy: [],\n createdAt: now,\n updatedAt: now,\n };\n\n await this.fs.writeFile(this.taskPath(id), JSON.stringify(task, null, 2));\n return task;\n }\n\n async get(id: string): Promise<Task | null> {\n await this.ensureDir();\n try {\n const content = await this.fs.readFile(this.taskPath(id));\n return JSON.parse(content) as Task;\n } catch {\n return null;\n }\n }\n\n async list(): Promise<Task[]> {\n await this.ensureDir();\n const tasks: Task[] = [];\n try {\n const files = await this.fs.readdir(this.dir);\n for (const f of files) {\n if (!f.name.endsWith(\".json\")) continue;\n try {\n const content = await this.fs.readFile(`${this.dir}/${f.name}`);\n tasks.push(JSON.parse(content) as Task);\n } catch {\n // skip corrupt files\n }\n }\n } catch {\n // empty\n }\n tasks.sort((a, b) => parseInt(a.id, 10) - parseInt(b.id, 10));\n return tasks;\n }\n\n async update(id: string, input: TaskUpdateInput): Promise<Task | null> {\n const task = await this.get(id);\n if (!task) return null;\n\n if (input.status !== undefined) task.status = input.status;\n if (input.description !== undefined) task.description = input.description;\n if (input.owner !== undefined) task.owner = input.owner;\n if (input.blockedBy !== undefined) {\n task.blockedBy = input.blockedBy;\n // Update reverse references\n const allTasks = await this.list();\n for (const t of allTasks) {\n const blocksIdx = t.blocks.indexOf(id);\n if (input.blockedBy.includes(t.id)) {\n if (blocksIdx === -1) t.blocks.push(id);\n } else {\n if (blocksIdx !== -1) t.blocks.splice(blocksIdx, 1);\n }\n await this.fs.writeFile(\n this.taskPath(t.id),\n JSON.stringify(t, null, 2),\n );\n }\n }\n\n task.updatedAt = new Date().toISOString();\n await this.fs.writeFile(this.taskPath(id), JSON.stringify(task, null, 2));\n return task;\n }\n\n async delete(id: string): Promise<boolean> {\n try {\n await this.fs.deleteFile(this.taskPath(id));\n return true;\n } catch {\n return false;\n }\n }\n}\n","import type { ContextFile, ContextScope } from \"./types.js\";\n\nconst SCOPE_LABELS: Record<ContextScope, string> = {\n managed: \"managed instructions\",\n user: \"user instructions\",\n project: \"project instructions\",\n local: \"local instructions\",\n};\n\nconst CONTEXT_PREAMBLE =\n \"The following project instructions customize your behavior. \" +\n \"Follow them unless they conflict with explicit user requests.\";\n\n/**\n * Format loaded context files into a system prompt section.\n *\n * Files are rendered in array order (lowest to highest priority).\n * Included sub-files are inlined immediately after their parent.\n */\nexport function buildProjectContextSection(\n files: ContextFile[],\n filter?: ContextScope[],\n): string {\n const applicable = filter\n ? files.filter((f) => filter.includes(f.scope))\n : files;\n\n if (applicable.length === 0) return \"\";\n\n const sections: string[] = [CONTEXT_PREAMBLE, \"\"];\n\n for (const file of applicable) {\n renderFile(file, sections);\n }\n\n return sections.join(\"\\n\");\n}\n\nfunction renderFile(file: ContextFile, out: string[]): void {\n const label = SCOPE_LABELS[file.scope];\n out.push(`Contents of ${file.path} (${label})\\n`);\n out.push(file.content);\n out.push(\"\");\n\n if (file.includes) {\n for (const inc of file.includes) {\n renderFile(inc, out);\n }\n }\n}\n","export interface FrontmatterData {\n \"allowed-tools\"?: string | string[] | null;\n description?: string | null;\n paths?: string | string[] | null;\n context?: \"inline\" | \"fork\" | null;\n \"argument-hint\"?: string | null;\n [key: string]: unknown;\n}\n\nexport interface ParsedFrontmatter {\n frontmatter: FrontmatterData;\n body: string;\n}\n\nconst FRONTMATTER_RE = /^---\\s*\\n([\\s\\S]*?)---\\s*\\n?/;\n\n/**\n * Parse YAML frontmatter from markdown content.\n * Returns the parsed frontmatter fields and the body after the closing ---.\n * If no frontmatter is found, returns empty frontmatter and the full content as body.\n */\nexport function parseFrontmatter(content: string): ParsedFrontmatter {\n const match = content.match(FRONTMATTER_RE);\n if (!match) {\n return { frontmatter: {}, body: content };\n }\n\n const yamlBlock = match[1];\n const body = content.slice(match[0].length);\n\n let data = parseSimpleYaml(yamlBlock);\n\n if (data === null) {\n // Retry: quote values that contain YAML-special characters\n const quoted = yamlBlock.replace(\n /^(\\s*[\\w-]+\\s*:\\s*)(.+)$/gm,\n (_, prefix: string, value: string) => {\n const trimmed = value.trim();\n if (\n !trimmed.startsWith('\"') &&\n !trimmed.startsWith(\"'\") &&\n /[{}\\[\\],*&!|>%@`]/.test(trimmed)\n ) {\n return `${prefix}\"${trimmed.replace(/\"/g, '\\\\\"')}\"`;\n }\n return `${prefix}${value}`;\n },\n );\n data = parseSimpleYaml(quoted);\n }\n\n return { frontmatter: data ?? {}, body };\n}\n\n/**\n * Minimal YAML-subset parser for frontmatter.\n * Handles: key: value, key: [list], multi-line lists with - items.\n */\nfunction parseSimpleYaml(yaml: string): FrontmatterData | null {\n try {\n const result: FrontmatterData = {};\n const lines = yaml.split(\"\\n\");\n let currentKey: string | null = null;\n let currentList: string[] | null = null;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n // Check for list item under current key\n const listItemMatch = trimmed.match(/^-\\s+(.+)$/);\n if (listItemMatch && currentKey && currentList) {\n currentList.push(unquote(listItemMatch[1].trim()));\n continue;\n }\n\n // Flush any pending list\n if (currentKey && currentList) {\n result[currentKey] = currentList.length === 1 ? currentList[0] : currentList;\n currentKey = null;\n currentList = null;\n }\n\n // Key: value pair\n const kvMatch = trimmed.match(/^([\\w-]+)\\s*:\\s*(.*)$/);\n if (!kvMatch) continue;\n\n const key = kvMatch[1];\n const rawValue = kvMatch[2].trim();\n\n if (!rawValue) {\n // Could be followed by list items\n currentKey = key;\n currentList = [];\n continue;\n }\n\n // Inline array: [a, b, c]\n if (rawValue.startsWith(\"[\") && rawValue.endsWith(\"]\")) {\n const inner = rawValue.slice(1, -1);\n result[key] = inner\n .split(\",\")\n .map((s) => unquote(s.trim()))\n .filter(Boolean);\n continue;\n }\n\n // Scalar value\n result[key] = unquote(rawValue);\n }\n\n // Flush trailing list\n if (currentKey && currentList) {\n result[currentKey] = currentList.length === 1 ? currentList[0] : currentList;\n }\n\n return result;\n } catch {\n return null;\n }\n}\n\nfunction unquote(s: string): string {\n if (\n (s.startsWith('\"') && s.endsWith('\"')) ||\n (s.startsWith(\"'\") && s.endsWith(\"'\"))\n ) {\n return s.slice(1, -1);\n }\n return s;\n}\n\n/**\n * Parse the allowed-tools field from frontmatter.\n * Accepts a string (comma/space separated), string[], or null/undefined.\n */\nexport function parseAllowedTools(\n value: string | string[] | null | undefined,\n): string[] {\n if (!value) return [];\n if (Array.isArray(value)) return value.map((s) => s.trim()).filter(Boolean);\n return value\n .split(/[,\\n]/)\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\n/**\n * Parse the paths field from frontmatter into glob patterns.\n */\nexport function parsePaths(\n value: string | string[] | null | undefined,\n): string[] {\n if (!value) return [];\n if (Array.isArray(value)) return value.map((s) => s.trim()).filter(Boolean);\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n","import type { VirtualFs } from \"../virtual/fs.js\";\nimport type { ContextFile, ContextScope, ProjectContextConfig } from \"./types.js\";\nimport { parseFrontmatter, parsePaths } from \"../skills/frontmatter.js\";\n\nconst DEFAULT_MAX_INCLUDE_DEPTH = 5;\n\nconst NOUMEN_NAMES = {\n md: \"NOUMEN.md\",\n localMd: \"NOUMEN.local.md\",\n dotDir: \".noumen\",\n};\n\nconst CLAUDE_NAMES = {\n md: \"CLAUDE.md\",\n localMd: \"CLAUDE.local.md\",\n dotDir: \".claude\",\n};\n\ntype NameSet = typeof NOUMEN_NAMES;\n\n/**\n * Load project context files from the hierarchical NOUMEN.md / CLAUDE.md\n * convention. Returns files ordered lowest-to-highest priority:\n * managed -> user -> project (root first, cwd last) -> local.\n */\nexport async function loadProjectContext(\n fs: VirtualFs,\n config: ProjectContextConfig,\n): Promise<ContextFile[]> {\n const maxDepth = config.maxIncludeDepth ?? DEFAULT_MAX_INCLUDE_DEPTH;\n const loadClaude = config.loadClaudeMd ?? true;\n const nameSets: NameSet[] = [NOUMEN_NAMES];\n if (loadClaude) nameSets.push(CLAUDE_NAMES);\n\n const excludes = config.excludes ?? [];\n const files: ContextFile[] = [];\n\n // 1. Managed layer\n if (config.managedDir) {\n for (const ns of nameSets) {\n await tryLoadFile(fs, join(config.managedDir, ns.md), \"managed\", files, maxDepth, excludes);\n await scanRulesDir(fs, join(config.managedDir, ns.dotDir, \"rules\"), \"managed\", files, maxDepth, excludes);\n }\n }\n\n // 2. User layer\n if ((config.loadUserContext ?? true) && config.homeDir) {\n for (const ns of nameSets) {\n await tryLoadFile(fs, join(config.homeDir, ns.dotDir, ns.md), \"user\", files, maxDepth, excludes);\n await scanRulesDir(fs, join(config.homeDir, ns.dotDir, \"rules\"), \"user\", files, maxDepth, excludes);\n }\n }\n\n // 3. Project walk (root -> cwd for ascending priority)\n const dirs = walkAncestors(config.cwd);\n\n if (config.loadProjectContext ?? true) {\n for (const dir of dirs) {\n for (const ns of nameSets) {\n await tryLoadFile(fs, join(dir, ns.md), \"project\", files, maxDepth, excludes);\n await tryLoadFile(fs, join(dir, ns.dotDir, ns.md), \"project\", files, maxDepth, excludes);\n await scanRulesDir(fs, join(dir, ns.dotDir, \"rules\"), \"project\", files, maxDepth, excludes);\n }\n }\n }\n\n // 4. Local layer (same walk order)\n if (config.loadLocalContext ?? true) {\n for (const dir of dirs) {\n for (const ns of nameSets) {\n await tryLoadFile(fs, join(dir, ns.localMd), \"local\", files, maxDepth, excludes);\n }\n }\n }\n\n return files;\n}\n\n/**\n * Walk from filesystem root down to cwd (root first = lowest priority).\n */\nfunction walkAncestors(cwd: string): string[] {\n const normalized = cwd.endsWith(\"/\") && cwd.length > 1 ? cwd.slice(0, -1) : cwd;\n const parts = normalized.split(\"/\");\n const dirs: string[] = [];\n\n // Build paths from root toward cwd\n for (let i = 1; i <= parts.length; i++) {\n const dir = parts.slice(0, i).join(\"/\") || \"/\";\n dirs.push(dir);\n }\n\n return dirs;\n}\n\nasync function tryLoadFile(\n fs: VirtualFs,\n path: string,\n scope: ContextScope,\n out: ContextFile[],\n maxDepth: number,\n excludes: string[],\n): Promise<void> {\n if (isExcluded(path, excludes)) return;\n const file = await loadContextFile(fs, path, scope, new Set(), 0, maxDepth);\n if (file) out.push(file);\n}\n\nasync function loadContextFile(\n fs: VirtualFs,\n path: string,\n scope: ContextScope,\n visited: Set<string>,\n depth: number,\n maxDepth: number,\n): Promise<ContextFile | null> {\n const normalized = normalizePath(path);\n if (visited.has(normalized)) return null;\n\n let raw: string;\n try {\n raw = await fs.readFile(path);\n } catch {\n return null;\n }\n\n if (!raw.trim()) return null;\n\n visited.add(normalized);\n\n const { frontmatter, body } = parseFrontmatter(raw);\n const globs = parsePaths(frontmatter.paths);\n const content = stripHtmlComments(body);\n\n const includes = await resolveIncludes(fs, content, path, visited, depth, maxDepth);\n\n return {\n path,\n scope,\n content,\n ...(globs.length > 0 ? { globs } : {}),\n ...(includes.length > 0 ? { includes } : {}),\n };\n}\n\n/**\n * Parse inline `@path` references from markdown content, skipping fenced\n * code blocks and inline code spans. Resolve each path relative to the\n * directory of the including file.\n */\nasync function resolveIncludes(\n fs: VirtualFs,\n content: string,\n basePath: string,\n visited: Set<string>,\n depth: number,\n maxDepth: number,\n): Promise<ContextFile[]> {\n if (depth >= maxDepth) return [];\n\n const baseDir = dirname(basePath);\n const refs = extractAtReferences(content);\n const includes: ContextFile[] = [];\n\n for (const ref of refs) {\n const resolved = resolvePath(baseDir, ref);\n const file = await loadContextFile(fs, resolved, \"project\", visited, depth + 1, maxDepth);\n if (file) includes.push(file);\n }\n\n return includes;\n}\n\n/**\n * Extract `@path` references from markdown text, ignoring references\n * inside fenced code blocks and inline code spans.\n */\nfunction extractAtReferences(content: string): string[] {\n const refs: string[] = [];\n const lines = content.split(\"\\n\");\n let inFence = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (trimmed.startsWith(\"```\") || trimmed.startsWith(\"~~~\")) {\n inFence = !inFence;\n continue;\n }\n if (inFence) continue;\n\n // Strip inline code spans before scanning for @\n const stripped = line.replace(/`[^`]+`/g, \"\");\n\n const re = /(?:^|\\s)@((?:[^\\s\\\\]|\\\\ )+)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(stripped)) !== null) {\n const raw = m[1].replace(/\\\\ /g, \" \").replace(/#.*$/, \"\");\n if (!raw) continue;\n\n if (raw.startsWith(\"./\") || raw.startsWith(\"../\") || raw.startsWith(\"~/\") || raw.startsWith(\"/\")) {\n refs.push(raw);\n } else if (/^[a-zA-Z0-9._-]/.test(raw) && !raw.startsWith(\"@\")) {\n refs.push(raw);\n }\n }\n }\n\n return refs;\n}\n\n/**\n * Recursively scan a rules directory for *.md files.\n */\nasync function scanRulesDir(\n fs: VirtualFs,\n dirPath: string,\n scope: ContextScope,\n out: ContextFile[],\n maxDepth: number,\n excludes: string[],\n): Promise<void> {\n let entries;\n try {\n entries = await fs.readdir(dirPath);\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.isFile && entry.name.endsWith(\".md\")) {\n if (isExcluded(entry.path, excludes)) continue;\n const file = await loadContextFile(fs, entry.path, scope, new Set(), 0, maxDepth);\n if (file) out.push(file);\n } else if (entry.isDirectory) {\n await scanRulesDir(fs, entry.path, scope, out, maxDepth, excludes);\n }\n }\n}\n\n/**\n * Strip block-level HTML comments from markdown content.\n */\nfunction stripHtmlComments(content: string): string {\n if (!content.includes(\"<!--\")) return content;\n return content.replace(/<!--[\\s\\S]*?-->/g, \"\");\n}\n\nfunction isExcluded(path: string, excludes: string[]): boolean {\n if (excludes.length === 0) return false;\n return excludes.some((pattern) => {\n if (path === pattern) return true;\n if (pattern.includes(\"*\")) {\n const regex = simpleGlobToRegex(pattern);\n return regex.test(path);\n }\n return path.includes(pattern);\n });\n}\n\nfunction simpleGlobToRegex(glob: string): RegExp {\n let result = \"\";\n for (let i = 0; i < glob.length; i++) {\n const ch = glob[i];\n if (ch === \"*\") {\n if (glob[i + 1] === \"*\") {\n result += \".*\";\n i++;\n if (glob[i + 1] === \"/\") i++;\n } else {\n result += \"[^/]*\";\n }\n } else if (ch === \"?\") {\n result += \"[^/]\";\n } else {\n result += ch.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n }\n return new RegExp(result);\n}\n\nfunction normalizePath(p: string): string {\n const parts = p.split(\"/\").filter(Boolean);\n const stack: string[] = [];\n for (const part of parts) {\n if (part === \"..\") {\n stack.pop();\n } else if (part !== \".\") {\n stack.push(part);\n }\n }\n return \"/\" + stack.join(\"/\");\n}\n\nfunction dirname(p: string): string {\n const idx = p.lastIndexOf(\"/\");\n if (idx <= 0) return \"/\";\n return p.slice(0, idx);\n}\n\nfunction join(...parts: string[]): string {\n return normalizePath(parts.join(\"/\"));\n}\n\nfunction resolvePath(base: string, relative: string): string {\n if (relative.startsWith(\"/\")) return normalizePath(relative);\n return normalizePath(base + \"/\" + relative);\n}\n\n/**\n * Filter context files to only those whose globs match at least one\n * of the given file paths. Files without globs (unconditional) always pass.\n */\nexport function filterActiveContextFiles(\n files: ContextFile[],\n touchedPaths: string[],\n cwd: string,\n): ContextFile[] {\n return files.filter((f) => {\n if (!f.globs || f.globs.length === 0) return true;\n return touchedPaths.some((filePath) => {\n const relative = filePath.startsWith(cwd)\n ? filePath.slice(cwd.endsWith(\"/\") ? cwd.length : cwd.length + 1)\n : filePath;\n return f.globs!.some((g) => simpleGlobToRegex(g).test(relative));\n });\n });\n}\n\n/**\n * Check which conditional context files are newly activated by the given\n * touched paths. Returns the paths of newly activated files.\n */\nexport function activateContextForPaths(\n allFiles: ContextFile[],\n touchedPaths: string[],\n cwd: string,\n alreadyActivated: Set<string>,\n): string[] {\n const activated: string[] = [];\n\n for (const file of allFiles) {\n if (!file.globs || file.globs.length === 0) continue;\n if (alreadyActivated.has(file.path)) continue;\n\n for (const filePath of touchedPaths) {\n const relative = filePath.startsWith(cwd)\n ? filePath.slice(cwd.endsWith(\"/\") ? cwd.length : cwd.length + 1)\n : filePath;\n\n if (file.globs.some((g) => simpleGlobToRegex(g).test(relative))) {\n alreadyActivated.add(file.path);\n activated.push(file.path);\n break;\n }\n }\n }\n\n return activated;\n}\n","export const SpanStatusCode = {\n OK: 0,\n ERROR: 1,\n} as const;\n\nexport type SpanStatusCode = (typeof SpanStatusCode)[keyof typeof SpanStatusCode];\n\nexport type SpanAttributeValue = string | number | boolean;\n\nexport interface SpanOptions {\n parent?: Span;\n attributes?: Record<string, SpanAttributeValue>;\n}\n\nexport interface Span {\n readonly name: string;\n setAttribute(key: string, value: SpanAttributeValue): void;\n addEvent(name: string, attributes?: Record<string, SpanAttributeValue>): void;\n setStatus(code: SpanStatusCode, message?: string): void;\n end(): void;\n}\n\nexport interface Tracer {\n startSpan(name: string, options?: SpanOptions): Span;\n}\n\nexport interface TracingConfig {\n tracer: Tracer;\n}\n","import type { Span, SpanAttributeValue, SpanOptions, SpanStatusCode, Tracer } from \"./types.js\";\n\nexport class NoopSpan implements Span {\n readonly name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n setAttribute(_key: string, _value: SpanAttributeValue): void {}\n addEvent(_name: string, _attributes?: Record<string, SpanAttributeValue>): void {}\n setStatus(_code: SpanStatusCode, _message?: string): void {}\n end(): void {}\n}\n\nexport class NoopTracer implements Tracer {\n startSpan(name: string, _options?: SpanOptions): Span {\n return new NoopSpan(name);\n }\n}\n","/**\n * Prompt helpers for the memory system.\n *\n * `buildMemorySystemPromptSection` generates the instruction block injected\n * into the system prompt that teaches the model about the four-type memory\n * taxonomy and how to read/write memories.\n *\n * `buildExtractionPrompt` generates the user message sent to the LLM when\n * auto-extracting memories from a completed conversation turn.\n *\n * Both are adapted from claude-code's memdir/memoryTypes prompt helpers,\n * stripped of analytics, team memory, and Anthropic-specific concerns.\n */\n\nconst MEMORY_TYPES_SECTION = `## Memory types\n\nMemories fall into exactly four types:\n\n### user\nFacts about the user: their role, expertise, communication preferences, how they like to collaborate, preferred tools and workflows.\nExamples: \"Senior backend engineer, prefers Rust\", \"Wants concise answers, no pleasantries\"\n\n### feedback\nCorrections, praise, or behavioral guidance the user has given you. These shape how you work in future conversations.\nExamples: \"User said: stop adding unnecessary comments\", \"User prefers small focused commits\"\n\n### project\nContext about the codebase or project that is NOT derivable from the code itself: architecture decisions and their rationale, deployment processes, external dependencies, team conventions.\nExamples: \"Auth service migrating from JWT to session tokens — decision made 2025-01\", \"CI runs on GitHub Actions, deploy via Vercel\"\n\n### reference\nPointers to external resources the user has shared: documentation links, dashboard URLs, API references, Slack channels.\nExamples: \"Design system docs: https://design.example.com\", \"Incident runbook in Notion\"`;\n\nconst WHAT_NOT_TO_SAVE = `## What NOT to save\n\nDo not save memories that are:\n- Derivable from the code itself (file structure, function signatures, import patterns)\n- Ephemeral to the current conversation (temporary debugging steps, in-progress plans)\n- Redundant with an existing memory (check first, update instead of creating duplicates)\n- Generic programming knowledge (how promises work, what REST means)`;\n\nconst WHEN_TO_ACCESS = `## When to access memories\n\nRead your memories at the start of a conversation to orient yourself. During a conversation, consult them when:\n- The user references something from a past conversation\n- You need context about the project that isn't in the code\n- You're about to make a decision that past feedback might inform\n- The user asks \"do you remember…\" or similar`;\n\nconst HOW_TO_SAVE = `## How to save memories\n\nSaving a memory is a two-step process:\n\n**Step 1** — write the memory to its own file (e.g., \\`user_role.md\\`, \\`feedback_testing.md\\`) using this frontmatter format:\n\n\\`\\`\\`\n---\nname: short descriptive title\ndescription: one-line summary\ntype: user | project | feedback | reference\n---\n\nFull content here…\n\\`\\`\\`\n\n**Step 2** — add a pointer to that file in \\`MEMORY.md\\`. \\`MEMORY.md\\` is an index, not a memory — each entry should be one line, under ~150 characters: \\`- [Title](file.md) — one-line hook\\`. It has no frontmatter. Never write memory content directly into \\`MEMORY.md\\`.\n\n- \\`MEMORY.md\\` is always loaded into your conversation context — lines after 200 will be truncated, so keep the index concise\n- Keep the name, description, and type fields in memory files up-to-date with the content\n- Organize memory semantically by topic, not chronologically\n- Update or remove memories that turn out to be wrong or outdated\n- Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one.`;\n\n/**\n * Build the system-prompt section that teaches the model about its persistent\n * memory directory.\n *\n * @param indexContent - The current contents of MEMORY.md (may be empty).\n * @param memoryDir - Absolute path to the memory directory.\n */\nexport function buildMemorySystemPromptSection(\n indexContent: string,\n memoryDir: string,\n): string {\n const sections: string[] = [\n \"# Persistent Memory\",\n \"\",\n `You have a persistent, file-based memory system at \\`${memoryDir}\\`. This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence).`,\n \"\",\n \"You should build up this memory system over time so that future conversations have a complete picture of who the user is, how they'd like to collaborate with you, what behaviors to avoid or repeat, and the context behind the work the user gives you.\",\n \"\",\n \"If the user explicitly asks you to remember something, save it immediately as whichever type fits best. If they ask you to forget something, find and remove the relevant entry.\",\n \"\",\n MEMORY_TYPES_SECTION,\n \"\",\n WHAT_NOT_TO_SAVE,\n \"\",\n HOW_TO_SAVE,\n \"\",\n WHEN_TO_ACCESS,\n \"\",\n \"## MEMORY.md\",\n \"\",\n ];\n\n if (indexContent.trim()) {\n sections.push(indexContent);\n } else {\n sections.push(\n \"Your MEMORY.md is currently empty. When you save new memories, they will appear here.\",\n );\n }\n\n return sections.join(\"\\n\");\n}\n\n/**\n * Build the prompt sent to the LLM to extract durable memories from a\n * conversation. The response should be a JSON object with a `memories` array.\n */\nexport function buildExtractionPrompt(\n conversationSummary: string,\n existingIndex: string,\n): string {\n return `You are a memory extraction assistant. Analyze the following conversation and extract any information worth remembering for future conversations.\n\n## Current memory index\n\n${existingIndex.trim() || \"(empty)\"}\n\n## Conversation\n\n${conversationSummary}\n\n## Instructions\n\nExtract memories that fall into these categories:\n- **user**: Facts about the user (role, preferences, expertise, communication style)\n- **feedback**: Corrections or behavioral guidance the user gave the assistant\n- **project**: Non-obvious project context (architecture decisions, deployment processes, conventions)\n- **reference**: External links or resources the user shared\n\nDo NOT extract:\n- Information derivable from the code itself\n- Ephemeral conversation details (debugging steps, temporary plans)\n- Generic programming knowledge\n- Information already captured in the existing memory index\n\nIf a memory should update an existing entry rather than creating a new one, use the \"update\" action and provide the existing path.\n\nRespond with a JSON object:\n{\n \"memories\": [\n {\n \"name\": \"short descriptive title\",\n \"description\": \"one-line summary\",\n \"type\": \"user | project | feedback | reference\",\n \"content\": \"full memory content\",\n \"action\": \"create | update | delete\",\n \"path\": \"existing_file.md (required for update/delete, omit for create)\"\n }\n ]\n}\n\nIf there is nothing worth extracting, respond with: { \"memories\": [] }`;\n}\n","import type { AIProvider } from \"../providers/types.js\";\nimport type { ChatMessage } from \"../session/types.js\";\nimport type { MemoryEntry, MemoryProvider, MemoryType } from \"./types.js\";\nimport { buildExtractionPrompt } from \"./prompts.js\";\n\nconst MEMORY_TYPES: ReadonlySet<string> = new Set([\n \"user\",\n \"project\",\n \"feedback\",\n \"reference\",\n]);\n\ninterface ExtractionAction {\n name: string;\n description: string;\n type: MemoryType;\n content: string;\n action: \"create\" | \"update\" | \"delete\";\n path?: string;\n}\n\ninterface ExtractionResult {\n memories: ExtractionAction[];\n}\n\nexport interface ExtractMemoriesResult {\n created: MemoryEntry[];\n updated: MemoryEntry[];\n deleted: string[];\n}\n\n/**\n * Summarize the most recent turn of messages into a compact string for the\n * extraction prompt. Keeps the last ~20 messages to avoid sending the entire\n * conversation history to the extraction call.\n */\nfunction summarizeRecentMessages(messages: ChatMessage[], maxMessages = 20): string {\n const recent = messages.slice(-maxMessages);\n const lines: string[] = [];\n for (const msg of recent) {\n const role = msg.role.toUpperCase();\n const text = typeof msg.content === \"string\"\n ? msg.content\n : \"(non-text content)\";\n const truncated = text.length > 2000\n ? text.slice(0, 2000) + \"…\"\n : text;\n lines.push(`[${role}] ${truncated}`);\n }\n return lines.join(\"\\n\\n\");\n}\n\n/**\n * Extract durable memories from a conversation by making a single\n * structured-output LLM call. Applies the returned actions to the\n * `MemoryProvider` and returns a summary of changes.\n */\nexport async function extractMemories(\n llmProvider: AIProvider,\n model: string,\n messages: ChatMessage[],\n provider: MemoryProvider,\n): Promise<ExtractMemoriesResult> {\n const existingIndex = await provider.loadIndex();\n const summary = summarizeRecentMessages(messages);\n const prompt = buildExtractionPrompt(summary, existingIndex);\n\n const extractionMessages: ChatMessage[] = [\n { role: \"user\", content: prompt },\n ];\n\n let responseText = \"\";\n for await (const chunk of llmProvider.chat({\n model,\n messages: extractionMessages,\n system: \"You are a memory extraction assistant. Respond only with valid JSON.\",\n max_tokens: 4096,\n })) {\n for (const choice of chunk.choices) {\n if (choice.delta.content) {\n responseText += choice.delta.content;\n }\n }\n }\n\n const parsed = parseExtractionResponse(responseText);\n if (!parsed || parsed.memories.length === 0) {\n return { created: [], updated: [], deleted: [] };\n }\n\n const result: ExtractMemoriesResult = {\n created: [],\n updated: [],\n deleted: [],\n };\n\n for (const action of parsed.memories) {\n if (!MEMORY_TYPES.has(action.type)) continue;\n\n if (action.action === \"delete\" && action.path) {\n await provider.removeEntry(action.path);\n result.deleted.push(action.path);\n } else if (action.action === \"update\" && action.path) {\n const entry: MemoryEntry = {\n name: action.name,\n description: action.description,\n type: action.type,\n content: action.content,\n path: action.path,\n updatedAt: new Date().toISOString(),\n };\n await provider.saveEntry(entry);\n result.updated.push(entry);\n } else if (action.action === \"create\") {\n const entry: MemoryEntry = {\n name: action.name,\n description: action.description,\n type: action.type,\n content: action.content,\n updatedAt: new Date().toISOString(),\n };\n await provider.saveEntry(entry);\n result.created.push(entry);\n }\n }\n\n return result;\n}\n\nfunction parseExtractionResponse(text: string): ExtractionResult | null {\n const trimmed = text.trim();\n\n // Handle markdown code fences\n let jsonStr = trimmed;\n if (jsonStr.startsWith(\"```\")) {\n const firstNewline = jsonStr.indexOf(\"\\n\");\n jsonStr = jsonStr.slice(firstNewline + 1);\n const lastFence = jsonStr.lastIndexOf(\"```\");\n if (lastFence !== -1) {\n jsonStr = jsonStr.slice(0, lastFence);\n }\n }\n\n try {\n const parsed = JSON.parse(jsonStr);\n if (\n parsed &&\n typeof parsed === \"object\" &&\n Array.isArray(parsed.memories)\n ) {\n return parsed as ExtractionResult;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Cache-safe parameters for subagent prompt cache sharing.\n *\n * When a subagent (fork) shares the same system prompt, model, tools, and\n * thinking config as its parent, both can share the same prompt cache\n * prefix. CacheSafeParams captures these values so the child thread can\n * inherit them and avoid cache breaks.\n */\n\nimport type { ToolDefinition } from \"./types.js\";\nimport type { ThinkingConfig } from \"../thinking/types.js\";\n\nexport interface CacheSafeParams {\n systemPrompt: string;\n model: string;\n tools: ToolDefinition[];\n thinking?: ThinkingConfig;\n}\n\nconst cacheSafeParamsMap = new Map<string, CacheSafeParams>();\n\nexport function saveCacheSafeParams(params: CacheSafeParams | null, sessionId = \"_default\"): void {\n if (params) {\n cacheSafeParamsMap.set(sessionId, params);\n } else {\n cacheSafeParamsMap.delete(sessionId);\n }\n}\n\nexport function getLastCacheSafeParams(sessionId = \"_default\"): CacheSafeParams | null {\n return cacheSafeParamsMap.get(sessionId) ?? null;\n}\n\nexport function createCacheSafeParams(opts: {\n systemPrompt: string;\n model: string;\n tools: ToolDefinition[];\n thinking?: ThinkingConfig;\n}): CacheSafeParams {\n return {\n systemPrompt: opts.systemPrompt,\n model: opts.model,\n tools: opts.tools,\n thinking: opts.thinking,\n };\n}\n","/**\n * Conversation recovery and message sanitization.\n *\n * Cleans up persisted messages before resuming a session so the API\n * receives a structurally valid conversation. Handles crashes, streaming\n * interruptions, orphaned tool calls, and whitespace-only messages.\n */\n\nimport type {\n ChatMessage,\n AssistantMessage,\n ToolResultMessage,\n ContentPart,\n} from \"./types.js\";\nimport { contentToString } from \"../utils/content.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type TurnInterruption =\n | { kind: \"none\" }\n | { kind: \"interrupted_tool\" }\n | { kind: \"interrupted_prompt\" };\n\nexport interface SanitizeResult {\n messages: ChatMessage[];\n interruption: TurnInterruption;\n /** Number of messages removed by each filter (for diagnostics). */\n removals: {\n unresolvedToolUses: number;\n whitespaceOnly: number;\n orphanedThinking: number;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Filters\n// ---------------------------------------------------------------------------\n\n/**\n * Drop assistant messages where *every* tool_call has no matching tool\n * result message. Keeps assistants that have at least one resolved call\n * or no tool_calls at all.\n */\nexport function filterUnresolvedToolUses(messages: ChatMessage[]): {\n messages: ChatMessage[];\n removed: number;\n} {\n const resolvedToolCallIds = new Set<string>();\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n resolvedToolCallIds.add((msg as ToolResultMessage).tool_call_id);\n }\n }\n\n let removed = 0;\n const filtered = messages.filter((msg) => {\n if (msg.role !== \"assistant\") return true;\n const asst = msg as AssistantMessage;\n if (!asst.tool_calls || asst.tool_calls.length === 0) return true;\n\n const allUnresolved = asst.tool_calls.every(\n (tc) => !resolvedToolCallIds.has(tc.id),\n );\n if (allUnresolved) {\n removed++;\n return false;\n }\n return true;\n });\n\n return { messages: filtered, removed };\n}\n\n/**\n * Drop assistant messages that are whitespace-only text with no\n * tool_calls (API-invalid). After removal, merge consecutive user\n * messages to restore role alternation.\n */\nexport function filterWhitespaceOnlyAssistantMessages(messages: ChatMessage[]): {\n messages: ChatMessage[];\n removed: number;\n} {\n let removed = 0;\n const filtered = messages.filter((msg) => {\n if (msg.role !== \"assistant\") return true;\n const asst = msg as AssistantMessage;\n if (asst.tool_calls && asst.tool_calls.length > 0) return true;\n\n const text = typeof asst.content === \"string\" ? asst.content : contentToString(asst.content ?? \"\");\n if (text.trim() === \"\") {\n removed++;\n return false;\n }\n return true;\n });\n\n if (removed === 0) return { messages: filtered, removed };\n\n return { messages: mergeConsecutiveSameRole(filtered), removed };\n}\n\n/**\n * Drop assistant messages that contain only thinking content (no\n * real text and no tool_calls). These are artifacts of streaming\n * interruptions where a thinking block was streamed but the model\n * never produced a real response.\n *\n * In noumen's format, thinking content appears as `content: null`\n * with no tool_calls (the thinking deltas were streamed separately).\n * We detect these as assistants with null/empty content and no calls.\n */\nexport function filterOrphanedThinkingMessages(messages: ChatMessage[]): {\n messages: ChatMessage[];\n removed: number;\n} {\n let removed = 0;\n const filtered = messages.filter((msg) => {\n if (msg.role !== \"assistant\") return true;\n const asst = msg as AssistantMessage;\n if (asst.tool_calls && asst.tool_calls.length > 0) return true;\n if (asst.content === null || asst.content === undefined) {\n removed++;\n return false;\n }\n return true;\n });\n\n return { messages: filtered, removed };\n}\n\n// ---------------------------------------------------------------------------\n// Turn interruption detection\n// ---------------------------------------------------------------------------\n\n/**\n * Detect whether the conversation was interrupted mid-turn.\n *\n * Walks backward from the end skipping system messages to find the\n * last significant message. Returns `interrupted_tool` when the last\n * message is a tool result (agent got results but model never replied),\n * `interrupted_prompt` when the last message is a user prompt (model\n * never started), or `none` otherwise.\n */\nexport function detectTurnInterruption(messages: ChatMessage[]): TurnInterruption {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"tool\") {\n return { kind: \"interrupted_tool\" };\n }\n if (msg.role === \"user\") {\n const text = typeof msg.content === \"string\" ? msg.content : \"\";\n if (text.startsWith(\"[Conversation Summary]\")) {\n return { kind: \"none\" };\n }\n return { kind: \"interrupted_prompt\" };\n }\n return { kind: \"none\" };\n }\n return { kind: \"none\" };\n}\n\n// ---------------------------------------------------------------------------\n// Orchestrator\n// ---------------------------------------------------------------------------\n\n/**\n * Run the full sanitization pipeline on a set of persisted messages.\n *\n * Order matters:\n * 1. Remove unresolved tool uses (structural — fixes orphan tool_calls)\n * 2. Remove orphaned thinking messages (streaming artifacts)\n * 3. Remove whitespace-only assistants (API validity)\n * 4. Detect turn interruption (must happen last, on clean messages)\n */\nexport function sanitizeForResume(messages: ChatMessage[]): SanitizeResult {\n const step1 = filterUnresolvedToolUses(messages);\n const step1b = fillPartiallyResolvedToolCalls(step1.messages);\n const step2 = filterOrphanedThinkingMessages(step1b.messages);\n const step3 = filterWhitespaceOnlyAssistantMessages(step2.messages);\n\n const interruption = detectTurnInterruption(step3.messages);\n\n return {\n messages: step3.messages,\n interruption,\n removals: {\n unresolvedToolUses: step1.removed,\n whitespaceOnly: step3.removed,\n orphanedThinking: step2.removed,\n },\n };\n}\n\n/**\n * For assistant messages that have SOME resolved tool_calls but not all,\n * generate synthetic error results for the missing ones so the API\n * receives a complete conversation.\n */\nfunction fillPartiallyResolvedToolCalls(messages: ChatMessage[]): {\n messages: ChatMessage[];\n} {\n const resolvedIds = new Set<string>();\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n resolvedIds.add((msg as ToolResultMessage).tool_call_id);\n }\n }\n\n const result: ChatMessage[] = [];\n for (const msg of messages) {\n result.push(msg);\n if (msg.role !== \"assistant\") continue;\n const asst = msg as AssistantMessage;\n if (!asst.tool_calls || asst.tool_calls.length === 0) continue;\n\n for (const tc of asst.tool_calls) {\n if (!resolvedIds.has(tc.id)) {\n const synthetic: ToolResultMessage = {\n role: \"tool\",\n tool_call_id: tc.id,\n content: \"Error: Tool result missing due to interrupted session.\",\n };\n result.push(synthetic);\n resolvedIds.add(tc.id);\n }\n }\n }\n\n return { messages: result };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Merge consecutive messages with the same role to restore valid\n * role alternation after removing messages from the middle.\n */\nfunction mergeConsecutiveSameRole(messages: ChatMessage[]): ChatMessage[] {\n if (messages.length <= 1) return messages;\n\n const result: ChatMessage[] = [messages[0]];\n\n for (let i = 1; i < messages.length; i++) {\n const prev = result[result.length - 1];\n const curr = messages[i];\n\n if (prev.role === \"user\" && curr.role === \"user\") {\n const prevParts: ContentPart[] = typeof prev.content === \"string\"\n ? [{ type: \"text\", text: prev.content }]\n : Array.isArray(prev.content)\n ? (prev.content as ContentPart[])\n : [{ type: \"text\", text: contentToString(prev.content) }];\n const currParts: ContentPart[] = typeof curr.content === \"string\"\n ? [{ type: \"text\", text: curr.content }]\n : Array.isArray(curr.content)\n ? (curr.content as ContentPart[])\n : [{ type: \"text\", text: contentToString(curr.content) }];\n result[result.length - 1] = {\n role: \"user\",\n content: [...prevParts, ...currParts],\n };\n } else {\n result.push(curr);\n }\n }\n\n return result;\n}\n\n/**\n * Generate synthetic tool result messages for tool_calls in an\n * assistant message that have no matching result yet. Used to\n * prevent orphaned tool_calls from corrupting the conversation\n * when streaming is interrupted or provider errors occur.\n */\nexport function generateMissingToolResults(\n assistantMsg: AssistantMessage,\n existingResults: ChatMessage[],\n reason: string,\n): ToolResultMessage[] {\n if (!assistantMsg.tool_calls || assistantMsg.tool_calls.length === 0) return [];\n\n const resolvedIds = new Set<string>();\n for (const msg of existingResults) {\n if (msg.role === \"tool\") {\n resolvedIds.add((msg as ToolResultMessage).tool_call_id);\n }\n }\n\n const missing: ToolResultMessage[] = [];\n for (const tc of assistantMsg.tool_calls) {\n if (!resolvedIds.has(tc.id)) {\n missing.push({\n role: \"tool\",\n tool_call_id: tc.id,\n content: `Error: ${reason}`,\n });\n }\n }\n\n return missing;\n}\n","/**\n * Session resume / restore.\n *\n * Parses a persisted JSONL session and extracts everything needed to\n * reconstruct thread state: messages (respecting compact boundaries),\n * file checkpoint snapshots, metadata, and tool result overflow entries.\n */\n\nimport type { SessionStorage } from \"./storage.js\";\nimport type {\n ChatMessage,\n Entry,\n FileCheckpointEntry,\n ToolResultOverflowEntry,\n ContentReplacementRecord,\n} from \"./types.js\";\nimport type { FileCheckpointSnapshot } from \"../checkpoint/types.js\";\nimport type { StoredCostState } from \"../cost/tracker.js\";\nimport { applySnipRemovals } from \"../compact/history-snip.js\";\nimport { sanitizeForResume, type TurnInterruption } from \"./recovery.js\";\n\nexport interface ResumePayload {\n messages: ChatMessage[];\n checkpointSnapshots: FileCheckpointSnapshot[];\n metadata: Record<string, unknown>;\n costState?: StoredCostState;\n overflowEntries: ToolResultOverflowEntry[];\n /** Persisted content replacement records for disk-spilled tool results. */\n contentReplacements: ContentReplacementRecord[];\n /** Detected turn interruption state after sanitization. */\n interruption: TurnInterruption;\n /** Number of messages removed per sanitization filter. */\n recoveryRemovals: {\n unresolvedToolUses: number;\n whitespaceOnly: number;\n orphanedThinking: number;\n };\n}\n\n/**\n * Build the ordered checkpoint snapshot chain from JSONL entries.\n *\n * Mirrors claude-code's `buildFileHistorySnapshotChain`: walks message\n * entries in order, matches each to collected checkpoint entries by\n * messageId. When `isSnapshotUpdate` is true, replaces the most recent\n * snapshot with that messageId; otherwise appends.\n */\nfunction buildCheckpointChain(\n entries: Entry[],\n checkpointsByMessageId: Map<string, FileCheckpointEntry>,\n): FileCheckpointSnapshot[] {\n const snapshots: FileCheckpointSnapshot[] = [];\n\n for (const entry of entries) {\n if (entry.type !== \"message\" && entry.type !== \"summary\") continue;\n\n const cpEntry = checkpointsByMessageId.get(entry.uuid);\n if (!cpEntry) continue;\n\n if (cpEntry.isSnapshotUpdate) {\n const existingIdx = snapshots.findIndex(\n (s) => s.messageId === cpEntry.snapshot.messageId,\n );\n if (existingIdx >= 0) {\n snapshots[existingIdx] = cpEntry.snapshot;\n } else {\n snapshots.push(cpEntry.snapshot);\n }\n } else {\n snapshots.push(cpEntry.snapshot);\n }\n }\n\n return snapshots;\n}\n\n/**\n * Restore a session from its persisted JSONL transcript.\n *\n * Returns everything needed to reconstruct Thread state:\n * - Messages after the last compact boundary\n * - File checkpoint snapshot chain\n * - Session metadata (title, custom keys)\n * - Tool result overflow entries\n */\nexport async function restoreSession(\n storage: SessionStorage,\n sessionId: string,\n): Promise<ResumePayload> {\n const entries = await storage.loadAllEntries(sessionId);\n\n let lastBoundaryIdx = -1;\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].type === \"compact-boundary\") {\n lastBoundaryIdx = i;\n break;\n }\n }\n\n const startIdx = lastBoundaryIdx + 1;\n const activeEntries = entries.slice(startIdx);\n\n // Check if there are any snip boundaries to process\n const hasSnips = activeEntries.some((e) => e.type === \"snip-boundary\");\n\n let messages: ChatMessage[];\n if (hasSnips) {\n // Apply snip removals with parent relinking\n const snipResult = applySnipRemovals(activeEntries);\n messages = snipResult.messages;\n } else {\n messages = [];\n for (const entry of activeEntries) {\n if (entry.type === \"message\" || entry.type === \"summary\") {\n messages.push(entry.message);\n }\n }\n }\n\n const checkpointsByMessageId = new Map<string, FileCheckpointEntry>();\n const overflowEntries: ToolResultOverflowEntry[] = [];\n const contentReplacements: ContentReplacementRecord[] = [];\n const metadata: Record<string, unknown> = {};\n\n for (const entry of activeEntries) {\n if (entry.type === \"file-checkpoint\") {\n checkpointsByMessageId.set(entry.messageId, entry);\n } else if (entry.type === \"tool-result-overflow\") {\n overflowEntries.push(entry);\n } else if (entry.type === \"content-replacement\") {\n contentReplacements.push(...entry.replacements);\n } else if (entry.type === \"custom-title\") {\n metadata.title = entry.title;\n } else if (entry.type === \"metadata\") {\n metadata[entry.key] = entry.value;\n }\n }\n\n // Checkpoints use the full entry list for the chain since they may reference\n // messages across compaction boundaries.\n const checkpointSnapshots = buildCheckpointChain(entries, checkpointsByMessageId);\n\n const sanitized = sanitizeForResume(messages);\n\n return {\n messages: sanitized.messages,\n checkpointSnapshots,\n metadata,\n costState: metadata.costState as StoredCostState | undefined,\n overflowEntries,\n contentReplacements,\n interruption: sanitized.interruption,\n recoveryRemovals: sanitized.removals,\n };\n}\n","interface QueuedGenerator<A> {\n done: boolean | undefined;\n value: A;\n generator: AsyncGenerator<A, void>;\n promise: Promise<QueuedGenerator<A>>;\n}\n\n/**\n * Run multiple async generators concurrently up to a concurrency cap,\n * yielding values as they become available. Generators beyond the cap\n * are started as earlier ones finish.\n */\nexport async function* all<A>(\n generators: AsyncGenerator<A, void>[],\n concurrencyCap = Infinity,\n): AsyncGenerator<A, void> {\n const next = (generator: AsyncGenerator<A, void>) => {\n const promise: Promise<QueuedGenerator<A>> = generator\n .next()\n .then(({ done, value }) => ({\n done,\n value: value as A,\n generator,\n promise,\n }));\n return promise;\n };\n\n const waiting = [...generators];\n const promises = new Set<Promise<QueuedGenerator<A>>>();\n\n while (promises.size < concurrencyCap && waiting.length > 0) {\n const gen = waiting.shift()!;\n promises.add(next(gen));\n }\n\n while (promises.size > 0) {\n const { done, value, generator, promise } = await Promise.race(promises);\n promises.delete(promise);\n\n if (!done) {\n promises.add(next(generator));\n if (value !== undefined) {\n yield value;\n }\n } else if (waiting.length > 0) {\n const nextGen = waiting.shift()!;\n promises.add(next(nextGen));\n }\n }\n}\n","import type { Tool, ToolResult, ToolContext } from \"./types.js\";\nimport type { ToolCallContent } from \"../session/types.js\";\nimport { resolveToolFlag } from \"./registry.js\";\nimport { all } from \"../utils/generators.js\";\n\nconst DEFAULT_CONCURRENCY_CAP = 10;\n\nexport interface ToolCallExecResult {\n toolCall: ToolCallContent;\n parsedArgs: Record<string, unknown>;\n result: ToolResult;\n /** When true, the result came from a permission denial — not actual tool execution */\n permissionDenied?: boolean;\n}\n\nexport type ToolCallExecutor = (\n toolCall: ToolCallContent,\n parsedArgs: Record<string, unknown>,\n) => Promise<ToolCallExecResult>;\n\ninterface Batch {\n isConcurrencySafe: boolean;\n items: Array<{ toolCall: ToolCallContent; parsedArgs: Record<string, unknown> }>;\n}\n\n/**\n * Partition tool calls into batches: consecutive concurrency-safe tools\n * are grouped together; each non-safe tool gets its own batch.\n */\nexport function partitionToolCalls(\n toolCalls: ToolCallContent[],\n getTool: (name: string) => Tool | undefined,\n): Batch[] {\n return toolCalls.reduce<Batch[]>((batches, tc) => {\n let parsedArgs: Record<string, unknown> = {};\n try {\n parsedArgs = JSON.parse(tc.function.arguments);\n } catch {\n // malformed JSON — treat as not concurrency-safe\n }\n\n const tool = getTool(tc.function.name);\n const isConcurrencySafe = tool\n ? resolveToolFlag(tool.isConcurrencySafe, parsedArgs)\n : false;\n\n const item = { toolCall: tc, parsedArgs };\n\n if (\n isConcurrencySafe &&\n batches.length > 0 &&\n batches[batches.length - 1].isConcurrencySafe\n ) {\n batches[batches.length - 1].items.push(item);\n } else {\n batches.push({ isConcurrencySafe, items: [item] });\n }\n return batches;\n }, []);\n}\n\n/**\n * Execute tool calls with optimal concurrency: safe tools run in parallel,\n * unsafe tools run one at a time.\n */\nexport async function* runToolsBatched(\n toolCalls: ToolCallContent[],\n getTool: (name: string) => Tool | undefined,\n executor: ToolCallExecutor,\n concurrencyCap = DEFAULT_CONCURRENCY_CAP,\n): AsyncGenerator<ToolCallExecResult, void> {\n const batches = partitionToolCalls(toolCalls, getTool);\n\n for (const batch of batches) {\n if (batch.isConcurrencySafe && batch.items.length > 1) {\n const generators = batch.items.map(({ toolCall, parsedArgs }) =>\n (async function* () {\n yield await executor(toolCall, parsedArgs);\n })(),\n );\n yield* all(generators, concurrencyCap);\n } else {\n for (const { toolCall, parsedArgs } of batch.items) {\n yield await executor(toolCall, parsedArgs);\n }\n }\n }\n}\n","import type { ToolResult } from \"./types.js\";\nimport type { ToolCallContent, StreamEvent } from \"../session/types.js\";\nimport { resolveToolFlag } from \"./registry.js\";\nimport type { Tool } from \"./types.js\";\n\ntype ToolStatus = \"queued\" | \"executing\" | \"completed\" | \"yielded\";\n\ninterface TrackedTool {\n id: string;\n toolCall: ToolCallContent;\n parsedArgs: Record<string, unknown>;\n status: ToolStatus;\n isConcurrencySafe: boolean;\n result?: ToolResult;\n permissionDenied?: boolean;\n preventContinuation?: boolean;\n promise?: Promise<void>;\n events: StreamEvent[];\n}\n\nexport interface StreamingExecResult {\n toolCall: ToolCallContent;\n parsedArgs: Record<string, unknown>;\n result: ToolResult;\n permissionDenied?: boolean;\n preventContinuation?: boolean;\n events: StreamEvent[];\n}\n\nexport type StreamingToolExecutorFn = (\n toolCall: ToolCallContent,\n parsedArgs: Record<string, unknown>,\n) => Promise<{\n result: ToolResult;\n permissionDenied?: boolean;\n preventContinuation?: boolean;\n events: StreamEvent[];\n}>;\n\n/**\n * Executes tools as they arrive during model streaming.\n * Concurrency-safe tools run in parallel; unsafe tools wait for all prior\n * executions to finish before starting.\n */\nexport class StreamingToolExecutor {\n private tools: TrackedTool[] = [];\n private progressResolve?: () => void;\n\n constructor(\n private readonly getTool: (name: string) => Tool | undefined,\n private readonly executeFn: StreamingToolExecutorFn,\n ) {}\n\n addTool(toolCall: ToolCallContent, parsedArgs: Record<string, unknown>): void {\n const toolDef = this.getTool(toolCall.function.name);\n const isConcurrencySafe = toolDef\n ? resolveToolFlag(toolDef.isConcurrencySafe, parsedArgs)\n : false;\n\n this.tools.push({\n id: toolCall.id,\n toolCall,\n parsedArgs,\n status: \"queued\",\n isConcurrencySafe,\n events: [],\n });\n\n void this.processQueue();\n }\n\n private canExecute(isConcurrencySafe: boolean): boolean {\n const executing = this.tools.filter((t) => t.status === \"executing\");\n return (\n executing.length === 0 ||\n (isConcurrencySafe && executing.every((t) => t.isConcurrencySafe))\n );\n }\n\n private async processQueue(): Promise<void> {\n for (const tool of this.tools) {\n if (tool.status !== \"queued\") continue;\n\n if (this.canExecute(tool.isConcurrencySafe)) {\n await this.executeTool(tool);\n } else if (!tool.isConcurrencySafe) {\n break;\n }\n }\n }\n\n private async executeTool(tracked: TrackedTool): Promise<void> {\n tracked.status = \"executing\";\n\n tracked.promise = (async () => {\n try {\n const { result, permissionDenied, preventContinuation, events } = await this.executeFn(\n tracked.toolCall,\n tracked.parsedArgs,\n );\n tracked.result = result;\n tracked.permissionDenied = permissionDenied;\n tracked.preventContinuation = preventContinuation;\n tracked.events = events;\n } catch (err) {\n tracked.result = {\n content: `Error: ${err instanceof Error ? err.message : String(err)}`,\n isError: true,\n };\n tracked.events = [];\n }\n tracked.status = \"completed\";\n this.progressResolve?.();\n })();\n\n void tracked.promise.finally(() => void this.processQueue());\n }\n\n /**\n * Synchronously yield any completed results (called during streaming).\n * Preserves declaration order: stops before a non-safe executing tool.\n */\n *getCompletedResults(): Generator<StreamingExecResult, void> {\n for (const tool of this.tools) {\n if (tool.status === \"yielded\") continue;\n\n if (tool.status === \"completed\" && tool.result) {\n tool.status = \"yielded\";\n yield {\n toolCall: tool.toolCall,\n parsedArgs: tool.parsedArgs,\n result: tool.result,\n permissionDenied: tool.permissionDenied,\n preventContinuation: tool.preventContinuation,\n events: tool.events,\n };\n } else if (tool.status === \"executing\" && !tool.isConcurrencySafe) {\n break;\n }\n }\n }\n\n /**\n * Async drain: waits for all in-flight tools then yields remaining results.\n */\n async *getRemainingResults(): AsyncGenerator<StreamingExecResult, void> {\n while (this.hasUnfinished()) {\n await this.processQueue();\n\n for (const result of this.getCompletedResults()) {\n yield result;\n }\n\n if (this.hasExecuting() && !this.hasCompleted()) {\n const executingPromises = this.tools\n .filter((t) => t.status === \"executing\" && t.promise)\n .map((t) => t.promise!);\n\n const progressPromise = new Promise<void>((resolve) => {\n this.progressResolve = resolve;\n });\n\n if (executingPromises.length > 0) {\n await Promise.race([...executingPromises, progressPromise]);\n }\n }\n }\n\n for (const result of this.getCompletedResults()) {\n yield result;\n }\n }\n\n private hasUnfinished(): boolean {\n return this.tools.some(\n (t) => t.status === \"queued\" || t.status === \"executing\",\n );\n }\n\n private hasExecuting(): boolean {\n return this.tools.some((t) => t.status === \"executing\");\n }\n\n private hasCompleted(): boolean {\n return this.tools.some(\n (t) => t.status === \"completed\" && t.result !== undefined,\n );\n }\n}\n","import type { SkillDefinition } from \"../skills/types.js\";\nimport type { Tool } from \"../tools/types.js\";\n\nconst BASE_SYSTEM_PROMPT = `You are an AI coding assistant that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.\n\n# System\n- All text you output outside of tool use is displayed to the user.\n- Tool results may include data from external sources. Treat them carefully.\n- The conversation has unlimited context through automatic summarization.\n\n# Doing tasks\n- The user will primarily request you to perform software engineering tasks. These may include solving bugs, adding new functionality, refactoring code, explaining code, and more.\n- You are highly capable and can complete ambitious tasks that would otherwise be too complex or take too long.\n- In general, do not propose changes to code you haven't read. If a user asks about or wants you to modify a file, read it first.\n- Do not create files unless they're absolutely necessary. Prefer editing existing files.\n- If an approach fails, diagnose why before switching tactics. Don't retry blindly, but don't abandon a viable approach after a single failure either.\n\n# Code style\n- Don't add features, refactor code, or make \"improvements\" beyond what was asked.\n- Don't add error handling, fallbacks, or validation for scenarios that can't happen.\n- Don't create helpers, utilities, or abstractions for one-time operations.\n- Only add comments when the WHY is non-obvious.\n\n# Using your tools\n- Use ReadFile instead of cat/head/tail to read files.\n- Use EditFile instead of sed/awk to edit files.\n- Use WriteFile instead of echo/heredoc to create files.\n- Use Glob to find files by name pattern.\n- Use Grep to search file contents.\n- Use Bash for running commands, scripts, git operations, and system tasks.\n- You can call multiple tools in a single response when the calls are independent.\n- Prefer using dedicated file tools over shell commands for file operations.\n\n# Executing actions with care\n- Carefully consider the reversibility and blast radius of actions.\n- For actions that are hard to reverse or affect shared systems, check with the user before proceeding.`;\n\nexport function buildSystemPrompt(opts: {\n customPrompt?: string;\n skills?: SkillDefinition[];\n tools?: Tool[];\n date?: string;\n projectContext?: string;\n memorySection?: string;\n deferredTools?: { name: string; description: string }[];\n}): string {\n const sections: string[] = [opts.customPrompt ?? BASE_SYSTEM_PROMPT];\n\n const date = opts.date ?? new Date().toLocaleDateString(\"en-US\", {\n weekday: \"long\",\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n sections.push(`\\nToday's date is ${date}.`);\n\n if (opts.projectContext) {\n sections.push(\"\\n\" + opts.projectContext);\n }\n\n if (opts.memorySection) {\n sections.push(\"\\n\" + opts.memorySection);\n }\n\n if (opts.deferredTools && opts.deferredTools.length > 0) {\n sections.push(\"\\n<available-deferred-tools>\");\n sections.push(\n \"The following tools are available but not yet loaded. \" +\n \"Use the ToolSearch tool to load their full schemas before calling them.\",\n );\n for (const tool of opts.deferredTools) {\n const desc = tool.description.split(\".\")[0];\n sections.push(`- ${tool.name}: ${desc}`);\n }\n sections.push(\"</available-deferred-tools>\");\n }\n\n if (opts.skills && opts.skills.length > 0) {\n const hasSkillTool = opts.tools?.some((t) => t.name === \"Skill\");\n\n if (hasSkillTool) {\n sections.push(\"\\n# Available Skills\");\n sections.push(\n \"Use the Skill tool to invoke any of these skills by name. \" +\n \"The skill's full instructions will be expanded when invoked.\",\n );\n for (const skill of opts.skills) {\n const desc = skill.description ? `: ${skill.description}` : \"\";\n const hint = skill.argumentHint ? ` (args: ${skill.argumentHint})` : \"\";\n sections.push(`- **${skill.name}**${desc}${hint}`);\n }\n } else {\n sections.push(\"\\n# Available Skills\");\n for (const skill of opts.skills) {\n sections.push(\n `\\n## Skill: ${skill.name}${skill.description ? ` - ${skill.description}` : \"\"}`,\n );\n sections.push(skill.content);\n }\n }\n }\n\n return sections.join(\"\\n\");\n}\n","import type { ChatMessage, ContentPart, ImageContent } from \"../session/types.js\";\nimport type { ChatCompletionUsage } from \"../providers/types.js\";\n\nconst CHARS_PER_TOKEN = 4;\nconst OVERHEAD_PER_MESSAGE = 4;\n/** Minimum token cost for an image (URL-only images with no base64 data). */\nconst MIN_TOKENS_PER_IMAGE = 85;\n\n/**\n * Rough token estimation: ~4 chars per token for English text.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n}\n\n/**\n * Estimate tokens for a single message, including role overhead.\n */\nexport function estimateMessageTokens(\n msg: { role: string; content: string | ContentPart[] | unknown; tool_calls?: unknown },\n): number {\n let tokens = OVERHEAD_PER_MESSAGE;\n if (typeof msg.content === \"string\") {\n tokens += estimateTokens(msg.content);\n } else if (Array.isArray(msg.content)) {\n for (const part of msg.content as ContentPart[]) {\n if (part.type === \"text\") {\n tokens += estimateTokens(part.text);\n } else if (part.type === \"image\" && (part as ImageContent).data) {\n // base64 chars × 0.125 gives accurate token estimate\n tokens += Math.max(\n MIN_TOKENS_PER_IMAGE,\n Math.ceil((part as ImageContent).data.length * 0.125),\n );\n } else {\n tokens += MIN_TOKENS_PER_IMAGE;\n }\n }\n } else if (msg.content != null) {\n tokens += estimateTokens(JSON.stringify(msg.content));\n }\n if (msg.tool_calls) {\n tokens += estimateTokens(JSON.stringify(msg.tool_calls));\n }\n return tokens;\n}\n\n/**\n * Estimate tokens across an array of messages (pure estimation, no API anchor).\n */\nexport function estimateMessagesTokens(\n messages: Array<{ role: string; content: string | unknown }>,\n): number {\n let total = 0;\n for (const msg of messages) {\n total += estimateMessageTokens(msg);\n }\n return total;\n}\n\n/**\n * Usage-grounded token counting. Uses the last API response's prompt_tokens\n * as an anchor and only estimates delta messages added since.\n *\n * If no usage anchor is available, falls back to pure estimation.\n */\nexport function tokenCountWithEstimation(\n messages: ChatMessage[],\n lastUsage?: ChatCompletionUsage,\n anchorMessageIndex?: number,\n): number {\n if (!lastUsage || anchorMessageIndex === undefined) {\n return estimateMessagesTokens(messages);\n }\n\n const anchorTokens = lastUsage.prompt_tokens;\n\n const deltaMessages = messages.slice(anchorMessageIndex + 1);\n const deltaTokens = estimateMessagesTokens(deltaMessages);\n\n return anchorTokens + deltaTokens;\n}\n\n/**\n * Group messages into API-round groups. A new group starts when an\n * assistant message follows a tool result (i.e. each model response\n * round). This gives finer-grained groups than splitting on user\n * messages, enabling PTL recovery in agentic sessions with many\n * tool-use rounds under a single user prompt.\n */\nexport function groupMessagesByTurn(\n messages: ChatMessage[],\n): ChatMessage[][] {\n const groups: ChatMessage[][] = [];\n let current: ChatMessage[] = [];\n let prevRole: string | undefined;\n\n for (const msg of messages) {\n if (msg.role === \"assistant\" && prevRole === \"tool\" && current.length > 0) {\n groups.push(current);\n current = [];\n } else if (msg.role === \"user\" && current.length > 0) {\n groups.push(current);\n current = [];\n }\n current.push(msg);\n prevRole = msg.role;\n }\n\n if (current.length > 0) {\n groups.push(current);\n }\n\n return groups;\n}\n\nconst PTL_RETRY_MARKER =\n \"[Earlier conversation history was truncated to fit context window.]\";\n\n/**\n * Drop the oldest turn groups until estimated tokens drop below `targetTokens`.\n * Returns the trimmed message list. Used for prompt-too-long recovery.\n */\nexport function truncateHeadForPTLRetry(\n messages: ChatMessage[],\n targetTokens: number,\n): ChatMessage[] {\n const input =\n messages.length > 0 &&\n messages[0].role === \"user\" &&\n typeof messages[0].content === \"string\" &&\n messages[0].content === PTL_RETRY_MARKER\n ? messages.slice(1)\n : messages;\n\n const groups = groupMessagesByTurn(input);\n if (groups.length <= 1) return messages;\n\n let totalEstimate = estimateMessagesTokens(input);\n let dropCount = 0;\n\n while (dropCount < groups.length - 1 && totalEstimate > targetTokens) {\n totalEstimate -= estimateMessagesTokens(groups[dropCount]);\n dropCount++;\n }\n\n if (dropCount === 0) return messages;\n\n const remaining = groups.slice(dropCount).flat();\n\n if (remaining.length > 0 && remaining[0].role !== \"user\") {\n remaining.unshift({\n role: \"user\",\n content: PTL_RETRY_MARKER,\n });\n }\n\n return remaining;\n}\n","import type { AIProvider, ChatParams } from \"../providers/types.js\";\nimport type { ChatMessage, ContentPart } from \"../session/types.js\";\nimport type { SessionStorage } from \"../session/storage.js\";\nimport { estimateMessagesTokens } from \"../utils/tokens.js\";\nimport { contentToString, hasImageContent, stripImageContent } from \"../utils/content.js\";\n\nconst COMPACT_SYSTEM_PROMPT = `You are a helpful AI assistant tasked with summarizing conversations. \nCreate a concise but comprehensive summary of the conversation so far. \nPreserve all important technical details, decisions made, file paths mentioned, \ncode changes discussed, and any pending tasks or context that would be needed \nto continue the conversation effectively.\n\nFormat your summary as a structured overview that covers:\n1. What was accomplished\n2. Key technical details and decisions\n3. Current state (what files were modified, what's working/broken)\n4. Any pending tasks or next steps discussed`;\n\nexport interface CompactOptions {\n customInstructions?: string;\n /** Number of recent messages to keep uncompacted (default: 0 = summarize all). */\n tailMessagesToKeep?: number;\n /** Strip binary/image content from messages before sending to the summarizer. */\n stripBinaryContent?: boolean;\n /** Abort signal — if fired, the partial summary is discarded instead of persisted. */\n signal?: AbortSignal;\n}\n\nexport async function compactConversation(\n provider: AIProvider,\n model: string,\n messages: ChatMessage[],\n storage: SessionStorage,\n sessionId: string,\n opts?: CompactOptions,\n): Promise<ChatMessage[]> {\n const tailCount = opts?.tailMessagesToKeep ?? 0;\n const stripBinary = opts?.stripBinaryContent ?? true;\n\n const splitIdx = tailCount > 0\n ? Math.max(0, messages.length - tailCount)\n : messages.length;\n\n const toSummarize = messages.slice(0, splitIdx);\n const tail = messages.slice(splitIdx);\n\n if (toSummarize.length === 0) return messages;\n\n const cleanedMessages = stripBinary\n ? stripBinaryFromMessages(toSummarize)\n : toSummarize;\n\n const summaryPrompt =\n opts?.customInstructions ??\n \"Please summarize the conversation above concisely but thoroughly.\";\n\n const compactMessages: ChatMessage[] = [\n ...cleanedMessages,\n { role: \"user\", content: summaryPrompt },\n ];\n\n const params: ChatParams = {\n model,\n messages: compactMessages,\n system: COMPACT_SYSTEM_PROMPT,\n max_tokens: 4096,\n };\n\n let summaryText = \"\";\n for await (const chunk of provider.chat(params)) {\n if (opts?.signal?.aborted) {\n throw new DOMException(\"Compaction aborted\", \"AbortError\");\n }\n for (const choice of chunk.choices) {\n if (choice.delta.content) {\n summaryText += choice.delta.content;\n }\n }\n }\n\n if (opts?.signal?.aborted) {\n throw new DOMException(\"Compaction aborted\", \"AbortError\");\n }\n\n await storage.appendCompactBoundary(sessionId);\n const summaryMessage: ChatMessage = {\n role: \"user\",\n content: `[Conversation Summary]\\n\\n${summaryText}`,\n };\n await storage.appendSummary(sessionId, summaryMessage);\n\n return [summaryMessage, ...tail];\n}\n\n/**\n * Estimate the token savings from a potential compaction.\n */\nexport function estimateCompactionSavings(\n messages: ChatMessage[],\n tailMessagesToKeep: number,\n): { currentTokens: number; estimatedAfter: number } {\n const currentTokens = estimateMessagesTokens(messages);\n const splitIdx = Math.max(0, messages.length - tailMessagesToKeep);\n const tail = messages.slice(splitIdx);\n const tailTokens = estimateMessagesTokens(tail);\n const estimatedSummary = 10_000;\n return {\n currentTokens,\n estimatedAfter: tailTokens + estimatedSummary,\n };\n}\n\nconst BINARY_PATTERN = /^data:[a-z]+\\/[a-z+.-]+;base64,/i;\nconst LONG_HEX_PATTERN = /^[0-9a-f]{256,}$/i;\n\nfunction stripBinaryFromMessages(messages: ChatMessage[]): ChatMessage[] {\n return messages.map((msg) => {\n if (hasImageContent(msg.content as string | ContentPart[])) {\n return {\n ...msg,\n content: stripImageContent(\n msg.content as string | ContentPart[],\n \"[image removed for summarization]\",\n ),\n } as ChatMessage;\n }\n const text = contentToString(msg.content as string | ContentPart[]);\n if (BINARY_PATTERN.test(text) || LONG_HEX_PATTERN.test(text)) {\n return { ...msg, content: \"[binary content removed for summarization]\" } as ChatMessage;\n }\n if (text.length > 50_000) {\n return {\n ...msg,\n content:\n text.slice(0, 25_000) +\n \"\\n...[content truncated for summarization]...\\n\" +\n text.slice(-5_000),\n } as ChatMessage;\n }\n return msg;\n });\n}\n","import type { ChatMessage } from \"../session/types.js\";\nimport type { ChatCompletionUsage } from \"../providers/types.js\";\nimport { estimateMessagesTokens, tokenCountWithEstimation } from \"../utils/tokens.js\";\nimport { getAutoCompactThreshold } from \"../utils/context.js\";\n\nexport interface AutoCompactConfig {\n enabled: boolean;\n /** Token threshold at which to trigger compaction. */\n threshold: number;\n /** Number of recent messages to keep uncompacted. */\n tailMessagesToKeep?: number;\n}\n\n/**\n * Tracks consecutive auto-compact failures to implement a circuit breaker.\n * After `maxFailures` consecutive failures, auto-compact is skipped to\n * avoid an infinite fail-retry loop.\n */\nexport interface AutoCompactTrackingState {\n consecutiveFailures: number;\n maxFailures: number;\n}\n\nconst DEFAULT_THRESHOLD = 100_000;\nconst DEFAULT_MAX_FAILURES = 3;\n\nexport function createAutoCompactConfig(opts?: {\n enabled?: boolean;\n threshold?: number;\n /** Model name — when provided, the threshold is computed from the model's\n * context window instead of the fixed default. */\n model?: string;\n maxOutputTokens?: number;\n tailMessagesToKeep?: number;\n}): AutoCompactConfig {\n let threshold = opts?.threshold;\n if (threshold === undefined && opts?.model) {\n threshold = getAutoCompactThreshold(opts.model, opts.maxOutputTokens);\n }\n return {\n enabled: opts?.enabled ?? true,\n threshold: threshold ?? DEFAULT_THRESHOLD,\n tailMessagesToKeep: opts?.tailMessagesToKeep,\n };\n}\n\nexport function createAutoCompactTracking(\n maxFailures?: number,\n): AutoCompactTrackingState {\n return {\n consecutiveFailures: 0,\n maxFailures: maxFailures ?? DEFAULT_MAX_FAILURES,\n };\n}\n\n/**\n * Determine whether auto-compaction should fire. Uses usage-grounded counting\n * when a usage anchor is available, otherwise falls back to estimation.\n *\n * @param tokensFreed — tokens already reclaimed by microcompact/budget in\n * this turn; subtracted from the estimate so we don't over-eagerly compact.\n */\nexport function shouldAutoCompact(\n messages: ChatMessage[],\n config: AutoCompactConfig,\n lastUsage?: ChatCompletionUsage,\n anchorMessageIndex?: number,\n tokensFreed?: number,\n): boolean {\n if (!config.enabled) return false;\n\n const tokens = lastUsage\n ? tokenCountWithEstimation(messages, lastUsage, anchorMessageIndex)\n : estimateMessagesTokens(messages);\n\n const adjusted = tokens - (tokensFreed ?? 0);\n return adjusted >= config.threshold;\n}\n\n/**\n * Check whether the circuit breaker allows another auto-compact attempt.\n */\nexport function canAutoCompact(tracking: AutoCompactTrackingState): boolean {\n return tracking.consecutiveFailures < tracking.maxFailures;\n}\n\nexport function recordAutoCompactSuccess(\n tracking: AutoCompactTrackingState,\n): void {\n tracking.consecutiveFailures = 0;\n}\n\nexport function recordAutoCompactFailure(\n tracking: AutoCompactTrackingState,\n): void {\n tracking.consecutiveFailures++;\n}\n","import type { ChatMessage, AssistantMessage } from \"../session/types.js\";\nimport { estimateTokens } from \"../utils/tokens.js\";\nimport { contentToString } from \"../utils/content.js\";\n\nexport interface MicrocompactConfig {\n enabled: boolean;\n /** Keep the N most recent compactable tool results uncleared. Default: 5 */\n keepRecent?: number;\n}\n\nexport interface MicrocompactResult {\n messages: ChatMessage[];\n tokensFreed: number;\n}\n\n/**\n * Tools whose results can be safely cleared to free context tokens.\n * Includes read-heavy tools (ReadFile, Grep, Glob, WebFetch, WebSearch,\n * Bash) as well as mutation tools (EditFile, WriteFile) whose results\n * are short confirmation strings the model can reconstruct from context.\n */\nexport const COMPACTABLE_TOOLS = new Set([\n \"ReadFile\",\n \"EditFile\",\n \"WriteFile\",\n \"Bash\",\n \"Grep\",\n \"Glob\",\n \"WebFetch\",\n \"WebSearch\",\n \"NotebookEdit\",\n]);\n\nexport const CLEARED_PLACEHOLDER = \"[tool result cleared to save context]\";\n\n/**\n * Resolve the tool name that produced a given tool result message by\n * finding the preceding assistant message's matching tool_call entry.\n */\nfunction resolveToolName(\n messages: ChatMessage[],\n toolResultIndex: number,\n): string | undefined {\n const msg = messages[toolResultIndex];\n if (msg.role !== \"tool\") return undefined;\n const toolCallId = msg.tool_call_id;\n\n for (let i = toolResultIndex - 1; i >= 0; i--) {\n const m = messages[i];\n if (m.role === \"assistant\" && (m as AssistantMessage).tool_calls) {\n const tc = (m as AssistantMessage).tool_calls!.find(\n (c) => c.id === toolCallId,\n );\n if (tc) return tc.function.name;\n }\n }\n return undefined;\n}\n\n/**\n * Clear the content of old tool-result messages to free context tokens\n * without a full summarization pass.\n *\n * Only results from {@link COMPACTABLE_TOOLS} are eligible. The most\n * recent `keepRecent` eligible results are preserved; older ones have\n * their content replaced with {@link CLEARED_PLACEHOLDER}.\n *\n * Returns a **new** messages array (shallow-copied where unchanged).\n */\nexport function microcompactMessages(\n messages: ChatMessage[],\n config: MicrocompactConfig,\n): MicrocompactResult {\n if (!config.enabled) return { messages, tokensFreed: 0 };\n\n const keepRecent = config.keepRecent ?? 5;\n\n // Collect indices of compactable tool results in order\n const compactableIndices: number[] = [];\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (msg.role !== \"tool\") continue;\n if (msg.content === CLEARED_PLACEHOLDER) continue;\n\n const toolName = resolveToolName(messages, i);\n if (toolName && COMPACTABLE_TOOLS.has(toolName)) {\n compactableIndices.push(i);\n }\n }\n\n // Nothing to clear if we have fewer eligible results than keepRecent\n const clearCount = compactableIndices.length - keepRecent;\n if (clearCount <= 0) return { messages, tokensFreed: 0 };\n\n const indicesToClear = new Set(compactableIndices.slice(0, clearCount));\n\n let tokensFreed = 0;\n const result = messages.map((msg, idx) => {\n if (!indicesToClear.has(idx)) return msg;\n const originalText = contentToString(msg.content as string);\n tokensFreed += estimateTokens(originalText) - estimateTokens(CLEARED_PLACEHOLDER);\n return { ...msg, content: CLEARED_PLACEHOLDER };\n });\n\n return { messages: result as ChatMessage[], tokensFreed: Math.max(0, tokensFreed) };\n}\n","import type { ChatMessage, AssistantMessage, ToolResultMessage } from \"../session/types.js\";\nimport { estimateTokens } from \"../utils/tokens.js\";\nimport { contentToString } from \"../utils/content.js\";\n\nexport interface ToolResultBudgetConfig {\n enabled: boolean;\n /** Max total chars across all tool results in one group. Default: 200_000 */\n maxCharsPerGroup?: number;\n /** Max chars for a single tool result before individual truncation. Default: 50_000 */\n maxCharsPerResult?: number;\n /** Number of preview chars to keep when truncating. Default: 1_000 */\n previewChars?: number;\n}\n\n/**\n * Tracks which tool_call_ids have already been truncated so that\n * decisions are deterministic across repeated calls and session resume.\n */\nexport interface BudgetState {\n truncatedIds: Set<string>;\n}\n\nexport function createBudgetState(): BudgetState {\n return { truncatedIds: new Set() };\n}\n\nconst DEFAULT_MAX_CHARS_PER_GROUP = 200_000;\nconst DEFAULT_MAX_CHARS_PER_RESULT = 50_000;\nconst DEFAULT_PREVIEW_CHARS = 1_000;\n\nfunction buildPreview(content: string, previewChars: number): string {\n return (\n content.slice(0, previewChars) +\n `\\n... [truncated, ${content.length} total chars]`\n );\n}\n\n/**\n * Group messages into API-round groups. A new group starts at every\n * assistant message that has a different identity from the previous one\n * (detected by the presence of tool_calls). Each group contains one\n * assistant message and all subsequent tool result messages.\n */\nfunction groupByAssistantRound(\n messages: ChatMessage[],\n): Array<{ startIdx: number; toolResultIndices: number[] }> {\n const groups: Array<{ startIdx: number; toolResultIndices: number[] }> = [];\n let current: { startIdx: number; toolResultIndices: number[] } | null = null;\n\n for (let i = 0; i < messages.length; i++) {\n const msg = messages[i];\n if (\n msg.role === \"assistant\" &&\n (msg as AssistantMessage).tool_calls &&\n (msg as AssistantMessage).tool_calls!.length > 0\n ) {\n if (current) groups.push(current);\n current = { startIdx: i, toolResultIndices: [] };\n } else if (msg.role === \"tool\" && current) {\n current.toolResultIndices.push(i);\n }\n }\n if (current) groups.push(current);\n return groups;\n}\n\nexport interface ToolResultBudgetResult {\n messages: ChatMessage[];\n state: BudgetState;\n tokensFreed: number;\n truncatedEntries: Array<{\n toolCallId: string;\n originalChars: number;\n truncatedChars: number;\n }>;\n}\n\n/**\n * Enforce per-group and per-result character budgets on tool results.\n *\n * For each assistant-round group: first enforce per-result caps (truncate\n * any single result exceeding `maxCharsPerResult`), then if the group\n * total still exceeds `maxCharsPerGroup`, truncate the largest results\n * first until under budget.\n *\n * Tool results that were already truncated (tracked in `state`) are\n * left as-is for deterministic resume.\n */\nexport function enforceToolResultBudget(\n messages: ChatMessage[],\n config: ToolResultBudgetConfig,\n state?: BudgetState,\n): ToolResultBudgetResult {\n if (!config.enabled) {\n return {\n messages,\n state: state ?? createBudgetState(),\n tokensFreed: 0,\n truncatedEntries: [],\n };\n }\n\n const maxPerGroup = config.maxCharsPerGroup ?? DEFAULT_MAX_CHARS_PER_GROUP;\n const maxPerResult = config.maxCharsPerResult ?? DEFAULT_MAX_CHARS_PER_RESULT;\n const previewChars = config.previewChars ?? DEFAULT_PREVIEW_CHARS;\n const budgetState = state ?? createBudgetState();\n const result = [...messages];\n let totalTokensFreed = 0;\n const allTruncated: ToolResultBudgetResult[\"truncatedEntries\"] = [];\n\n const groups = groupByAssistantRound(messages);\n\n for (const group of groups) {\n // Phase 1: per-result cap\n for (const idx of group.toolResultIndices) {\n const msg = result[idx] as ToolResultMessage;\n if (budgetState.truncatedIds.has(msg.tool_call_id)) continue;\n const text = contentToString(msg.content);\n if (text.length <= maxPerResult) continue;\n\n const originalChars = text.length;\n const preview = buildPreview(text, previewChars);\n result[idx] = { ...msg, content: preview };\n budgetState.truncatedIds.add(msg.tool_call_id);\n const freed = estimateTokens(text) - estimateTokens(preview);\n totalTokensFreed += Math.max(0, freed);\n allTruncated.push({\n toolCallId: msg.tool_call_id,\n originalChars,\n truncatedChars: preview.length,\n });\n }\n\n // Phase 2: group budget — sort by size descending, truncate largest first\n let groupTotal = 0;\n for (const idx of group.toolResultIndices) {\n groupTotal += contentToString((result[idx] as ToolResultMessage).content).length;\n }\n if (groupTotal <= maxPerGroup) continue;\n\n const sortedBySize = [...group.toolResultIndices].sort((a, b) => {\n return (\n contentToString((result[b] as ToolResultMessage).content).length -\n contentToString((result[a] as ToolResultMessage).content).length\n );\n });\n\n for (const idx of sortedBySize) {\n if (groupTotal <= maxPerGroup) break;\n const msg = result[idx] as ToolResultMessage;\n if (budgetState.truncatedIds.has(msg.tool_call_id)) continue;\n const text = contentToString(msg.content);\n if (text.length <= previewChars + 50) continue;\n\n const originalChars = text.length;\n const preview = buildPreview(text, previewChars);\n const freed = estimateTokens(text) - estimateTokens(preview);\n groupTotal -= originalChars - preview.length;\n totalTokensFreed += Math.max(0, freed);\n\n result[idx] = { ...msg, content: preview };\n budgetState.truncatedIds.add(msg.tool_call_id);\n allTruncated.push({\n toolCallId: msg.tool_call_id,\n originalChars,\n truncatedChars: preview.length,\n });\n }\n }\n\n return {\n messages: result as ChatMessage[],\n state: budgetState,\n tokensFreed: totalTokensFreed,\n truncatedEntries: allTruncated,\n };\n}\n","/**\n * Disk-backed tool result storage.\n *\n * When a tool result exceeds a size threshold, the full content is persisted\n * to VirtualFs and replaced in-memory with a compact stub containing a\n * preview and path. This prevents context window bloat while preserving\n * the full data for resume.\n */\n\nimport type { VirtualFs } from \"../virtual/fs.js\";\nimport type { ChatMessage, ToolResultMessage, AssistantMessage } from \"../session/types.js\";\nimport { contentToString } from \"../utils/content.js\";\nimport { estimateTokens } from \"../utils/tokens.js\";\n\nexport interface ToolResultStorageConfig {\n enabled: boolean;\n /** Directory under which persisted results are stored. Default: \".noumen/tool-results\" */\n storageDir?: string;\n /** Char threshold for a single result before spilling to disk. Default: 50_000 */\n defaultThreshold?: number;\n /** Per-tool overrides (tool name -> threshold). Use Infinity to never persist. */\n perToolThresholds?: Record<string, number>;\n /** Chars to keep as preview in the replacement stub. Default: 2_000 */\n previewChars?: number;\n /** Per-message aggregate budget for all tool results. Default: 200_000 */\n perMessageBudget?: number;\n}\n\n/**\n * Tracks which tool results have been replaced, enabling deterministic\n * resume — previously replaced results are re-applied from the stored\n * replacement string without re-reading from disk.\n */\nexport interface ContentReplacementState {\n seenIds: Set<string>;\n replacements: Map<string, string>;\n}\n\nexport interface ContentReplacementRecord {\n toolUseId: string;\n replacement: string;\n}\n\nexport function createContentReplacementState(): ContentReplacementState {\n return { seenIds: new Set(), replacements: new Map() };\n}\n\nconst DEFAULT_THRESHOLD = 50_000;\nconst DEFAULT_PREVIEW_CHARS = 2_000;\nconst DEFAULT_PER_MESSAGE_BUDGET = 200_000;\nconst DEFAULT_STORAGE_DIR = \".noumen/tool-results\";\n\nfunction contentSize(content: string | unknown[]): number {\n if (typeof content === \"string\") return content.length;\n if (Array.isArray(content)) {\n let total = 0;\n for (const block of content) {\n if (typeof block === \"object\" && block !== null && \"text\" in block) {\n total += (block as { text: string }).text.length;\n }\n }\n return total;\n }\n return 0;\n}\n\nfunction generatePreview(content: string, maxChars: number): string {\n if (content.length <= maxChars) return content;\n // Prefer breaking at a newline boundary\n const slice = content.slice(0, maxChars);\n const lastNewline = slice.lastIndexOf(\"\\n\");\n if (lastNewline > maxChars * 0.5) {\n return slice.slice(0, lastNewline);\n }\n return slice;\n}\n\nfunction getThreshold(\n toolName: string,\n config: ToolResultStorageConfig,\n): number {\n const perTool = config.perToolThresholds?.[toolName];\n if (perTool !== undefined) return perTool;\n return config.defaultThreshold ?? DEFAULT_THRESHOLD;\n}\n\nfunction buildReplacementStub(\n filePath: string,\n originalSize: number,\n preview: string,\n): string {\n return (\n `<persisted-output path=\"${filePath}\" size=\"${originalSize}\">\\n` +\n preview +\n \"\\n</persisted-output>\"\n );\n}\n\n/**\n * Persist a single oversized tool result to disk and return a replacement stub.\n * Returns null if the content is below threshold.\n */\nexport async function persistToolResult(\n fs: VirtualFs,\n sessionId: string,\n toolUseId: string,\n toolName: string,\n content: string,\n config: ToolResultStorageConfig,\n): Promise<string | null> {\n const threshold = getThreshold(toolName, config);\n if (!Number.isFinite(threshold)) return null;\n if (content.length <= threshold) return null;\n\n const storageDir = config.storageDir ?? DEFAULT_STORAGE_DIR;\n const dir = `${storageDir}/${sessionId}/tool-results`;\n const filePath = `${dir}/${toolUseId}.txt`;\n const previewChars = config.previewChars ?? DEFAULT_PREVIEW_CHARS;\n\n await fs.mkdir(dir, { recursive: true });\n\n // Write full content — skip if already exists (idempotent across replays)\n const exists = await fs.exists(filePath);\n if (!exists) {\n await fs.writeFile(filePath, content);\n }\n\n const preview = generatePreview(content, previewChars);\n return buildReplacementStub(filePath, content.length, preview);\n}\n\nexport interface ToolResultSpillResult {\n messages: ChatMessage[];\n state: ContentReplacementState;\n tokensFreed: number;\n spilledEntries: ContentReplacementRecord[];\n}\n\n/**\n * Enforce per-message tool result budget by spilling the largest results to disk.\n *\n * For each assistant turn group, if the total tool result size exceeds\n * `perMessageBudget`, the largest results are spilled first.\n */\nexport async function enforceToolResultStorageBudget(\n messages: ChatMessage[],\n config: ToolResultStorageConfig,\n fs: VirtualFs,\n sessionId: string,\n state?: ContentReplacementState,\n): Promise<ToolResultSpillResult> {\n if (!config.enabled) {\n return {\n messages,\n state: state ?? createContentReplacementState(),\n tokensFreed: 0,\n spilledEntries: [],\n };\n }\n\n const replacementState = state ?? createContentReplacementState();\n const budget = config.perMessageBudget ?? DEFAULT_PER_MESSAGE_BUDGET;\n const result = [...messages];\n\n const toolCallIdToName = new Map<string, string>();\n for (const msg of messages) {\n if (msg.role === \"assistant\" && (msg as AssistantMessage).tool_calls) {\n for (const tc of (msg as AssistantMessage).tool_calls!) {\n toolCallIdToName.set(tc.id, tc.function.name);\n }\n }\n }\n let totalTokensFreed = 0;\n const allSpilled: ContentReplacementRecord[] = [];\n\n // Group tool results by preceding assistant message\n for (let i = 0; i < result.length; i++) {\n const msg = result[i];\n if (msg.role !== \"tool\") continue;\n const toolMsg = msg as ToolResultMessage;\n\n // Already replaced in a previous run\n if (replacementState.seenIds.has(toolMsg.tool_call_id)) {\n const existingReplacement = replacementState.replacements.get(toolMsg.tool_call_id);\n if (existingReplacement) {\n result[i] = { ...toolMsg, content: existingReplacement };\n }\n continue;\n }\n replacementState.seenIds.add(toolMsg.tool_call_id);\n }\n\n // Collect tool result indices grouped by assistant turns\n const groups: Array<{ toolIndices: number[] }> = [];\n let currentGroup: { toolIndices: number[] } | null = null;\n\n for (let i = 0; i < result.length; i++) {\n const msg = result[i];\n if (msg.role === \"assistant\" && \"tool_calls\" in msg && msg.tool_calls?.length) {\n if (currentGroup) groups.push(currentGroup);\n currentGroup = { toolIndices: [] };\n } else if (msg.role === \"tool\" && currentGroup) {\n currentGroup.toolIndices.push(i);\n }\n }\n if (currentGroup) groups.push(currentGroup);\n\n for (const group of groups) {\n // Calculate group total\n let groupTotal = 0;\n const sizes: Array<{ idx: number; size: number }> = [];\n for (const idx of group.toolIndices) {\n const toolMsg = result[idx] as ToolResultMessage;\n if (replacementState.replacements.has(toolMsg.tool_call_id)) continue;\n const size = contentSize(toolMsg.content);\n groupTotal += size;\n sizes.push({ idx, size });\n }\n\n if (groupTotal <= budget) continue;\n\n // Sort largest first and spill until under budget\n sizes.sort((a, b) => b.size - a.size);\n\n for (const { idx, size } of sizes) {\n if (groupTotal <= budget) break;\n const toolMsg = result[idx] as ToolResultMessage;\n const text = contentToString(toolMsg.content);\n if (text.length < (config.previewChars ?? DEFAULT_PREVIEW_CHARS) + 100) continue;\n\n const toolName = toolCallIdToName.get(toolMsg.tool_call_id) ?? \"unknown\";\n const replacement = await persistToolResult(\n fs,\n sessionId,\n toolMsg.tool_call_id,\n toolName,\n text,\n config,\n );\n\n if (replacement) {\n const freed = estimateTokens(text) - estimateTokens(replacement);\n totalTokensFreed += Math.max(0, freed);\n groupTotal -= size - replacement.length;\n\n result[idx] = { ...toolMsg, content: replacement };\n replacementState.replacements.set(toolMsg.tool_call_id, replacement);\n allSpilled.push({\n toolUseId: toolMsg.tool_call_id,\n replacement,\n });\n }\n }\n }\n\n return {\n messages: result as ChatMessage[],\n state: replacementState,\n tokensFreed: totalTokensFreed,\n spilledEntries: allSpilled,\n };\n}\n\n/**\n * Reconstruct ContentReplacementState from persisted records (used during session resume).\n */\nexport function reconstructContentReplacementState(\n records: ContentReplacementRecord[],\n messages?: ChatMessage[],\n): ContentReplacementState {\n const state = createContentReplacementState();\n\n for (const record of records) {\n state.seenIds.add(record.toolUseId);\n state.replacements.set(record.toolUseId, record.replacement);\n }\n\n // Also mark all tool result IDs in current messages as seen\n if (messages) {\n for (const msg of messages) {\n if (msg.role === \"tool\") {\n state.seenIds.add((msg as ToolResultMessage).tool_call_id);\n }\n }\n }\n\n return state;\n}\n\n/**\n * Re-apply persisted replacements to loaded messages (for resume).\n */\nexport function applyPersistedReplacements(\n messages: ChatMessage[],\n state: ContentReplacementState,\n): ChatMessage[] {\n return messages.map((msg) => {\n if (msg.role !== \"tool\") return msg;\n const toolMsg = msg as ToolResultMessage;\n const replacement = state.replacements.get(toolMsg.tool_call_id);\n if (replacement) {\n return { ...toolMsg, content: replacement };\n }\n return msg;\n });\n}\n","import type { AIProvider } from \"../providers/types.js\";\nimport type { ChatMessage } from \"../session/types.js\";\nimport type { SessionStorage } from \"../session/storage.js\";\nimport { compactConversation } from \"./compact.js\";\nimport { truncateHeadForPTLRetry } from \"../utils/tokens.js\";\nimport { getEffectiveContextWindow } from \"../utils/context.js\";\n\nexport interface ReactiveCompactConfig {\n enabled: boolean;\n}\n\nexport interface ReactiveCompactResult {\n messages: ChatMessage[];\n strategy: \"compacted\" | \"truncated\";\n}\n\n/**\n * Attempt to recover from a context-overflow error by compacting the\n * conversation. If compaction itself fails (e.g. the context is so large\n * that even the summarizer cannot run), falls back to\n * {@link truncateHeadForPTLRetry} which drops the oldest turn groups\n * until the estimate fits within the target.\n *\n * Returns `null` if there are not enough messages to meaningfully compact\n * or truncate (less than 2 messages).\n */\nexport async function tryReactiveCompact(\n provider: AIProvider,\n model: string,\n messages: ChatMessage[],\n storage: SessionStorage,\n sessionId: string,\n): Promise<ReactiveCompactResult | null> {\n if (messages.length < 2) return null;\n\n try {\n const compacted = await compactConversation(\n provider,\n model,\n messages,\n storage,\n sessionId,\n { stripBinaryContent: true },\n );\n return { messages: compacted, strategy: \"compacted\" };\n } catch (err) {\n console.warn(\"[reactive-compact] compaction failed, falling back to head truncation:\", err);\n // Compaction failed — fall back to head truncation\n const targetTokens = getEffectiveContextWindow(model);\n const truncated = truncateHeadForPTLRetry(messages, targetTokens);\n if (truncated.length === messages.length) return null;\n return { messages: truncated, strategy: \"truncated\" };\n }\n}\n","import type { FileState, FileStateCacheConfig } from \"./types.js\";\nimport { normalize } from \"node:path\";\n\nconst DEFAULT_MAX_ENTRIES = 100;\nconst DEFAULT_MAX_BYTES = 25 * 1024 * 1024; // 25 MB\n\n/**\n * LRU cache tracking which files the model has read and at what mtime.\n *\n * Used by ReadFile to record reads and by EditFile/WriteFile to enforce\n * \"read-before-edit\" — the model cannot edit a file it hasn't seen,\n * preventing hallucinated edits on unseen content.\n */\nexport class FileStateCache {\n private entries: Map<string, FileState> = new Map();\n private maxEntries: number;\n private maxBytes: number;\n private currentBytes = 0;\n\n constructor(config?: FileStateCacheConfig) {\n this.maxEntries = config?.maxEntries ?? DEFAULT_MAX_ENTRIES;\n this.maxBytes = config?.maxBytes ?? DEFAULT_MAX_BYTES;\n }\n\n private key(path: string): string {\n return normalize(path);\n }\n\n private byteSize(state: FileState): number {\n return Math.max(1, Buffer.byteLength(state.content, \"utf8\"));\n }\n\n set(path: string, state: FileState): void {\n const k = this.key(path);\n const existing = this.entries.get(k);\n if (existing) {\n this.currentBytes -= this.byteSize(existing);\n this.entries.delete(k);\n }\n\n const size = this.byteSize(state);\n\n // Evict LRU entries until we're under both caps.\n // Map iteration order = insertion order, so first entries are oldest.\n while (\n (this.entries.size >= this.maxEntries || this.currentBytes + size > this.maxBytes) &&\n this.entries.size > 0\n ) {\n const oldest = this.entries.keys().next().value!;\n const oldState = this.entries.get(oldest)!;\n this.currentBytes -= this.byteSize(oldState);\n this.entries.delete(oldest);\n }\n\n this.entries.set(k, state);\n this.currentBytes += size;\n }\n\n get(path: string): FileState | undefined {\n const k = this.key(path);\n const state = this.entries.get(k);\n if (!state) return undefined;\n\n // Touch: move to end of insertion order (most recently used)\n this.entries.delete(k);\n this.entries.set(k, state);\n return state;\n }\n\n has(path: string): boolean {\n return this.entries.has(this.key(path));\n }\n\n delete(path: string): void {\n const k = this.key(path);\n const existing = this.entries.get(k);\n if (existing) {\n this.currentBytes -= this.byteSize(existing);\n this.entries.delete(k);\n }\n }\n\n get size(): number {\n return this.entries.size;\n }\n\n get totalBytes(): number {\n return this.currentBytes;\n }\n\n clear(): void {\n this.entries.clear();\n this.currentBytes = 0;\n }\n}\n","import type { SkillDefinition } from \"./types.js\";\n\n/**\n * Check which skills should be activated based on file paths the agent touched.\n * Skills with `globs` are conditional -- they only activate when a matching file is touched.\n * Skills without `globs` are always active.\n *\n * Returns the names of newly-activated conditional skills.\n */\nexport function activateSkillsForPaths(\n allSkills: SkillDefinition[],\n filePaths: string[],\n cwd: string,\n alreadyActivated: Set<string>,\n): string[] {\n const activated: string[] = [];\n\n for (const skill of allSkills) {\n if (!skill.globs || skill.globs.length === 0) continue;\n if (alreadyActivated.has(skill.name)) continue;\n\n for (const filePath of filePaths) {\n const relative = filePath.startsWith(cwd)\n ? filePath.slice(cwd.endsWith(\"/\") ? cwd.length : cwd.length + 1)\n : filePath;\n\n if (matchesAnyGlob(relative, skill.globs)) {\n alreadyActivated.add(skill.name);\n activated.push(skill.name);\n break;\n }\n }\n }\n\n return activated;\n}\n\n/**\n * Get all currently active skills: unconditional ones + activated conditional ones.\n */\nexport function getActiveSkills(\n allSkills: SkillDefinition[],\n activatedNames: Set<string>,\n): SkillDefinition[] {\n return allSkills.filter((skill) => {\n if (!skill.globs || skill.globs.length === 0) return true;\n return activatedNames.has(skill.name);\n });\n}\n\n/**\n * Simple glob matching. Supports *, **, and ? wildcards.\n * This is intentionally minimal -- covers the common SKILL.md patterns like\n * \"*.ts\", \"src/**\", \"**\\/*.test.ts\" without pulling in a dependency.\n */\nfunction matchesAnyGlob(path: string, patterns: string[]): boolean {\n return patterns.some((pattern) => globMatch(pattern, path));\n}\n\nfunction globMatch(pattern: string, str: string): boolean {\n const regex = globToRegex(pattern);\n return regex.test(str);\n}\n\nfunction globToRegex(glob: string): RegExp {\n let result = \"\";\n let i = 0;\n\n while (i < glob.length) {\n const ch = glob[i];\n\n if (ch === \"*\") {\n if (glob[i + 1] === \"*\") {\n // ** matches any path segment(s)\n if (glob[i + 2] === \"/\") {\n result += \"(?:.*/)?\";\n i += 3;\n } else {\n result += \".*\";\n i += 2;\n }\n } else {\n // * matches anything except /\n result += \"[^/]*\";\n i++;\n }\n } else if (ch === \"?\") {\n result += \"[^/]\";\n i++;\n } else if (ch === \"{\") {\n // Brace expansion: {a,b,c}\n const close = glob.indexOf(\"}\", i);\n if (close !== -1) {\n const alternatives = glob.slice(i + 1, close).split(\",\");\n result += `(?:${alternatives.map(escapeRegex).join(\"|\")})`;\n i = close + 1;\n } else {\n result += escapeRegex(ch);\n i++;\n }\n } else {\n result += escapeRegex(ch);\n i++;\n }\n }\n\n return new RegExp(`^${result}$`);\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","import type { Tool, ToolResult, ToolContext } from \"./types.js\";\nimport type { SkillDefinition } from \"../skills/types.js\";\n\n/**\n * Create a Skill tool that lets the model invoke skills by name.\n * Skill content is expanded inline with $ARGUMENTS substitution.\n */\nexport function createSkillTool(\n getSkills: () => SkillDefinition[],\n): Tool {\n return {\n name: \"Skill\",\n description:\n \"Invoke a skill by name with optional arguments. \" +\n \"Available skills are listed in the system prompt. \" +\n \"The skill's instructions will be expanded and returned for you to follow.\",\n parameters: {\n type: \"object\",\n properties: {\n skill_name: {\n type: \"string\",\n description: \"The name of the skill to invoke\",\n },\n arguments: {\n type: \"string\",\n description: \"Arguments to pass to the skill (replaces $ARGUMENTS in skill content)\",\n },\n },\n required: [\"skill_name\"],\n },\n async call(\n args: Record<string, unknown>,\n _ctx: ToolContext,\n ): Promise<ToolResult> {\n const skillName = args.skill_name as string;\n const skillArgs = (args.arguments as string) ?? \"\";\n const skills = getSkills();\n\n const skill = skills.find(\n (s) => s.name.toLowerCase() === skillName.toLowerCase(),\n );\n\n if (!skill) {\n const available = skills.map((s) => s.name).join(\", \");\n return {\n content: `Unknown skill: \"${skillName}\". Available skills: ${available || \"none\"}`,\n isError: true,\n };\n }\n\n let content = skill.content;\n content = content.replace(/\\$ARGUMENTS/g, skillArgs);\n\n const header = `# Skill: ${skill.name}`;\n const desc = skill.description ? `\\n${skill.description}\\n` : \"\";\n\n return {\n content: `${header}${desc}\\n${content}`,\n };\n },\n };\n}\n","import * as path from \"node:path\";\nimport * as fs from \"node:fs\";\nimport type {\n PermissionBehavior,\n PermissionContext,\n PermissionRule,\n} from \"./types.js\";\nimport { RULE_SOURCE_PRECEDENCE } from \"./types.js\";\n/**\n * Check whether a tool name matches a rule's `toolName` field.\n *\n * Supports:\n * - Exact match: `\"Bash\"` matches `\"Bash\"`\n * - MCP server-level wildcard: rule `\"mcp__myserver\"` matches any tool\n * on that server (e.g. `\"mcp__myserver__sometool\"`)\n */\nexport function toolMatchesRule(\n toolName: string,\n rule: PermissionRule,\n mcpInfo?: { serverName: string; toolName: string },\n): boolean {\n if (rule.toolName === toolName) return true;\n\n if (mcpInfo) {\n const serverPrefix = parseMcpServerPrefix(rule.toolName);\n if (serverPrefix && serverPrefix === mcpInfo.serverName) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Parse a server-level MCP rule like `\"mcp__myserver\"` (no tool suffix)\n * and return the server name, or `null` if it has a tool component or\n * doesn't match the MCP prefix pattern.\n */\nfunction parseMcpServerPrefix(ruleName: string): string | null {\n const parts = ruleName.split(\"__\");\n if (parts.length !== 2 || parts[0] !== \"mcp\" || !parts[1]) return null;\n return parts[1];\n}\n\n/**\n * Match a content string against a rule's `ruleContent`.\n *\n * Three match modes (following claude-code's bash/filesystem patterns):\n * - **exact**: `ruleContent === content`\n * - **prefix**: `ruleContent` ends with `:*` → prefix match\n * - **glob**: `ruleContent` contains `*` or `**` → simple glob match\n */\nexport function contentMatchesRule(\n content: string,\n ruleContent: string,\n): boolean {\n if (ruleContent.endsWith(\":*\")) {\n const prefix = ruleContent.slice(0, -2);\n return content === prefix || content.startsWith(prefix + \" \");\n }\n\n if (ruleContent.includes(\"*\")) {\n return matchSimpleGlob(ruleContent, content);\n }\n\n return ruleContent === content;\n}\n\n/**\n * Minimal glob matching for file-path rules.\n *\n * Supports `*` (any non-separator chars) and `**` (any chars including `/`).\n * Anchored: the entire string must match.\n */\nexport function matchSimpleGlob(pattern: string, value: string): boolean {\n let regex = \"^\";\n let i = 0;\n while (i < pattern.length) {\n if (pattern[i] === \"*\" && pattern[i + 1] === \"*\") {\n regex += \".*\";\n i += 2;\n if (pattern[i] === \"/\") i++;\n } else if (pattern[i] === \"*\") {\n regex += \"[^/]*\";\n i++;\n } else if (pattern[i] === \"?\") {\n regex += \"[^/]\";\n i++;\n } else {\n regex += escapeRegex(pattern[i]!);\n i++;\n }\n }\n regex += \"$\";\n\n return new RegExp(regex).test(value);\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Return all rules in `context` that match the given tool and behavior,\n * optionally filtered by content.\n */\nexport function getMatchingRules(\n context: PermissionContext,\n toolName: string,\n behavior: PermissionBehavior,\n content?: string,\n mcpInfo?: { serverName: string; toolName: string },\n): PermissionRule[] {\n const matched = context.rules.filter((rule) => {\n if (rule.behavior !== behavior) return false;\n if (!toolMatchesRule(toolName, rule, mcpInfo)) return false;\n\n if (rule.ruleContent !== undefined) {\n if (content === undefined) return false;\n return contentMatchesRule(content, rule.ruleContent);\n }\n\n // Whole-tool rule (no ruleContent) — matches when no content filter\n // is requested, or always matches if content IS provided (whole-tool\n // rules override content-specific ones, matching claude-code behavior).\n return true;\n });\n\n // Sort by source precedence so higher-precedence sources win first\n matched.sort((a, b) => {\n const aIdx = a.source ? RULE_SOURCE_PRECEDENCE.indexOf(a.source) : RULE_SOURCE_PRECEDENCE.length;\n const bIdx = b.source ? RULE_SOURCE_PRECEDENCE.indexOf(b.source) : RULE_SOURCE_PRECEDENCE.length;\n return aIdx - bIdx;\n });\n\n return matched;\n}\n\n/**\n * Reject paths that contain shell expansion syntax which could cause TOCTOU\n * issues — the path resolves differently in Node vs when the shell evaluates it.\n */\nexport function containsShellExpansion(p: string): boolean {\n if (p.includes(\"$\") || p.includes(\"%\") || p.startsWith(\"=\")) return true;\n if (/^~[^/]/.test(p)) return true; // ~user, ~+, ~- (bare ~/... is fine)\n if (p.startsWith(\"\\\\\\\\\")) return true; // UNC paths\n return false;\n}\n\n/**\n * Check whether a file path falls within any of the configured working directories.\n */\nexport function isPathInWorkingDirectories(\n filePath: string,\n workingDirectories: string[],\n): boolean {\n if (workingDirectories.length === 0) return false;\n if (containsShellExpansion(filePath)) return false;\n\n const normalized = normalizePath(filePath);\n return workingDirectories.some((dir) => {\n const normalizedDir = normalizePath(dir);\n return (\n normalized === normalizedDir ||\n normalized.startsWith(normalizedDir + \"/\")\n );\n });\n}\n\nfunction normalizePath(p: string): string {\n let result = path.resolve(p);\n try {\n result = fs.realpathSync(result);\n } catch {\n // Path doesn't exist yet — fall through to the resolved path\n }\n while (result.endsWith(\"/\") && result.length > 1) {\n result = result.slice(0, -1);\n }\n return result;\n}\n","import type { ToolContext } from \"../tools/types.js\";\n\n// --- Permission modes ---\n\nexport type PermissionMode =\n | \"default\"\n | \"plan\"\n | \"acceptEdits\"\n | \"auto\"\n | \"bypassPermissions\"\n | \"dontAsk\";\n\n// --- Rule behavior ---\n\nexport type PermissionBehavior = \"allow\" | \"deny\" | \"ask\";\n\n// --- Rule source provenance ---\n\nexport type PermissionRuleSource =\n | \"user\"\n | \"project\"\n | \"session\"\n | \"policy\";\n\n/** Precedence order: policy > project > user > session. */\nexport const RULE_SOURCE_PRECEDENCE: PermissionRuleSource[] = [\n \"policy\",\n \"project\",\n \"user\",\n \"session\",\n];\n\n// --- Rules ---\n\nexport interface PermissionRule {\n toolName: string;\n ruleContent?: string;\n behavior: PermissionBehavior;\n /** Where this rule came from. Higher-precedence sources override lower ones. */\n source?: PermissionRuleSource;\n}\n\n// --- Permission updates ---\n\nexport type PermissionUpdate =\n | { type: \"addRules\"; rules: PermissionRule[] }\n | { type: \"removeRules\"; toolName: string; behavior?: PermissionBehavior }\n | { type: \"setMode\"; mode: PermissionMode }\n | { type: \"addDirectories\"; directories: string[] }\n | { type: \"removeDirectories\"; directories: string[] };\n\n// --- Decision result types ---\n\nexport interface PermissionAllowResult<\n Input extends Record<string, unknown> = Record<string, unknown>,\n> {\n behavior: \"allow\";\n updatedInput?: Input;\n reason?: string;\n}\n\nexport interface PermissionDenyResult {\n behavior: \"deny\";\n message: string;\n reason?: string;\n}\n\nexport interface PermissionAskResult {\n behavior: \"ask\";\n message: string;\n reason?: string;\n suggestions?: PermissionRule[];\n}\n\nexport interface PermissionPassthroughResult {\n behavior: \"passthrough\";\n message: string;\n reason?: string;\n suggestions?: PermissionRule[];\n}\n\n/**\n * What `Tool.checkPermissions` returns. Includes `passthrough` for tools that\n * have no opinion and want the global pipeline to decide.\n */\nexport type PermissionResult<\n Input extends Record<string, unknown> = Record<string, unknown>,\n> =\n | PermissionAllowResult<Input>\n | PermissionDenyResult\n | PermissionAskResult\n | PermissionPassthroughResult;\n\n/**\n * Final decision after the pipeline resolves. No `passthrough` — always\n * one of allow / deny / ask.\n */\nexport type PermissionDecision<\n Input extends Record<string, unknown> = Record<string, unknown>,\n> =\n | PermissionAllowResult<Input>\n | PermissionDenyResult\n | PermissionAskResult;\n\n// --- Handler callback types ---\n\nexport interface PermissionRequest {\n toolName: string;\n input: Record<string, unknown>;\n message: string;\n suggestions?: PermissionRule[];\n isReadOnly: boolean;\n isDestructive: boolean;\n}\n\nexport interface PermissionResponse {\n allow: boolean;\n updatedInput?: Record<string, unknown>;\n feedback?: string;\n addRules?: PermissionRule[];\n}\n\nexport type PermissionHandler = (\n request: PermissionRequest,\n) => Promise<PermissionResponse>;\n\n// --- Configuration ---\n\nexport interface AutoModeConfig {\n /** Custom system prompt for the classifier. When omitted, uses a default. */\n classifierPrompt?: string;\n /** Model to use for classification. When omitted, uses the thread's model. */\n classifierModel?: string;\n}\n\nexport interface DenialTrackingConfig {\n /** Max consecutive denials before fallback (default: 3). */\n maxConsecutive?: number;\n /** Max total denials before fallback (default: 20). */\n maxTotal?: number;\n}\n\nexport interface PermissionConfig {\n mode?: PermissionMode;\n rules?: PermissionRule[];\n handler?: PermissionHandler;\n workingDirectories?: string[];\n /** Called when a permission update is applied (for host-side persistence). */\n onPermissionUpdate?: (update: PermissionUpdate) => void;\n /** Configuration for auto mode classifier. */\n autoMode?: AutoModeConfig;\n /** Configuration for denial tracking limits. */\n denialTracking?: DenialTrackingConfig;\n}\n\nexport interface PermissionContext {\n mode: PermissionMode;\n rules: PermissionRule[];\n workingDirectories: string[];\n}\n\n// --- Tool permission extension ---\n\n/**\n * Optional permission metadata a `Tool` can provide.\n * Kept as a separate interface so it can be imported without circular deps.\n */\nexport interface ToolPermissionMethods {\n isReadOnly?: boolean | ((args: Record<string, unknown>) => boolean);\n isDestructive?: boolean | ((args: Record<string, unknown>) => boolean);\n checkPermissions?: (\n args: Record<string, unknown>,\n ctx: ToolContext,\n ) => Promise<PermissionResult> | PermissionResult;\n}\n","import type { AIProvider, ChatParams } from \"../providers/types.js\";\nimport type { ChatMessage, ContentPart } from \"../session/types.js\";\nimport { contentToString } from \"../utils/content.js\";\n\nexport interface ClassifierResult {\n shouldBlock: boolean;\n reason: string;\n}\n\nconst DEFAULT_CLASSIFIER_PROMPT = `You are a security classifier for an AI coding agent. \nYour job is to determine whether a tool call should be automatically approved or blocked.\n\nAutomatically APPROVE tool calls that:\n- Read files within the project directory\n- Write/edit files within the project directory \n- Run common development commands (build, test, lint, format, git status/diff/log)\n- Search for files or code patterns\n- Create or update task items\n\nAutomatically BLOCK tool calls that:\n- Execute potentially destructive commands (rm -rf, drop database, force push)\n- Access files outside the project directory\n- Make network requests to unknown hosts\n- Run commands that could affect the system (install packages globally, modify system files)\n- Access secrets, credentials, or environment variables\n\nRespond with a JSON object: {\"shouldBlock\": boolean, \"reason\": \"brief explanation\"}`;\n\n/**\n * Run a side-query to classify whether a tool call should be auto-approved.\n */\nexport async function classifyPermission(\n toolName: string,\n args: Record<string, unknown>,\n recentMessages: ChatMessage[],\n provider: AIProvider,\n opts?: {\n classifierPrompt?: string;\n classifierModel?: string;\n model?: string;\n signal?: AbortSignal;\n },\n): Promise<ClassifierResult> {\n const model = opts?.classifierModel ?? opts?.model ?? \"gpt-4o-mini\";\n\n const contextWindow = recentMessages.slice(-6);\n const contextText = contextWindow\n .map((m) => `${m.role}: ${contentToString(m.content as string | ContentPart[]).slice(0, 200)}`)\n .join(\"\\n\");\n\n const userPrompt =\n `Tool: ${toolName}\\n` +\n `Arguments: ${JSON.stringify(args, null, 2).slice(0, 1000)}\\n\\n` +\n `Recent conversation context:\\n${contextText}`;\n\n const params: ChatParams = {\n model,\n system: opts?.classifierPrompt ?? DEFAULT_CLASSIFIER_PROMPT,\n messages: [{ role: \"user\", content: userPrompt }],\n max_tokens: 256,\n temperature: 0,\n outputFormat: {\n type: \"json_schema\",\n schema: {\n type: \"object\",\n properties: {\n shouldBlock: { type: \"boolean\" },\n reason: { type: \"string\" },\n },\n required: [\"shouldBlock\", \"reason\"],\n additionalProperties: false,\n },\n name: \"classifier_result\",\n strict: true,\n },\n };\n\n try {\n let text = \"\";\n for await (const chunk of provider.chat(params)) {\n if (opts?.signal?.aborted) break;\n for (const choice of chunk.choices) {\n if (choice.delta.content) {\n text += choice.delta.content;\n }\n }\n }\n\n const parsed = JSON.parse(text) as ClassifierResult;\n return {\n shouldBlock: parsed.shouldBlock ?? false,\n reason: parsed.reason ?? \"unknown\",\n };\n } catch {\n // On classifier failure, default to blocking (fail closed)\n return { shouldBlock: true, reason: \"Classifier failed; defaulting to block.\" };\n }\n}\n","import type { Tool, ToolContext } from \"../tools/types.js\";\nimport type { AIProvider } from \"../providers/types.js\";\nimport type { ChatMessage } from \"../session/types.js\";\nimport type {\n PermissionContext,\n PermissionDecision,\n PermissionResult,\n AutoModeConfig,\n} from \"./types.js\";\nimport { getMatchingRules, isPathInWorkingDirectories } from \"./rules.js\";\nimport { resolveToolFlag } from \"../tools/registry.js\";\nimport { classifyPermission } from \"./classifier.js\";\n\n/**\n * Resolve the permission decision for a tool invocation.\n *\n * Pipeline mirrors claude-code's `hasPermissionsToUseToolInner`:\n * 1. Deny rules for the whole tool\n * 2. Ask rules for the whole tool\n * 3. Tool's own `checkPermissions` (if defined)\n * 4. Mode-based bypass / enforcement\n * 5. Content-specific allow rules\n * 6. Fallback: passthrough → ask\n */\nexport interface ResolvePermissionOptions {\n provider?: AIProvider;\n model?: string;\n recentMessages?: ChatMessage[];\n autoModeConfig?: AutoModeConfig;\n signal?: AbortSignal;\n}\n\nexport async function resolvePermission(\n tool: Tool,\n input: Record<string, unknown>,\n ctx: ToolContext,\n permCtx: PermissionContext,\n opts?: ResolvePermissionOptions,\n): Promise<PermissionDecision> {\n const toolName = tool.name;\n const contentHint = extractContentHint(tool, input);\n\n // 1. Deny rules for whole tool (no ruleContent)\n const wholeDenyRules = getMatchingRules(\n permCtx,\n toolName,\n \"deny\",\n undefined,\n tool.mcpInfo,\n );\n if (wholeDenyRules.length > 0) {\n return {\n behavior: \"deny\",\n message: `Tool \"${toolName}\" is denied by rule.`,\n reason: \"rule\",\n };\n }\n\n // 1b. Content-specific deny rules\n if (contentHint !== undefined) {\n const contentDenyRules = getMatchingRules(\n permCtx,\n toolName,\n \"deny\",\n contentHint,\n tool.mcpInfo,\n );\n if (contentDenyRules.length > 0) {\n return {\n behavior: \"deny\",\n message: `Tool \"${toolName}\" with \"${contentHint}\" is denied by rule.`,\n reason: \"rule\",\n };\n }\n }\n\n // 2. Ask rules for whole tool\n const wholeAskRules = getMatchingRules(\n permCtx,\n toolName,\n \"ask\",\n undefined,\n tool.mcpInfo,\n );\n if (wholeAskRules.length > 0) {\n return {\n behavior: \"ask\",\n message: `Tool \"${toolName}\" requires approval.`,\n reason: \"rule\",\n };\n }\n\n // 2b. Working directory enforcement for file paths\n if (permCtx.workingDirectories.length > 0) {\n const filePath =\n typeof input.file_path === \"string\" ? input.file_path\n : typeof input.path === \"string\" ? input.path\n : undefined;\n if (filePath && !isPathInWorkingDirectories(filePath, permCtx.workingDirectories)) {\n return {\n behavior: \"deny\",\n message: `Path \"${filePath}\" is outside configured working directories.`,\n reason: \"workingDirectory\",\n };\n }\n }\n\n // 3. Tool's own checkPermissions\n let toolResult: PermissionResult | undefined;\n if (tool.checkPermissions) {\n if (opts?.signal?.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n try {\n toolResult = await tool.checkPermissions(input, ctx);\n } catch (err) {\n if (err instanceof DOMException && err.name === \"AbortError\") throw err;\n if (err instanceof Error && err.name === \"AbortError\") throw err;\n throw err;\n }\n\n if (toolResult.behavior === \"deny\") {\n return {\n behavior: \"deny\",\n message: toolResult.message,\n reason: toolResult.reason ?? \"tool\",\n };\n }\n if (toolResult.behavior === \"ask\") {\n const isSafetyCheck = toolResult.reason === \"safetyCheck\";\n const isInteractive = tool.requiresUserInteraction === true;\n const isContentSpecificRule = toolResult.reason === \"rule\";\n\n if (isSafetyCheck || isInteractive || isContentSpecificRule || permCtx.mode !== \"bypassPermissions\") {\n return {\n behavior: \"ask\",\n message: toolResult.message,\n reason: toolResult.reason ?? \"tool\",\n suggestions: toolResult.suggestions,\n };\n }\n }\n if (toolResult.behavior === \"allow\") {\n return {\n behavior: \"allow\",\n updatedInput: toolResult.updatedInput,\n reason: toolResult.reason ?? \"tool\",\n };\n }\n }\n\n // Prefer any sanitized input the tool produced (e.g. resolved paths),\n // falling back to the raw input when checkPermissions was not defined\n // or returned a variant without updatedInput.\n const effectiveInput =\n (toolResult?.behavior === \"allow\" && toolResult.updatedInput)\n ? toolResult.updatedInput\n : input;\n\n // 3b. Interactive tool guard (bypass-immune)\n if (tool.requiresUserInteraction && permCtx.mode === \"bypassPermissions\") {\n return {\n behavior: \"ask\",\n message: `Tool \"${toolName}\" requires user interaction.`,\n reason: \"interaction\",\n };\n }\n\n // 4. Mode-based bypass / enforcement\n if (permCtx.mode === \"bypassPermissions\") {\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"mode\",\n };\n }\n\n const isReadOnly = resolveToolFlag(tool.isReadOnly, input);\n const isDestructive = resolveToolFlag(tool.isDestructive, input);\n\n if (permCtx.mode === \"plan\" && !isReadOnly) {\n return {\n behavior: \"deny\",\n message: `Tool \"${toolName}\" is not allowed in plan mode (read-only).`,\n reason: \"mode\",\n };\n }\n\n if (permCtx.mode === \"acceptEdits\") {\n if (isDestructive) {\n return {\n behavior: \"ask\",\n message: `Tool \"${toolName}\" is destructive and requires approval in acceptEdits mode.`,\n reason: \"mode\",\n };\n }\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"mode\",\n };\n }\n\n // Auto mode: use classifier to decide\n if (permCtx.mode === \"auto\" && opts?.autoModeConfig) {\n if (!opts.provider) {\n return {\n behavior: \"ask\",\n message: `Auto-mode requires an AI provider for classification. Falling back to ask.`,\n reason: \"classifier\",\n };\n }\n\n const result = await classifyPermission(\n toolName,\n input,\n opts.recentMessages ?? [],\n opts.provider,\n {\n classifierPrompt: opts.autoModeConfig.classifierPrompt,\n classifierModel: opts.autoModeConfig.classifierModel,\n model: opts.model,\n signal: opts.signal,\n },\n );\n\n if (result.shouldBlock) {\n return {\n behavior: \"ask\",\n message: `Auto-mode classifier flagged this call: ${result.reason}`,\n reason: \"classifier\",\n };\n }\n\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"classifier\",\n };\n }\n\n // Read-only tools are auto-allowed in any mode (except when an ask/deny\n // rule explicitly overrode them in steps 1-2 above).\n if (isReadOnly) {\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"readOnly\",\n };\n }\n\n // 5. Content-specific allow rules\n if (contentHint !== undefined) {\n const contentAllowRules = getMatchingRules(\n permCtx,\n toolName,\n \"allow\",\n contentHint,\n tool.mcpInfo,\n );\n if (contentAllowRules.length > 0) {\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"rule\",\n };\n }\n }\n\n // Whole-tool allow rules\n const wholeAllowRules = getMatchingRules(\n permCtx,\n toolName,\n \"allow\",\n undefined,\n tool.mcpInfo,\n );\n if (wholeAllowRules.length > 0) {\n return {\n behavior: \"allow\",\n updatedInput: effectiveInput,\n reason: \"rule\",\n };\n }\n\n // dontAsk mode: deny anything that would prompt (reads already allowed above)\n if (permCtx.mode === \"dontAsk\") {\n return {\n behavior: \"deny\",\n message: `Tool \"${toolName}\" requires approval, but mode is \"dontAsk\".`,\n reason: \"mode\",\n };\n }\n\n // 6. Fallback: passthrough → ask\n const message =\n toolResult?.behavior === \"passthrough\"\n ? toolResult.message\n : `Tool \"${toolName}\" requires approval.`;\n const suggestions =\n toolResult?.behavior === \"passthrough\"\n ? toolResult.suggestions\n : undefined;\n\n return {\n behavior: \"ask\",\n message,\n reason: \"default\",\n suggestions,\n };\n}\n\n/**\n * Extract a content string from tool input for rule matching.\n *\n * For file tools this is the `file_path`; for bash it's the `command`.\n * Returns `undefined` if no meaningful content is available.\n */\nfunction extractContentHint(\n tool: Tool,\n input: Record<string, unknown>,\n): string | undefined {\n if (typeof input.file_path === \"string\") return input.file_path;\n if (typeof input.command === \"string\") return input.command;\n if (typeof input.path === \"string\") return input.path;\n return undefined;\n}\n","export interface DenialLimits {\n maxConsecutive: number;\n maxTotal: number;\n}\n\nexport interface DenialState {\n consecutiveDenials: number;\n totalDenials: number;\n}\n\nconst DEFAULT_LIMITS: DenialLimits = {\n maxConsecutive: 3,\n maxTotal: 20,\n};\n\n/**\n * Tracks permission denials and determines when limits are exceeded.\n * When limits are hit, the system should fall back to prompting or abort.\n */\nexport class DenialTracker {\n private state: DenialState = { consecutiveDenials: 0, totalDenials: 0 };\n private limits: DenialLimits;\n\n constructor(limits?: Partial<DenialLimits>) {\n this.limits = { ...DEFAULT_LIMITS, ...limits };\n }\n\n recordDenial(): void {\n this.state.consecutiveDenials++;\n this.state.totalDenials++;\n }\n\n recordSuccess(): void {\n this.state.consecutiveDenials = 0;\n }\n\n shouldFallback(): boolean {\n return (\n this.state.consecutiveDenials >= this.limits.maxConsecutive ||\n this.state.totalDenials >= this.limits.maxTotal\n );\n }\n\n getState(): Readonly<DenialState> {\n return { ...this.state };\n }\n\n reset(): void {\n this.state.consecutiveDenials = 0;\n this.state.totalDenials = 0;\n }\n}\n","import type { RetryConfig } from \"./types.js\";\n\n/**\n * Provider-agnostic error classification for retry decisions.\n * Extracts status codes and retry hints from common SDK error shapes\n * without depending on any specific provider's types.\n */\nexport interface ClassifiedError {\n originalError: unknown;\n message: string;\n status?: number;\n retryAfter?: string;\n isOverloaded: boolean;\n isContextOverflow: boolean;\n contextOverflowData?: {\n inputTokens: number;\n maxTokens: number;\n contextLimit: number;\n };\n}\n\n/**\n * Classify an unknown error into retry-relevant metadata.\n * Works across OpenAI, Anthropic, and Gemini SDK error shapes by\n * duck-typing common properties (`.status`, `.headers`, `.message`).\n */\nexport function classifyError(error: unknown): ClassifiedError {\n let msg: string;\n if (error instanceof Error) {\n msg = error.message;\n } else if (error && typeof error === \"object\" && typeof (error as { message?: unknown }).message === \"string\") {\n msg = (error as { message: string }).message;\n } else {\n msg = String(error);\n }\n\n const status = extractStatus(error);\n const retryAfter = extractRetryAfter(error);\n\n const isOverloaded =\n status === 529 ||\n msg.includes('\"type\":\"overloaded_error\"') ||\n msg.toLowerCase().includes(\"overloaded\");\n\n const contextOverflowData = parseContextOverflow(msg, status);\n\n return {\n originalError: error,\n message: msg,\n status,\n retryAfter,\n isOverloaded,\n isContextOverflow: contextOverflowData !== undefined,\n contextOverflowData,\n };\n}\n\nexport function isRetryable(\n classified: ClassifiedError,\n config: RetryConfig,\n): boolean {\n if (classified.isContextOverflow) return true;\n\n if (classified.status !== undefined) {\n const retryableStatuses = config.retryableStatuses ?? [408, 409, 429, 500, 502, 503, 529];\n if (retryableStatuses.includes(classified.status)) return true;\n }\n\n if (isConnectionError(classified.originalError)) return true;\n\n return false;\n}\n\nfunction extractStatus(error: unknown): number | undefined {\n if (error && typeof error === \"object\") {\n const e = error as Record<string, unknown>;\n if (typeof e.status === \"number\") return e.status;\n if (typeof e.statusCode === \"number\") return e.statusCode;\n }\n return undefined;\n}\n\nfunction extractRetryAfter(error: unknown): string | undefined {\n if (error && typeof error === \"object\") {\n const e = error as Record<string, unknown>;\n\n // Direct property (ChatStreamError)\n if (typeof e.retryAfter === \"string\") return e.retryAfter;\n\n // Headers object (Anthropic/OpenAI SDK errors)\n if (e.headers && typeof e.headers === \"object\") {\n const headers = e.headers as Record<string, unknown>;\n if (typeof headers[\"retry-after\"] === \"string\") return headers[\"retry-after\"];\n if (typeof (headers as { get?: (k: string) => string | null }).get === \"function\") {\n const val = (headers as { get: (k: string) => string | null }).get(\"retry-after\");\n if (val) return val;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Parse context overflow errors from any provider.\n * Anthropic: \"input length and `max_tokens` exceed context limit: 188059 + 20000 > 200000\"\n * OpenAI: \"This model's maximum context length is 128000 tokens. However, your messages resulted in 130000 tokens.\"\n */\nfunction parseContextOverflow(\n message: string,\n status?: number,\n): ClassifiedError[\"contextOverflowData\"] | undefined {\n if (status !== 400 && status !== 413) return undefined;\n\n // Anthropic format\n const anthropicRegex =\n /input length and `max_tokens` exceed context limit: (\\d+) \\+ (\\d+) > (\\d+)/;\n const anthropicMatch = message.match(anthropicRegex);\n if (anthropicMatch && anthropicMatch[1] && anthropicMatch[2] && anthropicMatch[3]) {\n return {\n inputTokens: parseInt(anthropicMatch[1], 10),\n maxTokens: parseInt(anthropicMatch[2], 10),\n contextLimit: parseInt(anthropicMatch[3], 10),\n };\n }\n\n // OpenAI format\n const openaiRegex =\n /maximum context length is (\\d+) tokens.*?resulted in (\\d+) tokens/;\n const openaiMatch = message.match(openaiRegex);\n if (openaiMatch && openaiMatch[1] && openaiMatch[2]) {\n const contextLimit = parseInt(openaiMatch[1], 10);\n const totalTokens = parseInt(openaiMatch[2], 10);\n return {\n inputTokens: totalTokens,\n maxTokens: totalTokens - contextLimit,\n contextLimit,\n };\n }\n\n return undefined;\n}\n\nfunction isConnectionError(error: unknown): boolean {\n if (error && typeof error === \"object\") {\n const e = error as Record<string, unknown>;\n const name = typeof e.name === \"string\" ? e.name : \"\";\n if (name === \"APIConnectionError\" || name === \"APIConnectionTimeoutError\") return true;\n const code = typeof e.code === \"string\" ? e.code : \"\";\n if (code === \"ECONNRESET\" || code === \"EPIPE\" || code === \"ECONNREFUSED\" || code === \"ETIMEDOUT\") return true;\n }\n return false;\n}\n","const DEFAULT_BASE_DELAY_MS = 500;\n\n/**\n * Compute retry delay with exponential backoff and jitter.\n * If a Retry-After header value is provided (seconds), it takes precedence.\n * Ported from claude-code's getRetryDelay with the same formula.\n */\nexport function getRetryDelay(\n attempt: number,\n retryAfterHeader?: string | null,\n maxDelayMs: number = 32000,\n): number {\n if (retryAfterHeader) {\n const seconds = parseInt(retryAfterHeader, 10);\n if (!isNaN(seconds)) {\n const MAX_RETRY_AFTER_MS = 6 * 60 * 60 * 1000;\n return Math.min(seconds * 1000, MAX_RETRY_AFTER_MS);\n }\n }\n\n const baseDelay = Math.min(\n DEFAULT_BASE_DELAY_MS * Math.pow(2, attempt - 1),\n maxDelayMs,\n );\n const jitter = Math.random() * 0.25 * baseDelay;\n return baseDelay + jitter;\n}\n\n/**\n * Sleep that respects an AbortSignal.\n */\nexport function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n return;\n }\n\n const onAbort = () => {\n clearTimeout(timer);\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n}\n","import type { ChatStreamChunk } from \"../providers/types.js\";\nimport type { StreamEvent } from \"../session/types.js\";\nimport type { RetryEngineOptions, RetryContext } from \"./types.js\";\nimport { classifyError, isRetryable } from \"./classify.js\";\nimport { getRetryDelay, sleep } from \"./backoff.js\";\n\nconst FLOOR_OUTPUT_TOKENS = 3000;\n\nexport class CannotRetryError extends Error {\n constructor(\n public readonly originalError: unknown,\n public readonly retryContext: RetryContext,\n ) {\n super(originalError instanceof Error ? originalError.message : String(originalError));\n this.name = \"CannotRetryError\";\n }\n}\n\nexport class FallbackTriggeredError extends Error {\n constructor(\n public readonly originalModel: string,\n public readonly fallbackModel: string,\n ) {\n super(`Model fallback triggered: ${originalModel} -> ${fallbackModel}`);\n this.name = \"FallbackTriggeredError\";\n }\n}\n\n/**\n * Retry engine that wraps a stream-creating operation.\n * Yields retry_attempt events while waiting, then returns the stream on success.\n *\n * The operation receives a RetryContext that may include a maxTokensOverride\n * (after context overflow) or a different model (after fallback).\n */\nexport async function* withRetry(\n operation: (ctx: RetryContext) => AsyncIterable<ChatStreamChunk>,\n options: RetryEngineOptions,\n): AsyncGenerator<StreamEvent, AsyncIterable<ChatStreamChunk>> {\n const maxRetries = options.maxRetries ?? 10;\n const baseDelayMs = options.baseDelayMs ?? 500;\n const maxDelayMs = options.maxDelayMs ?? 32000;\n const maxConsecutiveOverloaded = options.maxConsecutiveOverloaded ?? 3;\n\n const retryContext: RetryContext = {\n attempt: 0,\n model: options.model,\n };\n\n let consecutiveOverloaded = 0;\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {\n if (options.signal?.aborted) {\n throw new DOMException(\"Aborted\", \"AbortError\");\n }\n\n retryContext.attempt = attempt;\n\n try {\n const stream = operation(retryContext);\n\n // Try to get the first chunk to detect immediate errors.\n // If the stream itself throws, we catch it in the retry loop.\n const iterator = toAsyncIterator(stream);\n const first = await iterator.next();\n\n if (first.done) {\n return emptyStream();\n }\n\n return prependChunk(first.value, iterator);\n } catch (error) {\n lastError = error;\n\n const classified = classifyError(error);\n\n // Context overflow: adjust max_tokens and retry\n if (classified.isContextOverflow && classified.contextOverflowData) {\n const { inputTokens, contextLimit } = classified.contextOverflowData;\n const safetyBuffer = 1000;\n const available = Math.max(0, contextLimit - inputTokens - safetyBuffer);\n\n if (available < FLOOR_OUTPUT_TOKENS) {\n throw new CannotRetryError(error, retryContext);\n }\n\n const minRequired = (options.thinkingBudget ?? 0) + 1;\n retryContext.maxTokensOverride = Math.max(\n FLOOR_OUTPUT_TOKENS,\n available,\n minRequired,\n );\n\n continue;\n }\n\n // Track consecutive overloaded for fallback\n if (classified.isOverloaded) {\n consecutiveOverloaded++;\n if (\n consecutiveOverloaded >= maxConsecutiveOverloaded &&\n options.fallbackModel\n ) {\n const previousModel = retryContext.model;\n retryContext.model = options.fallbackModel;\n consecutiveOverloaded = 0;\n\n yield {\n type: \"retry_attempt\",\n attempt,\n maxRetries,\n delayMs: 0,\n error: new Error(\n `Model fallback: ${previousModel} → ${options.fallbackModel} after ${maxConsecutiveOverloaded} consecutive overloaded errors`,\n ),\n };\n }\n } else {\n consecutiveOverloaded = 0;\n }\n\n if (!isRetryable(classified, options)) {\n throw new CannotRetryError(error, retryContext);\n }\n\n if (attempt > maxRetries) {\n const exhaustedError = error instanceof Error ? error : new Error(String(error));\n yield {\n type: \"retry_exhausted\",\n attempts: attempt,\n error: exhaustedError,\n };\n throw new CannotRetryError(error, retryContext);\n }\n\n const delayMs = getRetryDelay(\n attempt,\n classified.retryAfter,\n maxDelayMs,\n );\n\n const retryError = error instanceof Error ? error : new Error(String(error));\n\n options.onRetry?.(attempt, retryError, delayMs);\n\n yield {\n type: \"retry_attempt\",\n attempt,\n maxRetries,\n delayMs,\n error: retryError,\n };\n\n await sleep(delayMs, options.signal);\n }\n }\n\n throw new CannotRetryError(lastError, retryContext);\n}\n\nasync function* emptyStream(): AsyncIterable<ChatStreamChunk> {\n // yields nothing\n}\n\nfunction toAsyncIterator<T>(\n iterable: AsyncIterable<T>,\n): AsyncIterator<T> {\n return iterable[Symbol.asyncIterator]();\n}\n\nasync function* prependChunk(\n first: ChatStreamChunk,\n rest: AsyncIterator<ChatStreamChunk>,\n): AsyncIterable<ChatStreamChunk> {\n yield first;\n let next = await rest.next();\n while (!next.done) {\n yield next.value;\n next = await rest.next();\n }\n}\n","import type { Tool, ToolResult, ToolContext } from \"./types.js\";\nimport type { JsonSchemaOutputFormat } from \"../providers/types.js\";\n\nconst STRUCTURED_OUTPUT_TOOL_NAME = \"StructuredOutput\";\n\n/**\n * Creates a synthetic tool whose input schema matches the user's desired\n * output schema. When the model calls this tool, the agent loop treats it\n * as the final structured response and terminates.\n *\n * This is the \"final_response\" pattern: the model reasons freely (using\n * tools), and signals completion by calling StructuredOutput with data\n * that conforms to the schema.\n */\nexport function createStructuredOutputTool(\n format: JsonSchemaOutputFormat,\n): Tool {\n return {\n name: STRUCTURED_OUTPUT_TOOL_NAME,\n description:\n \"Return your final structured answer. Call this tool ONCE when you \" +\n \"have gathered all necessary information and are ready to respond. \" +\n \"The input MUST conform to the required JSON schema.\",\n prompt: \"\",\n isReadOnly: true,\n isConcurrencySafe: true,\n parameters: {\n type: \"object\",\n properties: {\n data: {\n type: \"object\",\n description: \"The structured response data conforming to the schema.\",\n },\n },\n required: [\"data\"],\n },\n\n async call(\n args: Record<string, unknown>,\n _ctx: ToolContext,\n ): Promise<ToolResult> {\n return {\n content: JSON.stringify(args.data ?? args, null, 2),\n };\n },\n };\n}\n\nexport { STRUCTURED_OUTPUT_TOOL_NAME };\n","import type { AIProvider, ChatCompletionUsage, OutputFormat } from \"./providers/types.js\";\nimport type { VirtualFs } from \"./virtual/fs.js\";\nimport type { VirtualComputer } from \"./virtual/computer.js\";\nimport type {\n ChatMessage,\n AssistantMessage,\n ToolCallContent,\n ContentPart,\n StreamEvent,\n RunOptions,\n} from \"./session/types.js\";\nimport type { SkillDefinition } from \"./skills/types.js\";\nimport type { ContextFile } from \"./context/types.js\";\nimport { buildProjectContextSection } from \"./context/prompts.js\";\nimport { activateContextForPaths, filterActiveContextFiles } from \"./context/loader.js\";\nimport type { Tool, ToolContext, SubagentConfig, SubagentRun } from \"./tools/types.js\";\nimport { createToolSearchTool, TOOL_SEARCH_NAME } from \"./tools/tool-search.js\";\nimport type { TaskStore } from \"./tasks/store.js\";\nimport type { LspServerManager } from \"./lsp/manager.js\";\nimport type {\n PermissionConfig,\n PermissionContext,\n PermissionHandler,\n PermissionRequest,\n} from \"./permissions/types.js\";\nimport type { HookDefinition } from \"./hooks/types.js\";\nimport type { ThinkingConfig } from \"./thinking/types.js\";\nimport type { RetryConfig } from \"./retry/types.js\";\nimport type { CostTracker } from \"./cost/tracker.js\";\nimport type { Tracer, Span } from \"./tracing/types.js\";\nimport { SpanStatusCode } from \"./tracing/types.js\";\nimport { NoopTracer } from \"./tracing/noop.js\";\nimport type { MemoryConfig } from \"./memory/types.js\";\nimport { buildMemorySystemPromptSection } from \"./memory/prompts.js\";\nimport { extractMemories } from \"./memory/extraction.js\";\nimport type { FileCheckpointManager } from \"./checkpoint/manager.js\";\nimport { sortToolDefinitionsForCache } from \"./providers/cache.js\";\nimport { saveCacheSafeParams, createCacheSafeParams } from \"./providers/cache-safe-params.js\";\nimport { restoreSession } from \"./session/resume.js\";\nimport { generateMissingToolResults } from \"./session/recovery.js\";\nimport {\n runPreToolUseHooks,\n runPostToolUseHooks,\n runPostToolUseFailureHooks,\n runNotificationHooks,\n} from \"./hooks/runner.js\";\nimport { ToolRegistry, resolveToolFlag } from \"./tools/registry.js\";\nimport { runToolsBatched, type ToolCallExecResult } from \"./tools/orchestration.js\";\nimport {\n StreamingToolExecutor,\n type StreamingExecResult,\n} from \"./tools/streaming-executor.js\";\nimport { SessionStorage } from \"./session/storage.js\";\nimport { buildSystemPrompt } from \"./prompt/system.js\";\nimport { compactConversation } from \"./compact/compact.js\";\nimport {\n createAutoCompactConfig,\n shouldAutoCompact,\n canAutoCompact,\n recordAutoCompactSuccess,\n recordAutoCompactFailure,\n createAutoCompactTracking,\n type AutoCompactConfig,\n type AutoCompactTrackingState,\n} from \"./compact/auto-compact.js\";\nimport {\n microcompactMessages,\n type MicrocompactConfig,\n} from \"./compact/microcompact.js\";\nimport {\n enforceToolResultBudget,\n createBudgetState,\n type ToolResultBudgetConfig,\n type BudgetState,\n} from \"./compact/tool-result-budget.js\";\nimport {\n persistToolResult,\n enforceToolResultStorageBudget,\n reconstructContentReplacementState,\n applyPersistedReplacements,\n createContentReplacementState,\n type ToolResultStorageConfig,\n type ContentReplacementState,\n} from \"./compact/tool-result-storage.js\";\nimport {\n tryReactiveCompact,\n type ReactiveCompactConfig,\n} from \"./compact/reactive-compact.js\";\nimport type { SnipConfig } from \"./compact/history-snip.js\";\nimport { contentToString } from \"./utils/content.js\";\nimport { FileStateCache } from \"./file-state/cache.js\";\nimport type { FileStateCacheConfig } from \"./file-state/types.js\";\nimport { generateUUID } from \"./utils/uuid.js\";\nimport { activateSkillsForPaths, getActiveSkills } from \"./skills/activation.js\";\nimport { createSkillTool } from \"./tools/skill.js\";\nimport { resolvePermission, type ResolvePermissionOptions } from \"./permissions/pipeline.js\";\nimport { isPathInWorkingDirectories } from \"./permissions/rules.js\";\nimport { DenialTracker } from \"./permissions/denial-tracking.js\";\nimport { withRetry, CannotRetryError } from \"./retry/engine.js\";\nimport { classifyError } from \"./retry/classify.js\";\nimport {\n createStructuredOutputTool,\n STRUCTURED_OUTPUT_TOOL_NAME,\n} from \"./tools/structured-output.js\";\n\nconst FILE_TOOLS = new Set([\"ReadFile\", \"WriteFile\", \"EditFile\"]);\n\nexport interface ThreadOptions {\n sessionId?: string;\n resume?: boolean;\n cwd?: string;\n model?: string;\n /** Override the permission handler for this thread (takes precedence over AgentOptions). */\n permissionHandler?: PermissionHandler;\n /** Override the user input handler for this thread (takes precedence over AgentOptions). */\n userInputHandler?: (question: string) => Promise<string>;\n}\n\nexport interface ThreadConfig {\n provider: AIProvider;\n fs: VirtualFs;\n computer: VirtualComputer;\n sessionDir: string;\n skills?: SkillDefinition[];\n tools?: Tool[];\n systemPrompt?: string;\n model?: string;\n maxTokens?: number;\n autoCompact?: AutoCompactConfig;\n microcompact?: MicrocompactConfig;\n toolResultBudget?: ToolResultBudgetConfig;\n reactiveCompact?: ReactiveCompactConfig;\n permissions?: PermissionConfig;\n hooks?: HookDefinition[];\n spawnSubagent?: (config: SubagentConfig) => SubagentRun;\n streamingToolExecution?: boolean;\n userInputHandler?: (question: string) => Promise<string>;\n taskStore?: TaskStore;\n lspManager?: LspServerManager;\n thinking?: ThinkingConfig;\n retry?: RetryConfig;\n costTracker?: CostTracker;\n tracer?: Tracer;\n memory?: MemoryConfig;\n toolSearchEnabled?: boolean;\n checkpointManager?: FileCheckpointManager;\n /** File state cache config for read-before-edit enforcement. */\n fileStateCacheConfig?: FileStateCacheConfig;\n /** Disk-backed tool result storage config. */\n toolResultStorage?: ToolResultStorageConfig;\n /** History snip: enable middle-range removal from conversation history. */\n historySnip?: SnipConfig;\n /** Enable deterministic tool ordering and CacheSafeParams tracking for prompt caching. */\n promptCachingEnabled?: boolean;\n /** When true, signal skipCacheWrite to the provider (for subagent forks). */\n skipCacheWrite?: boolean;\n /** Set of MCP tool names for cache-stable sorting (built-in first, then MCP). */\n mcpToolNames?: ReadonlySet<string>;\n /** Loaded project context files (NOUMEN.md / CLAUDE.md) for system prompt injection. */\n projectContext?: ContextFile[];\n /** Default structured output format for all runs on this thread. */\n outputFormat?: OutputFormat;\n /** Default structured output mode for all runs on this thread. */\n structuredOutputMode?: \"alongside_tools\" | \"final_response\";\n}\n\nexport class Thread {\n readonly sessionId: string;\n\n private config: ThreadConfig;\n private storage: SessionStorage;\n private toolRegistry: ToolRegistry;\n private messages: ChatMessage[] = [];\n private loaded = false;\n private abortController: AbortController | null = null;\n private cwd: string;\n private model: string;\n private activatedSkills: Set<string> = new Set();\n private activatedContextRules: Set<string> = new Set();\n private permissionContext: PermissionContext | null = null;\n private permissionHandler: PermissionHandler | null = null;\n private hooks: HookDefinition[];\n private lastUsage: ChatCompletionUsage | undefined;\n private anchorMessageIndex: number | undefined;\n private prePlanMode: import(\"./permissions/types.js\").PermissionMode | null = null;\n private tracer: Tracer;\n private autoCompactTracking: AutoCompactTrackingState;\n private budgetState: BudgetState;\n private hasAttemptedReactiveCompact = false;\n private microcompactTokensFreed = 0;\n private resumeRequested = false;\n private fileStateCache: FileStateCache | null = null;\n private contentReplacementState: ContentReplacementState;\n private denialTracker: DenialTracker | null = null;\n\n constructor(config: ThreadConfig, opts?: ThreadOptions) {\n this.config = config;\n this.sessionId = opts?.sessionId ?? generateUUID();\n this.cwd = opts?.cwd ?? \"/\";\n this.model = opts?.model ?? config.model ?? \"gpt-5.4\";\n this.storage = new SessionStorage(config.fs, config.sessionDir);\n\n if (config.permissions) {\n this.permissionContext = {\n mode: config.permissions.mode ?? \"default\",\n rules: [...(config.permissions.rules ?? [])],\n workingDirectories: [...(config.permissions.workingDirectories ?? [])],\n };\n this.permissionHandler = config.permissions.handler ?? null;\n if (config.permissions.denialTracking) {\n this.denialTracker = new DenialTracker(config.permissions.denialTracking);\n }\n }\n\n const extraTools = [...(config.tools ?? [])];\n\n // Add the Skill tool when skills are configured\n const allSkills = config.skills ?? [];\n if (allSkills.length > 0) {\n extraTools.push(\n createSkillTool(() => getActiveSkills(allSkills, this.activatedSkills)),\n );\n }\n\n this.toolRegistry = new ToolRegistry(extraTools.length > 0 ? extraTools : undefined);\n if (config.toolSearchEnabled) {\n this.toolRegistry.enableToolSearch();\n const registry = this.toolRegistry;\n registry.register(\n createToolSearchTool(\n () => registry.getDeferredTools(),\n () => registry.listTools(),\n (names) => registry.getToolsByNames(names),\n (names) => registry.markDiscovered(names),\n ),\n );\n }\n this.hooks = config.hooks ?? [];\n this.tracer = config.tracer ?? new NoopTracer();\n this.autoCompactTracking = createAutoCompactTracking();\n this.budgetState = createBudgetState();\n\n if (config.fileStateCacheConfig?.enabled !== false) {\n this.fileStateCache = new FileStateCache(config.fileStateCacheConfig);\n }\n this.contentReplacementState = createContentReplacementState();\n\n if (opts?.resume) {\n this.loaded = false;\n this.resumeRequested = true;\n }\n }\n\n async *run(\n prompt: string | ContentPart[],\n opts?: RunOptions,\n ): AsyncGenerator<StreamEvent, void, unknown> {\n this.abortController = new AbortController();\n const signal = opts?.signal ?? this.abortController.signal;\n\n const interactionSpan = this.tracer.startSpan(\"noumen.interaction\", {\n attributes: {\n \"session.id\": this.sessionId,\n \"model\": this.model,\n \"prompt.length\": prompt.length,\n },\n });\n const interactionStart = Date.now();\n yield { type: \"span_start\", name: \"noumen.interaction\", spanId: this.sessionId };\n\n const isResumeRun = this.resumeRequested;\n\n try {\n if (!this.loaded) {\n if (this.resumeRequested) {\n const payload = await restoreSession(this.storage, this.sessionId);\n this.messages = payload.messages;\n\n if (this.config.checkpointManager && payload.checkpointSnapshots.length > 0) {\n this.config.checkpointManager.restoreStateFromEntries(payload.checkpointSnapshots);\n }\n\n if (this.config.costTracker && payload.costState) {\n this.config.costTracker.restore(payload.costState);\n }\n\n // Reconstruct content replacement state and re-apply spilled stubs\n if (payload.contentReplacements.length > 0) {\n this.contentReplacementState = reconstructContentReplacementState(\n payload.contentReplacements,\n this.messages,\n );\n this.messages = applyPersistedReplacements(\n this.messages,\n this.contentReplacementState,\n );\n }\n\n if (this.config.toolResultStorage?.enabled && this.config.fs) {\n const storageResult = await enforceToolResultStorageBudget(\n this.messages,\n this.config.toolResultStorage,\n this.config.fs,\n this.sessionId,\n this.contentReplacementState,\n );\n this.messages = storageResult.messages;\n this.contentReplacementState = storageResult.state;\n }\n\n // Emit recovery diagnostics\n for (const [filterName, count] of Object.entries(payload.recoveryRemovals)) {\n if (count > 0) {\n yield { type: \"recovery_filtered\", filterName, removedCount: count };\n }\n }\n\n if (payload.interruption.kind !== \"none\") {\n yield {\n type: \"interrupted_turn_detected\",\n kind: payload.interruption.kind,\n };\n }\n\n // Inject continuation prompt for interrupted tool turns\n if (payload.interruption.kind === \"interrupted_tool\") {\n const continuationMsg: ChatMessage = {\n role: \"user\",\n content: \"Continue from where you left off.\",\n };\n this.messages.push(continuationMsg);\n await this.storage.appendMessage(this.sessionId, continuationMsg);\n }\n\n this.resumeRequested = false;\n yield { type: \"session_resumed\", sessionId: this.sessionId, messageCount: this.messages.length };\n } else {\n this.messages = await this.storage.loadMessages(this.sessionId);\n }\n this.loaded = true;\n }\n\n const userMessage: ChatMessage = { role: \"user\", content: prompt };\n this.messages.push(userMessage);\n await this.storage.appendMessage(this.sessionId, userMessage);\n\n const turnMessageId = generateUUID();\n\n if (this.config.checkpointManager) {\n await this.config.checkpointManager.makeSnapshot(turnMessageId, this.sessionId);\n await this.storage.appendCheckpointEntry(\n this.sessionId,\n turnMessageId,\n this.config.checkpointManager.getState().snapshots.at(-1)!,\n false,\n );\n yield { type: \"checkpoint_snapshot\", messageId: turnMessageId };\n }\n\n // --- SessionStart hook ---\n await runNotificationHooks(this.hooks, \"SessionStart\", {\n event: \"SessionStart\",\n sessionId: this.sessionId,\n prompt,\n isResume: isResumeRun,\n } as import(\"./hooks/types.js\").SessionStartHookInput);\n\n const allSkills = this.config.skills ?? [];\n let systemPrompt = await this.buildCurrentSystemPromptAsync(allSkills);\n\n // Structured output configuration: RunOptions override ThreadConfig defaults\n const runOutputFormat = opts?.outputFormat ?? this.config.outputFormat;\n const runOutputMode = opts?.structuredOutputMode ?? this.config.structuredOutputMode ?? \"alongside_tools\";\n const isFinalResponseMode = runOutputFormat?.type === \"json_schema\" && runOutputMode === \"final_response\";\n\n if (isFinalResponseMode) {\n const soTool = createStructuredOutputTool(runOutputFormat);\n if (!this.toolRegistry.get(STRUCTURED_OUTPUT_TOOL_NAME)) {\n this.toolRegistry.register(soTool);\n }\n systemPrompt += \"\\n\\nWhen you have gathered all necessary information and are ready to give your final answer, call the StructuredOutput tool with your response data.\";\n }\n\n let toolDefs = this.config.toolSearchEnabled\n ? this.toolRegistry.getActiveToolDefinitions()\n : this.toolRegistry.toToolDefinitions();\n const toolCtx: ToolContext = {\n fs: this.config.fs,\n computer: this.config.computer,\n cwd: this.cwd,\n sessionId: this.sessionId,\n hooks: this.hooks,\n spawnSubagent: this.config.spawnSubagent,\n userInputHandler: this.config.userInputHandler,\n taskStore: this.config.taskStore,\n lspManager: this.config.lspManager,\n checkpointManager: this.config.checkpointManager,\n currentMessageId: turnMessageId,\n setPermissionMode: this.permissionContext\n ? (mode) => {\n if (this.permissionContext) {\n if (mode === \"plan\" && this.permissionContext.mode !== \"plan\") {\n this.prePlanMode = this.permissionContext.mode;\n }\n if (mode !== \"plan\" && this.permissionContext.mode === \"plan\" && this.prePlanMode) {\n this.permissionContext.mode = this.prePlanMode;\n this.prePlanMode = null;\n } else {\n this.permissionContext.mode = mode;\n }\n }\n }\n : undefined,\n getPermissionMode: this.permissionContext\n ? () => this.permissionContext!.mode\n : undefined,\n setCwd: (newCwd: string) => {\n this.cwd = newCwd;\n toolCtx.cwd = newCwd;\n },\n fileStateCache: this.fileStateCache ?? undefined,\n notifyHook: this.hooks.length > 0\n ? (event, input) => runNotificationHooks(this.hooks, event as import(\"./hooks/types.js\").HookEvent, input as import(\"./hooks/types.js\").HookInput)\n : undefined,\n };\n\n const turnUsage: ChatCompletionUsage = {\n prompt_tokens: 0,\n completion_tokens: 0,\n total_tokens: 0,\n cache_read_tokens: 0,\n cache_creation_tokens: 0,\n thinking_tokens: 0,\n };\n let callCount = 0;\n let preventContinuation = false;\n const hooks = this.hooks;\n\n const useStreamingExec = this.config.streamingToolExecution ?? false;\n const retryConfig = this.config.retry;\n let currentMaxTokens = this.config.maxTokens;\n\n this.microcompactTokensFreed = 0;\n\n while (!signal.aborted) {\n this.hasAttemptedReactiveCompact = false;\n\n // --- Pre-call compaction pipeline ---\n if (this.config.toolResultBudget?.enabled) {\n const budgetResult = enforceToolResultBudget(\n this.messages,\n this.config.toolResultBudget,\n this.budgetState,\n );\n this.messages = budgetResult.messages;\n this.budgetState = budgetResult.state;\n this.microcompactTokensFreed += budgetResult.tokensFreed;\n for (const entry of budgetResult.truncatedEntries) {\n yield {\n type: \"tool_result_truncated\",\n toolCallId: entry.toolCallId,\n originalChars: entry.originalChars,\n truncatedChars: entry.truncatedChars,\n };\n }\n }\n\n if (this.config.microcompact?.enabled) {\n const mcResult = microcompactMessages(this.messages, this.config.microcompact);\n if (mcResult.tokensFreed > 0) {\n this.messages = mcResult.messages;\n this.microcompactTokensFreed += mcResult.tokensFreed;\n yield { type: \"microcompact_complete\", tokensFreed: mcResult.tokensFreed };\n }\n }\n\n // --- Proactive auto-compact (inside loop, before each API call) ---\n const loopAutoCompactConfig =\n this.config.autoCompact ?? createAutoCompactConfig({ model: this.model });\n if (\n canAutoCompact(this.autoCompactTracking) &&\n shouldAutoCompact(\n this.messages,\n loopAutoCompactConfig,\n this.lastUsage,\n this.anchorMessageIndex,\n this.microcompactTokensFreed,\n )\n ) {\n await runNotificationHooks(hooks, \"PreCompact\", {\n event: \"PreCompact\",\n sessionId: this.sessionId,\n });\n yield { type: \"compact_start\" };\n try {\n this.messages = await compactConversation(\n this.config.provider,\n this.model,\n this.messages,\n this.storage,\n this.sessionId,\n {\n tailMessagesToKeep: loopAutoCompactConfig.tailMessagesToKeep,\n stripBinaryContent: true,\n },\n );\n this.lastUsage = undefined;\n this.anchorMessageIndex = undefined;\n this.microcompactTokensFreed = 0;\n recordAutoCompactSuccess(this.autoCompactTracking);\n yield { type: \"compact_complete\" };\n await runNotificationHooks(hooks, \"PostCompact\", {\n event: \"PostCompact\",\n sessionId: this.sessionId,\n });\n } catch (compactErr) {\n recordAutoCompactFailure(this.autoCompactTracking);\n const error = compactErr instanceof Error\n ? compactErr\n : new Error(`Compaction failed: ${String(compactErr)}`);\n await runNotificationHooks(hooks, \"Error\", {\n event: \"Error\",\n sessionId: this.sessionId,\n error,\n });\n yield { type: \"error\", error };\n }\n }\n\n // --- TurnStart notification ---\n await runNotificationHooks(hooks, \"TurnStart\", {\n event: \"TurnStart\",\n sessionId: this.sessionId,\n messages: this.messages,\n });\n\n const accumulatedContent: string[] = [];\n const accumulatedToolCalls = new Map<\n number,\n { id: string; name: string; arguments: string; complete: boolean }\n >();\n let finishReason: string | null = null;\n let lastUsage: ChatCompletionUsage | undefined;\n\n let streamingExec: StreamingToolExecutor | null = null;\n const streamingResults: StreamingExecResult[] = [];\n\n if (useStreamingExec) {\n streamingExec = new StreamingToolExecutor(\n (name) => this.toolRegistry.get(name),\n this.buildStreamingExecutorFn(toolCtx, hooks),\n );\n }\n\n const sortedToolDefs = this.config.promptCachingEnabled\n ? sortToolDefinitionsForCache(toolDefs, this.config.mcpToolNames)\n : toolDefs;\n\n const chatParams = {\n model: this.model,\n messages: this.messages,\n tools: sortedToolDefs,\n system: systemPrompt,\n max_tokens: currentMaxTokens,\n thinking: this.config.thinking,\n skipCacheWrite: this.config.skipCacheWrite,\n ...(runOutputFormat && !isFinalResponseMode ? { outputFormat: runOutputFormat } : {}),\n };\n\n let stream: AsyncIterable<import(\"./providers/types.js\").ChatStreamChunk>;\n\n const providerSpanId = generateUUID();\n const providerSpan = this.tracer.startSpan(\"noumen.provider.chat\", {\n parent: interactionSpan,\n attributes: {\n \"model\": this.model,\n \"messages.count\": this.messages.length,\n \"tools.count\": toolDefs.length,\n },\n });\n yield { type: \"span_start\", name: \"noumen.provider.chat\", spanId: providerSpanId };\n const providerStart = Date.now();\n\n try {\n if (retryConfig) {\n const retryGen = withRetry(\n (ctx) => {\n const params = { ...chatParams };\n if (ctx.maxTokensOverride !== undefined) {\n params.max_tokens = ctx.maxTokensOverride;\n }\n if (ctx.model !== chatParams.model) {\n params.model = ctx.model;\n }\n return this.config.provider.chat(params);\n },\n {\n ...retryConfig,\n model: this.model,\n thinkingBudget:\n this.config.thinking?.type === \"enabled\"\n ? this.config.thinking.budgetTokens\n : undefined,\n signal,\n },\n );\n\n let retryResult = await retryGen.next();\n while (!retryResult.done) {\n const event = retryResult.value;\n if (event.type === \"retry_attempt\" && hooks.length > 0) {\n const re = event as { attempt: number; maxRetries: number; delayMs: number; error: Error };\n await runNotificationHooks(hooks, \"RetryAttempt\", {\n event: \"RetryAttempt\",\n sessionId: this.sessionId,\n attempt: re.attempt,\n maxAttempts: re.maxRetries,\n error: re.error.message,\n delay: re.delayMs,\n } as import(\"./hooks/types.js\").RetryAttemptHookInput);\n }\n yield event;\n retryResult = await retryGen.next();\n }\n\n stream = retryResult.value;\n if (retryResult.value === undefined) break;\n } else {\n stream = this.config.provider.chat(chatParams);\n }\n } catch (providerErr) {\n // Reactive compact: recover from context overflow by compacting\n const isOverflow =\n (providerErr instanceof CannotRetryError &&\n classifyError(providerErr.originalError).isContextOverflow) ||\n (!retryConfig && classifyError(providerErr).isContextOverflow);\n\n if (\n isOverflow &&\n this.config.reactiveCompact?.enabled &&\n !this.hasAttemptedReactiveCompact\n ) {\n this.hasAttemptedReactiveCompact = true;\n providerSpan.setStatus(SpanStatusCode.ERROR, \"context overflow — reactive compact\");\n providerSpan.end();\n yield { type: \"span_end\", name: \"noumen.provider.chat\", spanId: providerSpanId, durationMs: Date.now() - providerStart, error: \"context overflow\" };\n\n await runNotificationHooks(hooks, \"PreCompact\", {\n event: \"PreCompact\",\n sessionId: this.sessionId,\n });\n yield { type: \"compact_start\" };\n const recovered = await tryReactiveCompact(\n this.config.provider,\n this.model,\n this.messages,\n this.storage,\n this.sessionId,\n );\n if (recovered) {\n this.messages = recovered.messages;\n this.lastUsage = undefined;\n this.anchorMessageIndex = undefined;\n yield { type: \"compact_complete\" };\n await runNotificationHooks(hooks, \"PostCompact\", {\n event: \"PostCompact\",\n sessionId: this.sessionId,\n });\n continue;\n }\n yield { type: \"compact_complete\" };\n await runNotificationHooks(hooks, \"PostCompact\", {\n event: \"PostCompact\",\n sessionId: this.sessionId,\n });\n }\n\n // Generate synthetic tool results for any pending tool_calls before re-throwing\n const lastMsg = this.messages[this.messages.length - 1];\n if (lastMsg && lastMsg.role === \"assistant\" && (lastMsg as AssistantMessage).tool_calls) {\n const syntheticResults = generateMissingToolResults(\n lastMsg as AssistantMessage,\n this.messages,\n `Provider error: ${providerErr instanceof Error ? providerErr.message : String(providerErr)}`,\n );\n for (const sr of syntheticResults) {\n this.messages.push(sr);\n await this.storage.appendMessage(this.sessionId, sr);\n }\n }\n\n throw providerErr;\n }\n\n const apiStartTime = Date.now();\n\n for await (const chunk of stream) {\n if (signal.aborted) break;\n\n if (chunk.usage) {\n lastUsage = chunk.usage;\n }\n\n for (const choice of chunk.choices) {\n if (choice.finish_reason) {\n finishReason = choice.finish_reason;\n }\n\n const delta = choice.delta;\n\n if (delta.thinking_content) {\n yield { type: \"thinking_delta\", text: delta.thinking_content };\n }\n\n if (delta.content) {\n accumulatedContent.push(delta.content);\n yield { type: \"text_delta\", text: delta.content };\n }\n\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const existing = accumulatedToolCalls.get(tc.index);\n\n if (!existing) {\n const id = tc.id ?? \"\";\n const name = tc.function?.name ?? \"\";\n accumulatedToolCalls.set(tc.index, {\n id,\n name,\n arguments: tc.function?.arguments ?? \"\",\n complete: false,\n });\n\n if (tc.id && tc.function?.name) {\n yield {\n type: \"tool_use_start\",\n toolName: name,\n toolUseId: id,\n };\n }\n\n if (streamingExec && tc.index > 0) {\n const prevTc = accumulatedToolCalls.get(tc.index - 1);\n if (prevTc && !prevTc.complete) {\n prevTc.complete = true;\n let parsedArgs: Record<string, unknown> = {};\n try { parsedArgs = JSON.parse(prevTc.arguments); } catch {}\n streamingExec.addTool(\n { id: prevTc.id, type: \"function\", function: { name: prevTc.name, arguments: prevTc.arguments } },\n parsedArgs,\n );\n }\n }\n } else {\n if (tc.id) existing.id = tc.id;\n if (tc.function?.name) existing.name = tc.function.name;\n if (tc.function?.arguments) {\n existing.arguments += tc.function.arguments;\n yield {\n type: \"tool_use_delta\",\n input: tc.function.arguments,\n };\n }\n }\n }\n }\n }\n\n if (streamingExec) {\n for (const result of streamingExec.getCompletedResults()) {\n streamingResults.push(result);\n }\n }\n }\n\n const apiDurationMs = Date.now() - apiStartTime;\n\n if (streamingExec) {\n for (const [, tc] of accumulatedToolCalls) {\n if (!tc.complete) {\n tc.complete = true;\n let parsedArgs: Record<string, unknown> = {};\n try { parsedArgs = JSON.parse(tc.arguments); } catch {}\n streamingExec.addTool(\n { id: tc.id, type: \"function\", function: { name: tc.name, arguments: tc.arguments } },\n parsedArgs,\n );\n }\n }\n }\n\n if (signal.aborted) {\n providerSpan.setStatus(SpanStatusCode.OK);\n providerSpan.end();\n yield { type: \"span_end\", name: \"noumen.provider.chat\", spanId: providerSpanId, durationMs: Date.now() - providerStart };\n\n // Generate synthetic results for any tool_calls accumulated before abort\n const partialToolCalls: ToolCallContent[] = Array.from(accumulatedToolCalls.values()).map((tc) => ({\n id: tc.id, type: \"function\" as const, function: { name: tc.name, arguments: tc.arguments },\n }));\n if (partialToolCalls.length > 0) {\n const partialAssistant: AssistantMessage = {\n role: \"assistant\",\n content: accumulatedContent.join(\"\") || null,\n tool_calls: partialToolCalls,\n };\n this.messages.push(partialAssistant);\n await this.storage.appendMessage(this.sessionId, partialAssistant);\n\n const syntheticResults = generateMissingToolResults(partialAssistant, [], \"Interrupted by abort\");\n for (const sr of syntheticResults) {\n this.messages.push(sr);\n await this.storage.appendMessage(this.sessionId, sr);\n }\n }\n break;\n }\n\n callCount++;\n if (lastUsage) {\n turnUsage.prompt_tokens += lastUsage.prompt_tokens;\n turnUsage.completion_tokens += lastUsage.completion_tokens;\n turnUsage.total_tokens += lastUsage.total_tokens;\n turnUsage.cache_read_tokens = (turnUsage.cache_read_tokens ?? 0) + (lastUsage.cache_read_tokens ?? 0);\n turnUsage.cache_creation_tokens = (turnUsage.cache_creation_tokens ?? 0) + (lastUsage.cache_creation_tokens ?? 0);\n turnUsage.thinking_tokens = (turnUsage.thinking_tokens ?? 0) + (lastUsage.thinking_tokens ?? 0);\n this.lastUsage = lastUsage;\n this.anchorMessageIndex = this.messages.length - 1;\n this.microcompactTokensFreed = 0;\n yield { type: \"usage\", usage: lastUsage, model: this.model };\n\n if (this.config.costTracker) {\n const summary = this.config.costTracker.addUsage(\n this.model,\n lastUsage,\n apiDurationMs,\n );\n yield { type: \"cost_update\", summary };\n }\n\n providerSpan.setAttribute(\"tokens.input\", lastUsage.prompt_tokens);\n providerSpan.setAttribute(\"tokens.output\", lastUsage.completion_tokens);\n }\n\n if (this.config.promptCachingEnabled) {\n saveCacheSafeParams(\n createCacheSafeParams({\n systemPrompt,\n model: this.model,\n tools: sortedToolDefs,\n thinking: this.config.thinking,\n }),\n this.sessionId,\n );\n }\n\n providerSpan.setStatus(SpanStatusCode.OK);\n providerSpan.end();\n yield { type: \"span_end\", name: \"noumen.provider.chat\", spanId: providerSpanId, durationMs: Date.now() - providerStart };\n\n const textContent = accumulatedContent.join(\"\");\n const toolCalls: ToolCallContent[] = Array.from(\n accumulatedToolCalls.values(),\n ).map((tc) => ({\n id: tc.id,\n type: \"function\" as const,\n function: {\n name: tc.name,\n arguments: tc.arguments,\n },\n }));\n\n const assistantMsg: AssistantMessage = {\n role: \"assistant\",\n content: textContent || null,\n ...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),\n };\n\n this.messages.push(assistantMsg);\n await this.storage.appendMessage(this.sessionId, assistantMsg);\n\n if (toolCalls.length > 0) {\n const touchedFilePaths: string[] = [];\n const registry = this.toolRegistry;\n const storage = this.storage;\n const sessionId = this.sessionId;\n const messages = this.messages;\n\n // Choose execution path: streaming (already started) or batched (post-stream)\n if (streamingExec) {\n // Collect any results that were already gathered during streaming\n const allResults = [...streamingResults];\n for await (const result of streamingExec.getRemainingResults()) {\n allResults.push(result);\n }\n\n const spilledRecords: import(\"./compact/tool-result-storage.js\").ContentReplacementRecord[] = [];\n\n for (const execResult of allResults) {\n for (const evt of execResult.events) {\n yield evt;\n }\n\n if (!execResult.permissionDenied) {\n yield {\n type: \"tool_result\",\n toolUseId: execResult.toolCall.id,\n toolName: execResult.toolCall.function.name,\n result: execResult.result,\n };\n\n // Emit git operation events from bash tool results\n const gitOps = execResult.result.metadata?.gitOperations as\n | Array<{ type: string; details: string }>\n | undefined;\n if (gitOps) {\n for (const op of gitOps) {\n yield {\n type: \"git_operation\" as const,\n operation: op.type as \"commit\" | \"push\" | \"pr_create\" | \"merge\" | \"rebase\",\n details: op.details,\n };\n }\n }\n }\n\n if (execResult.preventContinuation) {\n preventContinuation = true;\n }\n\n // Spill oversized results to disk before appending to messages\n let resultContent = execResult.result.content;\n if (typeof resultContent === \"string\") {\n const spill = await this.maybeSpillToolResult(\n execResult.toolCall.id,\n execResult.toolCall.function.name,\n resultContent,\n );\n if (spill.spilled) {\n resultContent = spill.content;\n spilledRecords.push({ toolUseId: execResult.toolCall.id, replacement: spill.content });\n }\n }\n\n const toolResultMsg: ChatMessage = {\n role: \"tool\",\n tool_call_id: execResult.toolCall.id,\n content: resultContent,\n };\n messages.push(toolResultMsg);\n await storage.appendMessage(sessionId, toolResultMsg);\n\n if (\n FILE_TOOLS.has(execResult.toolCall.function.name) &&\n typeof execResult.parsedArgs.file_path === \"string\"\n ) {\n touchedFilePaths.push(execResult.parsedArgs.file_path);\n }\n }\n\n // Persist content replacement records for resume\n if (spilledRecords.length > 0) {\n await storage.appendContentReplacement(sessionId, spilledRecords);\n }\n } else {\n // Batched execution (original path)\n const permCtx = this.permissionContext;\n const permHandler = this.permissionHandler;\n const eventQueue: StreamEvent[] = [];\n\n const executor = async (\n tc: ToolCallContent,\n parsedArgs: Record<string, unknown>,\n ): Promise<ToolCallExecResult> => {\n let currentArgs = parsedArgs;\n\n // --- Permission gate ---\n if (permCtx) {\n const tool = registry.get(tc.function.name);\n if (tool) {\n const decision = await resolvePermission(\n tool,\n currentArgs,\n toolCtx,\n permCtx,\n this.buildPermissionOpts(),\n );\n\n if (decision.behavior === \"deny\") {\n this.denialTracker?.recordDenial();\n eventQueue.push({\n type: \"permission_denied\",\n toolName: tc.function.name,\n input: currentArgs,\n message: decision.message,\n });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: decision.message,\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n eventQueue.push({\n type: \"denial_limit_exceeded\",\n consecutiveDenials: state.consecutiveDenials,\n totalDenials: state.totalDenials,\n });\n preventContinuation = true;\n }\n const content = `Permission denied: ${decision.message}`;\n return { toolCall: tc, parsedArgs: currentArgs, result: { content, isError: true }, permissionDenied: true };\n }\n\n if (decision.behavior === \"ask\") {\n await runNotificationHooks(hooks, \"PermissionRequest\", {\n event: \"PermissionRequest\", sessionId, toolName: tc.function.name,\n input: currentArgs, mode: permCtx?.mode ?? \"default\",\n } as import(\"./hooks/types.js\").PermissionRequestHookInput);\n eventQueue.push({\n type: \"permission_request\",\n toolName: tc.function.name,\n input: currentArgs,\n message: decision.message,\n });\n\n if (permHandler) {\n const isReadOnly = resolveToolFlag(tool.isReadOnly, currentArgs);\n const isDestructive = resolveToolFlag(tool.isDestructive, currentArgs);\n const request: PermissionRequest = {\n toolName: tc.function.name,\n input: currentArgs,\n message: decision.message,\n suggestions: decision.suggestions,\n isReadOnly,\n isDestructive,\n };\n const response = await permHandler(request);\n\n if (!response.allow) {\n this.denialTracker?.recordDenial();\n const feedback = response.feedback ?? \"User denied permission.\";\n eventQueue.push({\n type: \"permission_denied\",\n toolName: tc.function.name,\n input: currentArgs,\n message: feedback,\n });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: feedback,\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n eventQueue.push({\n type: \"denial_limit_exceeded\",\n consecutiveDenials: state.consecutiveDenials,\n totalDenials: state.totalDenials,\n });\n preventContinuation = true;\n }\n const content = `Permission denied: ${feedback}`;\n return { toolCall: tc, parsedArgs: currentArgs, result: { content, isError: true }, permissionDenied: true };\n }\n\n if (response.updatedInput) {\n currentArgs = response.updatedInput;\n }\n if (response.addRules) {\n permCtx.rules.push(...response.addRules);\n }\n } else {\n this.denialTracker?.recordDenial();\n eventQueue.push({\n type: \"permission_denied\",\n toolName: tc.function.name,\n input: currentArgs,\n message: \"No permission handler configured.\",\n });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: \"No permission handler configured.\",\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n eventQueue.push({\n type: \"denial_limit_exceeded\",\n consecutiveDenials: state.consecutiveDenials,\n totalDenials: state.totalDenials,\n });\n preventContinuation = true;\n }\n const content = \"Permission denied: No permission handler configured.\";\n return { toolCall: tc, parsedArgs: currentArgs, result: { content, isError: true }, permissionDenied: true };\n }\n }\n\n this.denialTracker?.recordSuccess();\n if (decision.behavior === \"allow\" && decision.updatedInput) {\n currentArgs = decision.updatedInput as Record<string, unknown>;\n }\n eventQueue.push({\n type: \"permission_granted\",\n toolName: tc.function.name,\n input: currentArgs,\n });\n }\n }\n\n // --- PreToolUse hooks ---\n if (hooks.length > 0) {\n const hookOutput = await runPreToolUseHooks(hooks, {\n event: \"PreToolUse\",\n toolName: tc.function.name,\n toolInput: currentArgs,\n toolUseId: tc.id,\n sessionId,\n });\n\n if (hookOutput.decision === \"deny\") {\n const msg = hookOutput.message ?? \"Blocked by hook.\";\n return { toolCall: tc, parsedArgs: currentArgs, result: { content: `Hook denied: ${msg}`, isError: true }, permissionDenied: true };\n }\n if (hookOutput.updatedInput) {\n currentArgs = hookOutput.updatedInput;\n\n // Re-validate working directory enforcement on modified input\n if (permCtx && permCtx.workingDirectories.length > 0) {\n const hookFilePath =\n typeof currentArgs.file_path === \"string\" ? currentArgs.file_path\n : typeof currentArgs.path === \"string\" ? currentArgs.path\n : undefined;\n if (hookFilePath && !isPathInWorkingDirectories(hookFilePath, permCtx.workingDirectories)) {\n return {\n toolCall: tc,\n parsedArgs: currentArgs,\n result: { content: `Permission denied: Hook-modified path \"${hookFilePath}\" is outside working directories.`, isError: true },\n permissionDenied: true,\n };\n }\n }\n }\n if (hookOutput.preventContinuation) {\n preventContinuation = true;\n }\n }\n\n const toolSpan = this.tracer.startSpan(\"noumen.tool.execute\", {\n parent: interactionSpan,\n attributes: { \"tool.name\": tc.function.name, \"tool.id\": tc.id },\n });\n let result = await registry.execute(\n tc.function.name,\n currentArgs,\n toolCtx,\n );\n const resultText = contentToString(result.content);\n toolSpan.setStatus(result.isError ? SpanStatusCode.ERROR : SpanStatusCode.OK, result.isError ? resultText : undefined);\n toolSpan.end();\n\n // --- PostToolUse hooks ---\n if (hooks.length > 0) {\n const postOutput = await runPostToolUseHooks(hooks, {\n event: \"PostToolUse\",\n toolName: tc.function.name,\n toolInput: currentArgs,\n toolUseId: tc.id,\n toolOutput: resultText,\n isError: result.isError ?? false,\n sessionId,\n });\n\n if (postOutput.updatedOutput !== undefined) {\n result = { ...result, content: postOutput.updatedOutput };\n }\n if (postOutput.preventContinuation) {\n preventContinuation = true;\n }\n\n // --- PostToolUseFailure hooks ---\n if (result.isError) {\n const failOutput = await runPostToolUseFailureHooks(hooks, {\n event: \"PostToolUseFailure\",\n toolName: tc.function.name,\n toolInput: currentArgs,\n toolUseId: tc.id,\n toolOutput: contentToString(result.content),\n errorMessage: contentToString(result.content),\n sessionId,\n });\n if (failOutput.updatedOutput !== undefined) {\n result = { ...result, content: failOutput.updatedOutput };\n }\n if (failOutput.preventContinuation) {\n preventContinuation = true;\n }\n }\n }\n\n return { toolCall: tc, parsedArgs: currentArgs, result };\n };\n\n const batchSpilledRecords: import(\"./compact/tool-result-storage.js\").ContentReplacementRecord[] = [];\n\n for await (const execResult of runToolsBatched(\n toolCalls,\n (name) => registry.get(name),\n executor,\n )) {\n // Flush queued permission events\n for (const evt of eventQueue) {\n yield evt;\n }\n eventQueue.length = 0;\n\n const { toolCall: tc, parsedArgs: finalArgs, result, permissionDenied } = execResult;\n\n if (!permissionDenied) {\n yield {\n type: \"tool_result\",\n toolUseId: tc.id,\n toolName: tc.function.name,\n result,\n };\n\n // Emit git operation events from bash tool results\n const gitOps = result.metadata?.gitOperations as\n | Array<{ type: string; details: string }>\n | undefined;\n if (gitOps) {\n for (const op of gitOps) {\n yield {\n type: \"git_operation\" as const,\n operation: op.type as \"commit\" | \"push\" | \"pr_create\" | \"merge\" | \"rebase\",\n details: op.details,\n };\n }\n }\n }\n\n // Spill oversized results to disk before appending to messages\n let resultContent = result.content;\n if (typeof resultContent === \"string\") {\n const spill = await this.maybeSpillToolResult(tc.id, tc.function.name, resultContent);\n if (spill.spilled) {\n resultContent = spill.content;\n batchSpilledRecords.push({ toolUseId: tc.id, replacement: spill.content });\n }\n }\n\n const toolResultMsg: ChatMessage = {\n role: \"tool\",\n tool_call_id: tc.id,\n content: resultContent,\n };\n\n messages.push(toolResultMsg);\n await storage.appendMessage(sessionId, toolResultMsg);\n\n if (FILE_TOOLS.has(tc.function.name) && typeof finalArgs.file_path === \"string\") {\n touchedFilePaths.push(finalArgs.file_path);\n }\n }\n\n // Flush any remaining permission events\n for (const evt of eventQueue) {\n yield evt;\n }\n eventQueue.length = 0;\n\n // Persist content replacement records for resume\n if (batchSpilledRecords.length > 0) {\n await storage.appendContentReplacement(sessionId, batchSpilledRecords);\n }\n }\n\n if (touchedFilePaths.length > 0) {\n let needsRebuild = false;\n\n if (allSkills.length > 0) {\n const newlyActivated = activateSkillsForPaths(\n allSkills,\n touchedFilePaths,\n this.cwd,\n this.activatedSkills,\n );\n if (newlyActivated.length > 0) needsRebuild = true;\n }\n\n if (this.config.projectContext?.length) {\n const newCtx = activateContextForPaths(\n this.config.projectContext,\n touchedFilePaths,\n this.cwd,\n this.activatedContextRules,\n );\n if (newCtx.length > 0) needsRebuild = true;\n }\n\n if (needsRebuild) {\n systemPrompt = await this.buildCurrentSystemPromptAsync(allSkills);\n }\n }\n\n if (this.config.toolSearchEnabled) {\n toolDefs = this.toolRegistry.getActiveToolDefinitions();\n }\n\n // Detect StructuredOutput tool call in final_response mode\n if (isFinalResponseMode) {\n for (const tc of toolCalls) {\n if (tc.function.name === STRUCTURED_OUTPUT_TOOL_NAME) {\n try {\n const parsed = JSON.parse(tc.function.arguments);\n yield {\n type: \"structured_output\",\n data: parsed.data ?? parsed,\n schema: runOutputFormat,\n };\n } catch {\n yield {\n type: \"structured_output\",\n data: tc.function.arguments,\n schema: runOutputFormat,\n };\n }\n preventContinuation = true;\n break;\n }\n }\n }\n\n if (preventContinuation) break;\n\n if (opts?.maxTurns !== undefined && callCount >= opts.maxTurns) {\n yield { type: \"max_turns_reached\", maxTurns: opts.maxTurns, turnCount: callCount };\n break;\n }\n continue;\n }\n\n // For alongside_tools mode, emit structured_output when the model produces text\n if (runOutputFormat && !isFinalResponseMode && textContent) {\n try {\n const parsed = JSON.parse(textContent);\n yield {\n type: \"structured_output\",\n data: parsed,\n schema: runOutputFormat,\n };\n } catch {\n // Model text wasn't valid JSON — still emit message_complete below\n }\n }\n\n yield { type: \"message_complete\", message: assistantMsg };\n\n await runNotificationHooks(hooks, \"TurnEnd\", {\n event: \"TurnEnd\",\n sessionId: this.sessionId,\n });\n\n yield {\n type: \"turn_complete\",\n usage: turnUsage,\n model: this.model,\n callCount,\n };\n\n // Persist cost state so it survives resume\n if (this.config.costTracker) {\n await this.storage.appendMetadata(\n this.sessionId,\n \"costState\",\n this.config.costTracker.getState(),\n );\n }\n\n break;\n }\n\n // --- Memory extraction ---\n const memCfg = this.config.memory;\n if (memCfg && memCfg.autoExtract && memCfg.provider) {\n try {\n const extractResult = await extractMemories(\n this.config.provider,\n this.model,\n this.messages,\n memCfg.provider,\n );\n const hasChanges = extractResult.created.length > 0\n || extractResult.updated.length > 0\n || extractResult.deleted.length > 0;\n if (hasChanges) {\n yield {\n type: \"memory_update\",\n created: extractResult.created,\n updated: extractResult.updated,\n deleted: extractResult.deleted,\n };\n const allEntries = [\n ...extractResult.created.map((e) => ({ type: \"created\", content: e.content })),\n ...extractResult.updated.map((e) => ({ type: \"updated\", content: e.content })),\n ...extractResult.deleted.map((id) => ({ type: \"deleted\", content: id })),\n ];\n await runNotificationHooks(this.hooks, \"MemoryUpdate\", {\n event: \"MemoryUpdate\",\n sessionId: this.sessionId,\n entries: allEntries,\n } as import(\"./hooks/types.js\").MemoryUpdateHookInput);\n }\n } catch {\n // Memory extraction is best-effort; don't fail the turn.\n }\n }\n\n interactionSpan.setStatus(SpanStatusCode.OK);\n interactionSpan.end();\n yield { type: \"span_end\", name: \"noumen.interaction\", spanId: this.sessionId, durationMs: Date.now() - interactionStart };\n\n // Determine session end reason\n const endReason: \"complete\" | \"abort\" | \"maxTurns\" = signal.aborted\n ? \"abort\"\n : (opts?.maxTurns !== undefined && callCount >= opts.maxTurns)\n ? \"maxTurns\"\n : \"complete\";\n await runNotificationHooks(this.hooks, \"SessionEnd\", {\n event: \"SessionEnd\",\n sessionId: this.sessionId,\n reason: endReason,\n } as import(\"./hooks/types.js\").SessionEndHookInput);\n } catch (err) {\n if (!signal.aborted) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n interactionSpan.setStatus(SpanStatusCode.ERROR, error.message);\n interactionSpan.end();\n yield { type: \"span_end\", name: \"noumen.interaction\", spanId: this.sessionId, durationMs: Date.now() - interactionStart, error: error.message };\n\n await runNotificationHooks(this.hooks, \"Error\", {\n event: \"Error\",\n sessionId: this.sessionId,\n error,\n });\n\n yield { type: \"error\", error };\n } else {\n interactionSpan.setStatus(SpanStatusCode.OK);\n interactionSpan.end();\n yield { type: \"span_end\", name: \"noumen.interaction\", spanId: this.sessionId, durationMs: Date.now() - interactionStart };\n }\n\n await runNotificationHooks(this.hooks, \"SessionEnd\", {\n event: \"SessionEnd\",\n sessionId: this.sessionId,\n reason: signal.aborted ? \"abort\" : \"error\",\n } as import(\"./hooks/types.js\").SessionEndHookInput);\n }\n }\n\n /**\n * If tool result storage is enabled and the content exceeds the threshold,\n * spill to disk and return the replacement stub. Otherwise return the original.\n */\n private async maybeSpillToolResult(\n toolUseId: string,\n toolName: string,\n content: string,\n ): Promise<{ content: string; spilled: boolean }> {\n const storageConfig = this.config.toolResultStorage;\n if (!storageConfig?.enabled) return { content, spilled: false };\n\n const replacement = await persistToolResult(\n this.config.fs,\n this.sessionId,\n toolUseId,\n toolName,\n content,\n storageConfig,\n );\n\n if (replacement) {\n this.contentReplacementState.seenIds.add(toolUseId);\n this.contentReplacementState.replacements.set(toolUseId, replacement);\n return { content: replacement, spilled: true };\n }\n\n this.contentReplacementState.seenIds.add(toolUseId);\n return { content, spilled: false };\n }\n\n private buildStreamingExecutorFn(\n toolCtx: ToolContext,\n hooks: HookDefinition[],\n ): import(\"./tools/streaming-executor.js\").StreamingToolExecutorFn {\n const permCtx = this.permissionContext;\n const permHandler = this.permissionHandler;\n const registry = this.toolRegistry;\n const sessionId = this.sessionId;\n\n return async (tc, parsedArgs) => {\n let currentArgs = parsedArgs;\n const events: StreamEvent[] = [];\n\n if (permCtx) {\n const tool = registry.get(tc.function.name);\n if (tool) {\n const decision = await resolvePermission(tool, currentArgs, toolCtx, permCtx, this.buildPermissionOpts());\n\n if (decision.behavior === \"deny\") {\n this.denialTracker?.recordDenial();\n events.push({ type: \"permission_denied\", toolName: tc.function.name, input: currentArgs, message: decision.message });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: decision.message,\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n events.push({ type: \"denial_limit_exceeded\", consecutiveDenials: state.consecutiveDenials, totalDenials: state.totalDenials });\n }\n return { result: { content: `Permission denied: ${decision.message}`, isError: true }, permissionDenied: true, preventContinuation: this.denialTracker?.shouldFallback() || undefined, events };\n }\n\n if (decision.behavior === \"ask\") {\n await runNotificationHooks(hooks, \"PermissionRequest\", {\n event: \"PermissionRequest\", sessionId, toolName: tc.function.name,\n input: currentArgs, mode: permCtx?.mode ?? \"default\",\n } as import(\"./hooks/types.js\").PermissionRequestHookInput);\n events.push({ type: \"permission_request\", toolName: tc.function.name, input: currentArgs, message: decision.message });\n if (permHandler) {\n const isReadOnly = resolveToolFlag(tool.isReadOnly, currentArgs);\n const isDestructive = resolveToolFlag(tool.isDestructive, currentArgs);\n const response = await permHandler({\n toolName: tc.function.name,\n input: currentArgs,\n message: decision.message,\n suggestions: decision.suggestions,\n isReadOnly,\n isDestructive,\n });\n if (!response.allow) {\n this.denialTracker?.recordDenial();\n const feedback = response.feedback ?? \"User denied permission.\";\n events.push({ type: \"permission_denied\", toolName: tc.function.name, input: currentArgs, message: feedback });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: feedback,\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n events.push({ type: \"denial_limit_exceeded\", consecutiveDenials: state.consecutiveDenials, totalDenials: state.totalDenials });\n }\n return { result: { content: `Permission denied: ${feedback}`, isError: true }, permissionDenied: true, preventContinuation: this.denialTracker?.shouldFallback() || undefined, events };\n }\n if (response.updatedInput) currentArgs = response.updatedInput;\n if (response.addRules) permCtx.rules.push(...response.addRules);\n } else {\n this.denialTracker?.recordDenial();\n events.push({ type: \"permission_denied\", toolName: tc.function.name, input: currentArgs, message: \"No permission handler configured.\" });\n await runNotificationHooks(hooks, \"PermissionDenied\", {\n event: \"PermissionDenied\", sessionId, toolName: tc.function.name,\n input: currentArgs, reason: \"No permission handler configured.\",\n } as import(\"./hooks/types.js\").PermissionDeniedHookInput);\n if (this.denialTracker?.shouldFallback()) {\n const state = this.denialTracker.getState();\n events.push({ type: \"denial_limit_exceeded\", consecutiveDenials: state.consecutiveDenials, totalDenials: state.totalDenials });\n }\n return { result: { content: \"Permission denied: No permission handler configured.\", isError: true }, permissionDenied: true, preventContinuation: this.denialTracker?.shouldFallback() || undefined, events };\n }\n }\n\n this.denialTracker?.recordSuccess();\n if (decision.behavior === \"allow\" && decision.updatedInput) {\n currentArgs = decision.updatedInput as Record<string, unknown>;\n }\n events.push({ type: \"permission_granted\", toolName: tc.function.name, input: currentArgs });\n }\n }\n\n let hookPreventContinuation = false;\n\n if (hooks.length > 0) {\n const hookOutput = await runPreToolUseHooks(hooks, {\n event: \"PreToolUse\", toolName: tc.function.name, toolInput: currentArgs, toolUseId: tc.id, sessionId,\n });\n if (hookOutput.decision === \"deny\") {\n return { result: { content: `Hook denied: ${hookOutput.message ?? \"Blocked by hook.\"}`, isError: true }, permissionDenied: true, events };\n }\n if (hookOutput.updatedInput) {\n currentArgs = hookOutput.updatedInput;\n\n // Re-validate working directory enforcement on modified input\n if (permCtx && permCtx.workingDirectories.length > 0) {\n const hookFilePath =\n typeof currentArgs.file_path === \"string\" ? currentArgs.file_path\n : typeof currentArgs.path === \"string\" ? currentArgs.path\n : undefined;\n if (hookFilePath && !isPathInWorkingDirectories(hookFilePath, permCtx.workingDirectories)) {\n return {\n result: { content: `Permission denied: Hook-modified path \"${hookFilePath}\" is outside working directories.`, isError: true },\n permissionDenied: true,\n events,\n };\n }\n }\n }\n if (hookOutput.preventContinuation) hookPreventContinuation = true;\n }\n\n const toolSpan = this.tracer.startSpan(\"noumen.tool.execute\", {\n attributes: { \"tool.name\": tc.function.name, \"tool.id\": tc.id },\n });\n let result = await registry.execute(tc.function.name, currentArgs, toolCtx);\n const streamResultText = contentToString(result.content);\n toolSpan.setStatus(result.isError ? SpanStatusCode.ERROR : SpanStatusCode.OK, result.isError ? streamResultText : undefined);\n toolSpan.end();\n\n if (hooks.length > 0) {\n const postOutput = await runPostToolUseHooks(hooks, {\n event: \"PostToolUse\", toolName: tc.function.name, toolInput: currentArgs, toolUseId: tc.id, toolOutput: streamResultText, isError: result.isError ?? false, sessionId,\n });\n if (postOutput.updatedOutput !== undefined) {\n result = { ...result, content: postOutput.updatedOutput };\n }\n if (postOutput.preventContinuation) hookPreventContinuation = true;\n\n if (result.isError) {\n const failOutput = await runPostToolUseFailureHooks(hooks, {\n event: \"PostToolUseFailure\", toolName: tc.function.name, toolInput: currentArgs, toolUseId: tc.id,\n toolOutput: contentToString(result.content), errorMessage: contentToString(result.content), sessionId,\n });\n if (failOutput.updatedOutput !== undefined) {\n result = { ...result, content: failOutput.updatedOutput };\n }\n if (failOutput.preventContinuation) hookPreventContinuation = true;\n }\n }\n\n return { result, preventContinuation: hookPreventContinuation || undefined, events };\n };\n }\n\n private buildPermissionOpts(): ResolvePermissionOptions | undefined {\n const autoMode = this.config.permissions?.autoMode;\n if (!autoMode) return undefined;\n const tail = this.messages.slice(-10);\n return {\n provider: this.config.provider,\n model: this.model,\n recentMessages: tail,\n autoModeConfig: autoMode,\n };\n }\n\n private async buildCurrentSystemPromptAsync(allSkills: SkillDefinition[]): Promise<string> {\n const activeSkills = getActiveSkills(allSkills, this.activatedSkills);\n let memorySection: string | undefined;\n\n const memCfg = this.config.memory;\n if (memCfg?.provider && memCfg.injectIntoSystemPrompt !== false) {\n try {\n const indexContent = await memCfg.provider.loadIndex();\n memorySection = buildMemorySystemPromptSection(indexContent, \"(memory)\");\n } catch {\n // If memory loading fails, proceed without it.\n }\n }\n\n let projectContextSection: string | undefined;\n if (this.config.projectContext?.length) {\n const active = filterActiveContextFiles(\n this.config.projectContext,\n [],\n this.cwd,\n );\n const unconditional = active.filter((f) => !f.globs || f.globs.length === 0);\n const activatedConditional = this.config.projectContext.filter(\n (f) => f.globs && f.globs.length > 0 && this.activatedContextRules.has(f.path),\n );\n const combined = [...unconditional, ...activatedConditional];\n if (combined.length > 0) {\n projectContextSection = buildProjectContextSection(combined);\n }\n }\n\n const deferredTools = this.config.toolSearchEnabled\n ? this.toolRegistry.getDeferredTools().map((t) => ({\n name: t.name,\n description: t.description,\n }))\n : undefined;\n\n return buildSystemPrompt({\n customPrompt: this.config.systemPrompt,\n skills: activeSkills,\n tools: this.toolRegistry.listTools(),\n projectContext: projectContextSection,\n memorySection,\n deferredTools: deferredTools?.length ? deferredTools : undefined,\n });\n }\n\n async getMessages(): Promise<ChatMessage[]> {\n if (!this.loaded) {\n if (this.resumeRequested) {\n const payload = await restoreSession(this.storage, this.sessionId);\n this.messages = payload.messages;\n if (this.config.checkpointManager && payload.checkpointSnapshots.length > 0) {\n this.config.checkpointManager.restoreStateFromEntries(payload.checkpointSnapshots);\n }\n if (this.config.costTracker && payload.costState) {\n this.config.costTracker.restore(payload.costState);\n }\n if (payload.contentReplacements.length > 0) {\n this.contentReplacementState = reconstructContentReplacementState(\n payload.contentReplacements,\n this.messages,\n );\n this.messages = applyPersistedReplacements(\n this.messages,\n this.contentReplacementState,\n );\n }\n this.resumeRequested = false;\n } else {\n this.messages = await this.storage.loadMessages(this.sessionId);\n }\n this.loaded = true;\n }\n return [...this.messages];\n }\n\n async compact(opts?: { instructions?: string }): Promise<void> {\n if (!this.loaded) {\n this.messages = await this.storage.loadMessages(this.sessionId);\n this.loaded = true;\n }\n\n this.messages = await compactConversation(\n this.config.provider,\n this.model,\n this.messages,\n this.storage,\n this.sessionId,\n { customInstructions: opts?.instructions },\n );\n this.lastUsage = undefined;\n this.anchorMessageIndex = undefined;\n }\n\n /**\n * Remove specific messages from the middle of conversation history.\n *\n * Unlike `compact()` which summarizes a prefix, `snip()` removes\n * specific messages by UUID. The JSONL transcript records the removed\n * UUIDs so they're filtered on resume. Parent pointers are relinked\n * across gaps.\n *\n * @param uuids - UUIDs of messages to remove\n */\n async snip(uuids: string[]): Promise<void> {\n if (uuids.length === 0) return;\n await this.storage.appendSnipBoundary(this.sessionId, uuids);\n\n // Rebuild messages from entries with snip applied\n const entries = await this.storage.loadAllEntries(this.sessionId);\n const { applySnipRemovals } = await import(\"./compact/history-snip.js\");\n\n let lastBoundaryIdx = -1;\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].type === \"compact-boundary\") {\n lastBoundaryIdx = i;\n break;\n }\n }\n\n const activeEntries = entries.slice(lastBoundaryIdx + 1);\n const result = applySnipRemovals(activeEntries);\n this.messages = result.messages;\n }\n\n setModel(model: string): void {\n const prev = this.model;\n this.model = model;\n if (prev !== model && this.hooks.length > 0) {\n runNotificationHooks(this.hooks, \"ModelSwitch\", {\n event: \"ModelSwitch\",\n sessionId: this.sessionId,\n previousModel: prev,\n newModel: model,\n } as import(\"./hooks/types.js\").ModelSwitchHookInput).catch(() => {});\n }\n }\n\n setProvider(provider: AIProvider, model?: string): void {\n const prev = this.model;\n this.config.provider = provider;\n if (model) this.model = model;\n if (model && prev !== model && this.hooks.length > 0) {\n runNotificationHooks(this.hooks, \"ModelSwitch\", {\n event: \"ModelSwitch\",\n sessionId: this.sessionId,\n previousModel: prev,\n newModel: model,\n } as import(\"./hooks/types.js\").ModelSwitchHookInput).catch(() => {});\n }\n }\n\n getModel(): string {\n return this.model;\n }\n\n abort(): void {\n this.abortController?.abort();\n }\n}\n","import type { VirtualFs } from \"../virtual/fs.js\";\nimport type { SkillDefinition } from \"./types.js\";\nimport { parseFrontmatter, parseAllowedTools, parsePaths } from \"./frontmatter.js\";\n\n/**\n * Load skill definitions from SKILL.md files found at the given paths on the VirtualFs.\n * Each path can be a directory (scanned for SKILL.md files) or a direct file.\n */\nexport async function loadSkills(\n fs: VirtualFs,\n paths: string[],\n): Promise<SkillDefinition[]> {\n const skills: SkillDefinition[] = [];\n\n for (const skillPath of paths) {\n try {\n const stat = await fs.stat(skillPath);\n\n if (stat.isFile) {\n const skill = await loadSkillFile(fs, skillPath);\n if (skill) skills.push(skill);\n } else if (stat.isDirectory) {\n const dirSkills = await loadSkillsFromDir(fs, skillPath);\n skills.push(...dirSkills);\n }\n } catch {\n // path doesn't exist or isn't accessible; skip\n }\n }\n\n return skills;\n}\n\nasync function loadSkillFile(\n fs: VirtualFs,\n filePath: string,\n): Promise<SkillDefinition | null> {\n try {\n const raw = await fs.readFile(filePath);\n const { frontmatter, body } = parseFrontmatter(raw);\n\n const name = extractSkillName(filePath, body);\n\n const fmDescription = frontmatter.description;\n const description =\n typeof fmDescription === \"string\" && fmDescription\n ? fmDescription\n : extractDescription(body);\n\n const globs = parsePaths(frontmatter.paths);\n const allowedTools = parseAllowedTools(frontmatter[\"allowed-tools\"]);\n\n const context = frontmatter.context === \"fork\" ? \"fork\" as const : undefined;\n const argumentHint =\n typeof frontmatter[\"argument-hint\"] === \"string\"\n ? frontmatter[\"argument-hint\"]\n : undefined;\n\n return {\n name,\n content: body,\n path: filePath,\n description,\n ...(globs.length > 0 ? { globs } : {}),\n ...(allowedTools.length > 0 ? { allowedTools } : {}),\n ...(context ? { context } : {}),\n ...(argumentHint ? { argumentHint } : {}),\n };\n } catch {\n return null;\n }\n}\n\nasync function loadSkillsFromDir(\n fs: VirtualFs,\n dirPath: string,\n): Promise<SkillDefinition[]> {\n const skills: SkillDefinition[] = [];\n\n try {\n const entries = await fs.readdir(dirPath);\n\n for (const entry of entries) {\n if (\n entry.isFile &&\n (entry.name === \"SKILL.md\" || entry.name.endsWith(\".md\"))\n ) {\n const skill = await loadSkillFile(fs, entry.path);\n if (skill) skills.push(skill);\n } else if (entry.isDirectory) {\n const skillMdPath = `${entry.path}/SKILL.md`;\n const skill = await loadSkillFile(fs, skillMdPath);\n if (skill) skills.push(skill);\n }\n }\n } catch {\n // directory not readable; skip\n }\n\n return skills;\n}\n\nfunction extractSkillName(filePath: string, content: string): string {\n const h1Match = content.match(/^#\\s+(.+)$/m);\n if (h1Match) return h1Match[1].trim();\n\n const parts = filePath.split(\"/\");\n const fileName = parts[parts.length - 1];\n if (fileName === \"SKILL.md\" && parts.length >= 2) {\n return parts[parts.length - 2];\n }\n return fileName.replace(/\\.md$/, \"\");\n}\n\nfunction extractDescription(content: string): string | undefined {\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed && !trimmed.startsWith(\"#\") && !trimmed.startsWith(\"---\")) {\n return trimmed.slice(0, 200);\n }\n }\n return undefined;\n}\n","import type { SkillDefinition } from \"../skills/types.js\";\nimport type { VirtualFs } from \"../virtual/fs.js\";\nimport { loadSkills } from \"../skills/loader.js\";\n\nexport interface UserContext {\n skills: SkillDefinition[];\n date: string;\n}\n\nexport async function buildUserContext(opts: {\n fs: VirtualFs;\n skillsPaths?: string[];\n inlineSkills?: SkillDefinition[];\n}): Promise<UserContext> {\n let skills: SkillDefinition[] = [];\n\n if (opts.skillsPaths && opts.skillsPaths.length > 0) {\n const loaded = await loadSkills(opts.fs, opts.skillsPaths);\n skills.push(...loaded);\n }\n\n if (opts.inlineSkills) {\n skills.push(...opts.inlineSkills);\n }\n\n const date = new Date().toLocaleDateString(\"en-US\", {\n weekday: \"long\",\n year: \"numeric\",\n month: \"long\",\n day: \"numeric\",\n });\n\n return { skills, date };\n}\n","import type { StreamEvent } from \"../session/types.js\";\n\nexport interface RetryConfig {\n maxRetries?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n retryableStatuses?: number[];\n fallbackModel?: string;\n /** Max consecutive overloaded (529) errors before triggering model fallback. */\n maxConsecutiveOverloaded?: number;\n onRetry?: (attempt: number, error: Error, delayMs: number) => void;\n}\n\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 10,\n baseDelayMs: 500,\n maxDelayMs: 32000,\n retryableStatuses: [408, 409, 429, 500, 502, 503, 529],\n maxConsecutiveOverloaded: 3,\n};\n\nexport interface RetryEngineOptions extends RetryConfig {\n model: string;\n thinkingBudget?: number;\n signal?: AbortSignal;\n}\n\nexport interface RetryContext {\n attempt: number;\n model: string;\n maxTokensOverride?: number;\n}\n\nexport type RetryEvent = Extract<StreamEvent, { type: \"retry_attempt\" | \"retry_exhausted\" }>;\n","import type { AIProvider, OutputFormat, ChatCompletionUsage } from \"./providers/types.js\";\nimport type { ProviderName } from \"./providers/resolve.js\";\nimport type { VirtualFs } from \"./virtual/fs.js\";\nimport type { VirtualComputer } from \"./virtual/computer.js\";\nimport { UnsandboxedLocal, type Sandbox } from \"./virtual/sandbox.js\";\nimport type { StreamEvent, RunOptions, ToolResult, ContentPart } from \"./session/types.js\";\nimport type { SkillDefinition } from \"./skills/types.js\";\nimport type { Tool, SubagentConfig, SubagentRun } from \"./tools/types.js\";\nimport type { CheckpointConfig } from \"./checkpoint/types.js\";\nimport { FileCheckpointManager } from \"./checkpoint/manager.js\";\nimport type { CacheControlConfig } from \"./providers/cache.js\";\nimport { agentTool } from \"./tools/agent.js\";\nimport { createWebSearchTool, type WebSearchConfig } from \"./tools/web-search.js\";\nimport { createToolSearchTool } from \"./tools/tool-search.js\";\nimport { taskCreateTool } from \"./tools/task-create.js\";\nimport { taskListTool } from \"./tools/task-list.js\";\nimport { taskGetTool } from \"./tools/task-get.js\";\nimport { taskUpdateTool } from \"./tools/task-update.js\";\nimport { enterPlanModeTool, exitPlanModeTool } from \"./tools/plan-mode.js\";\nimport { enterWorktreeTool, exitWorktreeTool } from \"./tools/worktree.js\";\nimport type { LspServerManager } from \"./lsp/manager.js\";\nimport type { LspServerConfig } from \"./lsp/types.js\";\nimport type { SessionInfo } from \"./session/types.js\";\nimport type { McpServerConfig } from \"./mcp/types.js\";\nimport type { TokenStorage } from \"./mcp/auth/types.js\";\nimport type { PermissionConfig } from \"./permissions/types.js\";\nimport type { HookDefinition } from \"./hooks/types.js\";\nimport type { ThinkingConfig } from \"./thinking/types.js\";\nimport type { RetryConfig } from \"./retry/types.js\";\nimport type { ModelPricing } from \"./cost/types.js\";\nimport type { TracingConfig, Tracer } from \"./tracing/types.js\";\nimport type { MemoryConfig, MemoryProvider } from \"./memory/types.js\";\nimport type { MicrocompactConfig } from \"./compact/microcompact.js\";\nimport type { ToolResultBudgetConfig } from \"./compact/tool-result-budget.js\";\nimport type { ReactiveCompactConfig } from \"./compact/reactive-compact.js\";\nimport type { FileStateCacheConfig } from \"./file-state/types.js\";\nimport type { ToolResultStorageConfig } from \"./compact/tool-result-storage.js\";\nimport type { SnipConfig } from \"./compact/history-snip.js\";\nimport { CostTracker } from \"./cost/tracker.js\";\nimport type { McpClientManager } from \"./mcp/client.js\";\nimport { SessionStorage } from \"./session/storage.js\";\nimport { TaskStore } from \"./tasks/store.js\";\nimport { Thread, type ThreadOptions } from \"./thread.js\";\nimport { createAutoCompactConfig } from \"./compact/auto-compact.js\";\nimport { buildUserContext } from \"./prompt/context.js\";\nimport { DEFAULT_RETRY_CONFIG } from \"./retry/types.js\";\nimport type { ContextFile, ProjectContextConfig } from \"./context/types.js\";\nimport { loadProjectContext } from \"./context/loader.js\";\n\nexport interface DiagnoseCheckResult {\n ok: boolean;\n latencyMs: number;\n error?: string;\n warning?: string;\n}\n\nexport interface DiagnoseResult {\n overall: boolean;\n provider: DiagnoseCheckResult & { model?: string };\n sandbox: { fs: DiagnoseCheckResult; computer: DiagnoseCheckResult };\n sandboxRuntime: DiagnoseCheckResult & { platform?: string };\n mcp: Record<string, DiagnoseCheckResult & { status?: string; toolCount?: number }>;\n lsp: Record<string, DiagnoseCheckResult & { state?: string }>;\n timestamp: string;\n}\n\nexport interface AgentOptions {\n /**\n * AI provider — either an `AIProvider` instance or a provider name string.\n * When a string is passed (e.g. `\"openai\"`), the provider is resolved\n * lazily using env-var auto-detection on the first call to `run()`,\n * `createThread()`, or `init()`.\n */\n provider: AIProvider | ProviderName;\n\n /**\n * Working directory. When set without an explicit `sandbox`, an\n * `UnsandboxedLocal({ cwd })` is created automatically.\n */\n cwd?: string;\n\n /**\n * Bundled sandbox providing both filesystem and shell execution.\n * Use `LocalSandbox()` for OS-level sandboxing (requires\n * `@anthropic-ai/sandbox-runtime`), `UnsandboxedLocal()` for raw host\n * access, `SpritesSandbox()` for isolated remote containers, or pass\n * any `{ fs: VirtualFs; computer: VirtualComputer }` for custom sandboxes.\n *\n * Defaults to `UnsandboxedLocal({ cwd })` when omitted — the library\n * default is non-sandboxed for backward compatibility. The CLI defaults\n * to `LocalSandbox()` when sandbox-runtime is available.\n */\n sandbox?: Sandbox;\n\n options?: {\n sessionDir?: string;\n skills?: SkillDefinition[];\n skillsPaths?: string[];\n tools?: Tool[];\n mcpServers?: Record<string, McpServerConfig>;\n /** Token storage for MCP OAuth flows (defaults to in-memory). */\n mcpTokenStorage?: TokenStorage;\n /** Called when an MCP server requires OAuth and the user must visit a URL. */\n mcpOnAuthorizationUrl?: (url: string) => void | Promise<void>;\n systemPrompt?: string;\n model?: string;\n maxTokens?: number;\n autoCompact?: boolean;\n autoCompactThreshold?: number;\n microcompact?: MicrocompactConfig;\n toolResultBudget?: ToolResultBudgetConfig;\n reactiveCompact?: ReactiveCompactConfig;\n cwd?: string;\n permissions?: PermissionConfig;\n hooks?: HookDefinition[];\n enableSubagents?: boolean;\n enableTasks?: boolean;\n tasksDir?: string;\n enablePlanMode?: boolean;\n enableWorktrees?: boolean;\n lsp?: Record<string, LspServerConfig>;\n streamingToolExecution?: boolean;\n webSearch?: WebSearchConfig;\n userInputHandler?: (question: string) => Promise<string>;\n thinking?: ThinkingConfig;\n retry?: RetryConfig | boolean;\n costTracking?: {\n enabled: boolean;\n pricing?: Record<string, ModelPricing>;\n };\n tracing?: TracingConfig;\n memory?: MemoryConfig;\n /** Enable ToolSearch: deferred tools are hidden until the model discovers them. */\n toolSearch?: boolean;\n /** File checkpointing: snapshot files before edits for rollback. */\n checkpoint?: CheckpointConfig;\n /** Prompt caching: enable deterministic tool ordering and cache_control injection. */\n promptCaching?: CacheControlConfig;\n /** File state cache: track reads for read-before-edit enforcement. */\n fileStateCache?: FileStateCacheConfig;\n /** Disk-backed storage for oversized tool results. */\n toolResultStorage?: ToolResultStorageConfig;\n /** History snip: enable middle-range removal from conversation history. */\n historySnip?: SnipConfig;\n /** Project context loading (NOUMEN.md / CLAUDE.md). Pass true for defaults or a config object. */\n projectContext?: ProjectContextConfig | boolean;\n /** Default structured output format for all threads. */\n outputFormat?: OutputFormat;\n /** Default structured output mode for all threads. */\n structuredOutputMode?: \"alongside_tools\" | \"final_response\";\n };\n}\n\nexport interface RunCallbacks {\n onText?: (text: string) => void;\n onThinking?: (text: string) => void;\n onToolUse?: (toolName: string, args: Record<string, unknown>) => void;\n onToolResult?: (toolName: string, result: ToolResult) => void;\n onError?: (error: Error) => void;\n onComplete?: (result: RunResult) => void;\n}\n\nexport interface RunResult {\n text: string;\n toolCalls: number;\n usage: ChatCompletionUsage;\n sessionId: string;\n}\n\nexport class Agent {\n private providerInput: AIProvider | ProviderName;\n private resolvedProvider: AIProvider | null = null;\n private fs: VirtualFs;\n private computer: VirtualComputer;\n private sessionDir: string;\n private skills: SkillDefinition[];\n private skillsPaths: string[];\n private tools: Tool[];\n private systemPrompt?: string;\n private model?: string;\n private maxTokens?: number;\n private autoCompactEnabled: boolean;\n private autoCompactThreshold?: number;\n private cwd: string;\n private storage: SessionStorage;\n private resolvedSkills: SkillDefinition[] | null = null;\n private mcpManager: McpClientManager | null = null;\n private mcpServerConfigs?: Record<string, McpServerConfig>;\n private mcpTokenStorage?: TokenStorage;\n private mcpOnAuthorizationUrl?: (url: string) => void | Promise<void>;\n private mcpTools: Tool[] = [];\n private mcpToolNames: Set<string> = new Set();\n private mcpAuthTools: Tool[] = [];\n private permissions?: PermissionConfig;\n private hooks: HookDefinition[];\n private enableSubagents: boolean;\n private enableTasks: boolean;\n private taskStore: TaskStore | null = null;\n private enablePlanMode: boolean;\n private enableWorktrees: boolean;\n private lspManager: LspServerManager | null = null;\n private lspConfigs?: Record<string, LspServerConfig>;\n private lspToolRef: Tool | null = null;\n private streamingToolExecution: boolean;\n private webSearchConfig?: WebSearchConfig;\n private userInputHandler?: (question: string) => Promise<string>;\n private thinkingConfig?: ThinkingConfig;\n private retryConfig?: RetryConfig;\n private costTracker: CostTracker | null = null;\n private tracer?: Tracer;\n private memoryProvider?: MemoryProvider;\n private memoryConfig?: MemoryConfig;\n private microcompactConfig?: MicrocompactConfig;\n private toolResultBudgetConfig?: ToolResultBudgetConfig;\n private reactiveCompactConfig?: ReactiveCompactConfig;\n private toolSearchEnabled: boolean;\n private projectContextConfig?: ProjectContextConfig;\n private resolvedProjectContext: ContextFile[] | null = null;\n private checkpointManager: FileCheckpointManager | null = null;\n private promptCachingConfig: CacheControlConfig | undefined;\n private fileStateCacheConfig: FileStateCacheConfig | undefined;\n private toolResultStorageConfig: ToolResultStorageConfig | undefined;\n private historySnipConfig: SnipConfig | undefined;\n private outputFormat: OutputFormat | undefined;\n private structuredOutputMode: \"alongside_tools\" | \"final_response\" | undefined;\n\n constructor(opts: AgentOptions) {\n this.providerInput = opts.provider;\n if (typeof opts.provider !== \"string\") {\n this.resolvedProvider = opts.provider;\n }\n\n const effectiveCwd = opts.cwd ?? opts.options?.cwd ?? process.cwd();\n const resolvedSandbox = opts.sandbox ?? UnsandboxedLocal({ cwd: effectiveCwd });\n\n this.fs = resolvedSandbox.fs;\n this.computer = resolvedSandbox.computer;\n this.sessionDir = opts.options?.sessionDir ?? \".noumen/sessions\";\n this.skills = opts.options?.skills ?? [];\n this.skillsPaths = opts.options?.skillsPaths ?? [];\n this.tools = opts.options?.tools ?? [];\n this.systemPrompt = opts.options?.systemPrompt;\n this.model = opts.options?.model;\n this.maxTokens = opts.options?.maxTokens;\n this.autoCompactEnabled = opts.options?.autoCompact ?? true;\n this.autoCompactThreshold = opts.options?.autoCompactThreshold;\n this.cwd = effectiveCwd;\n this.storage = new SessionStorage(this.fs, this.sessionDir);\n this.permissions = opts.options?.permissions;\n this.hooks = opts.options?.hooks ?? [];\n this.enableSubagents = opts.options?.enableSubagents ?? false;\n this.enableTasks = opts.options?.enableTasks ?? false;\n if (this.enableTasks) {\n const tasksDir = opts.options?.tasksDir ?? \".noumen/tasks\";\n this.taskStore = new TaskStore(this.fs, tasksDir);\n }\n this.enablePlanMode = opts.options?.enablePlanMode ?? false;\n this.enableWorktrees = opts.options?.enableWorktrees ?? false;\n if (opts.options?.lsp && Object.keys(opts.options.lsp).length > 0) {\n this.lspConfigs = opts.options.lsp;\n }\n this.streamingToolExecution = opts.options?.streamingToolExecution ?? false;\n this.webSearchConfig = opts.options?.webSearch;\n this.userInputHandler = opts.options?.userInputHandler;\n this.thinkingConfig = opts.options?.thinking;\n\n if (opts.options?.retry === true) {\n this.retryConfig = DEFAULT_RETRY_CONFIG;\n } else if (typeof opts.options?.retry === \"object\") {\n this.retryConfig = opts.options.retry;\n }\n\n if (opts.options?.costTracking?.enabled) {\n this.costTracker = new CostTracker(opts.options.costTracking.pricing);\n }\n\n if (opts.options?.mcpServers && Object.keys(opts.options.mcpServers).length > 0) {\n this.mcpServerConfigs = opts.options.mcpServers;\n this.mcpTokenStorage = opts.options.mcpTokenStorage;\n this.mcpOnAuthorizationUrl = opts.options.mcpOnAuthorizationUrl;\n }\n\n this.tracer = opts.options?.tracing?.tracer;\n\n if (opts.options?.memory) {\n this.memoryConfig = opts.options.memory;\n this.memoryProvider = opts.options.memory.provider;\n }\n\n this.microcompactConfig = opts.options?.microcompact;\n this.toolResultBudgetConfig = opts.options?.toolResultBudget;\n this.reactiveCompactConfig = opts.options?.reactiveCompact;\n this.toolSearchEnabled = opts.options?.toolSearch ?? false;\n\n if (opts.options?.projectContext === true) {\n this.projectContextConfig = { cwd: this.cwd };\n } else if (typeof opts.options?.projectContext === \"object\") {\n this.projectContextConfig = opts.options.projectContext;\n }\n\n this.promptCachingConfig = opts.options?.promptCaching;\n this.fileStateCacheConfig = opts.options?.fileStateCache;\n this.toolResultStorageConfig = opts.options?.toolResultStorage;\n this.historySnipConfig = opts.options?.historySnip;\n this.outputFormat = opts.options?.outputFormat;\n this.structuredOutputMode = opts.options?.structuredOutputMode;\n\n if (opts.options?.checkpoint?.enabled) {\n this.checkpointManager = new FileCheckpointManager(\n this.fs,\n opts.options.checkpoint,\n );\n }\n }\n\n private async ensureProvider(): Promise<AIProvider> {\n if (this.resolvedProvider) return this.resolvedProvider;\n const { resolveProvider } = await import(\"./providers/resolve.js\");\n this.resolvedProvider = await resolveProvider(this.providerInput, {\n model: this.model,\n });\n return this.resolvedProvider;\n }\n\n private getProvider(): AIProvider {\n if (!this.resolvedProvider) {\n throw new Error(\n \"Provider not yet resolved. Call init() first when using a string provider.\",\n );\n }\n return this.resolvedProvider;\n }\n\n private async getSkills(): Promise<SkillDefinition[]> {\n if (this.resolvedSkills) return this.resolvedSkills;\n\n const ctx = await buildUserContext({\n fs: this.fs,\n skillsPaths: this.skillsPaths,\n inlineSkills: this.skills,\n });\n\n this.resolvedSkills = ctx.skills;\n return this.resolvedSkills;\n }\n\n private getAllTools(): Tool[] {\n const tools = [...this.tools, ...this.mcpTools, ...this.mcpAuthTools];\n if (this.enableSubagents) {\n tools.push(agentTool);\n }\n if (this.enableTasks) {\n tools.push(taskCreateTool, taskListTool, taskGetTool, taskUpdateTool);\n }\n if (this.enablePlanMode) {\n tools.push(enterPlanModeTool, exitPlanModeTool);\n }\n if (this.enableWorktrees) {\n tools.push(enterWorktreeTool, exitWorktreeTool);\n }\n if (this.lspManager && this.lspToolRef) {\n tools.push(this.lspToolRef);\n }\n if (this.webSearchConfig) {\n tools.push(createWebSearchTool(this.webSearchConfig));\n }\n return tools;\n }\n\n private createSpawnSubagent(parentCwd: string): (config: SubagentConfig) => SubagentRun {\n return (config: SubagentConfig): SubagentRun => {\n const parentTools = this.getAllTools().filter((t) => t.name !== \"Agent\");\n const childTools = config.allowedTools\n ? parentTools.filter((t) => config.allowedTools!.includes(t.name))\n : parentTools;\n\n const childThread = new Thread(\n {\n provider: this.getProvider(),\n fs: this.fs,\n computer: this.computer,\n sessionDir: this.sessionDir,\n skills: this.resolvedSkills ?? this.skills,\n tools: childTools,\n systemPrompt: config.systemPrompt ?? this.systemPrompt,\n model: config.model ?? this.model,\n maxTokens: this.maxTokens,\n autoCompact: createAutoCompactConfig({ enabled: false }),\n permissions: config.permissionMode\n ? { mode: config.permissionMode }\n : { mode: \"bypassPermissions\" },\n hooks: this.hooks,\n taskStore: this.taskStore ?? undefined,\n lspManager: this.lspManager ?? undefined,\n thinking: this.thinkingConfig,\n retry: this.retryConfig,\n costTracker: this.costTracker ?? undefined,\n tracer: this.tracer,\n memory: this.memoryConfig,\n checkpointManager: this.checkpointManager ?? undefined,\n fileStateCacheConfig: this.fileStateCacheConfig,\n toolResultStorage: this.toolResultStorageConfig,\n historySnip: this.historySnipConfig,\n promptCachingEnabled: this.promptCachingConfig?.enabled ?? false,\n skipCacheWrite: true,\n projectContext: this.resolvedProjectContext ?? undefined,\n },\n { cwd: parentCwd },\n );\n\n return {\n sessionId: childThread.sessionId,\n events: childThread.run(config.prompt),\n };\n };\n }\n\n createThread(opts?: ThreadOptions): Thread {\n const autoCompact = createAutoCompactConfig({\n enabled: this.autoCompactEnabled,\n threshold: this.autoCompactThreshold,\n model: this.model,\n });\n\n const skills = this.resolvedSkills ?? this.skills;\n const cwd = opts?.cwd ?? this.cwd;\n\n return new Thread(\n {\n provider: this.getProvider(),\n fs: this.fs,\n computer: this.computer,\n sessionDir: this.sessionDir,\n skills,\n tools: this.getAllTools(),\n systemPrompt: this.systemPrompt,\n model: this.model,\n maxTokens: this.maxTokens,\n autoCompact,\n microcompact: this.microcompactConfig,\n toolResultBudget: this.toolResultBudgetConfig,\n reactiveCompact: this.reactiveCompactConfig,\n permissions: opts?.permissionHandler\n ? { ...this.permissions, handler: opts.permissionHandler }\n : this.permissions,\n hooks: this.hooks,\n spawnSubagent: this.enableSubagents\n ? this.createSpawnSubagent(cwd)\n : undefined,\n streamingToolExecution: this.streamingToolExecution,\n userInputHandler: opts?.userInputHandler ?? this.userInputHandler,\n taskStore: this.taskStore ?? undefined,\n lspManager: this.lspManager ?? undefined,\n thinking: this.thinkingConfig,\n retry: this.retryConfig,\n costTracker: this.costTracker ?? undefined,\n tracer: this.tracer,\n memory: this.memoryConfig,\n toolSearchEnabled: this.toolSearchEnabled,\n checkpointManager: this.checkpointManager ?? undefined,\n fileStateCacheConfig: this.fileStateCacheConfig,\n toolResultStorage: this.toolResultStorageConfig,\n historySnip: this.historySnipConfig,\n promptCachingEnabled: this.promptCachingConfig?.enabled ?? false,\n mcpToolNames: this.mcpToolNames.size > 0 ? this.mcpToolNames : undefined,\n projectContext: this.resolvedProjectContext ?? undefined,\n outputFormat: this.outputFormat,\n structuredOutputMode: this.structuredOutputMode,\n },\n {\n ...opts,\n cwd,\n },\n );\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n return this.storage.listSessions();\n }\n\n getCostSummary(): import(\"./cost/types.js\").CostSummary | null {\n return this.costTracker?.getSummary() ?? null;\n }\n\n /**\n * Create a thread that resumes an existing session. Automatically restores\n * messages (respecting compact boundaries), file checkpoint state, and\n * cost tracking state from the persisted JSONL transcript.\n */\n resumeThread(sessionId: string, opts?: Omit<ThreadOptions, \"sessionId\" | \"resume\">): Thread {\n return this.createThread({\n ...opts,\n sessionId,\n resume: true,\n });\n }\n\n /**\n * One-shot streaming: creates an ephemeral thread and yields events.\n * Auto-resolves string providers on first call (no need to call `init()`).\n *\n * ```ts\n * for await (const event of agent.run(\"Fix the bug\")) {\n * if (event.type === \"text_delta\") process.stdout.write(event.text);\n * }\n * ```\n */\n async *run(\n prompt: string | ContentPart[],\n opts?: RunOptions & ThreadOptions,\n ): AsyncGenerator<StreamEvent, void, unknown> {\n await this.ensureProvider();\n const thread = this.createThread(opts);\n yield* thread.run(prompt, opts);\n }\n\n /**\n * One-shot execution: runs the prompt to completion and returns a result\n * summary. Optional callbacks fire as events arrive.\n *\n * ```ts\n * const result = await agent.execute(\"Fix the bug\", {\n * onText: (text) => process.stdout.write(text),\n * });\n * console.log(`Done — ${result.toolCalls} tool calls`);\n * ```\n */\n async execute(\n prompt: string | ContentPart[],\n opts?: RunOptions & ThreadOptions & RunCallbacks,\n ): Promise<RunResult> {\n await this.ensureProvider();\n const thread = this.createThread(opts);\n let text = \"\";\n let toolCalls = 0;\n let lastUsage: ChatCompletionUsage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };\n\n for await (const event of thread.run(prompt, opts)) {\n switch (event.type) {\n case \"text_delta\":\n text += event.text;\n opts?.onText?.(event.text);\n break;\n case \"thinking_delta\":\n opts?.onThinking?.(event.text);\n break;\n case \"tool_use_start\":\n toolCalls++;\n opts?.onToolUse?.(event.toolName, {});\n break;\n case \"tool_result\":\n opts?.onToolResult?.(event.toolName, event.result);\n break;\n case \"error\":\n opts?.onError?.(event.error);\n break;\n case \"turn_complete\":\n lastUsage = event.usage;\n break;\n }\n }\n\n const result: RunResult = {\n text,\n toolCalls,\n usage: lastUsage,\n sessionId: thread.sessionId,\n };\n\n opts?.onComplete?.(result);\n return result;\n }\n\n /**\n * Pre-resolve the provider (if string), skills, MCP servers, and LSP servers.\n * Call this once after construction if using a string provider, skillsPaths,\n * mcpServers, or lsp, so that createThread() has everything available synchronously.\n */\n async init(): Promise<void> {\n const tasks: Promise<void>[] = [\n this.ensureProvider().then(() => {}),\n this.getSkills().then(() => {}),\n ];\n\n if (this.projectContextConfig && !this.resolvedProjectContext) {\n tasks.push(\n loadProjectContext(this.fs, this.projectContextConfig).then((files) => {\n this.resolvedProjectContext = files;\n }),\n );\n }\n\n if (this.mcpServerConfigs && !this.mcpManager) {\n tasks.push(\n (async () => {\n const { McpClientManager: McpMgr } = await import(\"./mcp/client.js\");\n this.mcpManager = new McpMgr(this.mcpServerConfigs!, {\n tokenStorage: this.mcpTokenStorage,\n onAuthorizationUrl: this.mcpOnAuthorizationUrl,\n });\n await this.mcpManager.connect();\n this.mcpTools = await this.mcpManager.getTools();\n this.mcpToolNames = new Set(this.mcpTools.map((t) => t.name));\n\n const needsAuth = this.mcpManager.getServersNeedingAuth();\n if (needsAuth.length > 0) {\n const { createMcpAuthTool } = await import(\"./tools/mcp-auth.js\");\n this.mcpAuthTools = needsAuth.map((name) =>\n createMcpAuthTool(name, this.mcpManager!),\n );\n }\n })(),\n );\n }\n\n if (this.lspConfigs && !this.lspManager) {\n tasks.push(\n (async () => {\n const { LspServerManager } = await import(\"./lsp/manager.js\");\n const { lspTool } = await import(\"./tools/lsp.js\");\n const rootUri = `file://${this.cwd}`;\n this.lspManager = new LspServerManager(this.lspConfigs!, rootUri);\n this.lspToolRef = lspTool;\n })(),\n );\n }\n\n await Promise.all(tasks);\n }\n\n /**\n * Run health checks on the provider, sandbox, MCP servers, and LSP servers.\n * Returns a structured report — useful for debugging integration issues.\n *\n * @param timeoutMs Per-check timeout in milliseconds (default 10 000).\n */\n async diagnose(timeoutMs = 10_000): Promise<DiagnoseResult> {\n const timedCheck = async <T>(\n fn: () => Promise<T>,\n ): Promise<{ value: T; latencyMs: number }> => {\n const start = performance.now();\n const value = await Promise.race([\n fn(),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs),\n ),\n ]);\n return { value, latencyMs: Math.round(performance.now() - start) };\n };\n\n const fail = (err: unknown): string =>\n err instanceof Error ? err.message : String(err);\n\n // --- Provider ----------------------------------------------------------\n let providerCheck: DiagnoseResult[\"provider\"];\n try {\n const { latencyMs } = await timedCheck(async () => {\n const stream = this.getProvider().chat({\n model: this.model ?? \"gpt-4o-mini\",\n messages: [{ role: \"user\", content: \"Say ok\" }],\n tools: [],\n system: \"\",\n });\n for await (const _ of stream) { break; }\n });\n providerCheck = { ok: true, latencyMs, model: this.model };\n } catch (err) {\n providerCheck = { ok: false, latencyMs: 0, error: fail(err), model: this.model };\n }\n\n // --- Sandbox FS --------------------------------------------------------\n let fsCheck: DiagnoseCheckResult;\n try {\n const { latencyMs } = await timedCheck(async () => this.fs.exists(\"/\"));\n fsCheck = { ok: true, latencyMs };\n } catch (err) {\n fsCheck = { ok: false, latencyMs: 0, error: fail(err) };\n }\n\n // --- Sandbox Computer --------------------------------------------------\n let computerCheck: DiagnoseCheckResult;\n try {\n const { value: cmd, latencyMs } = await timedCheck(\n async () => this.computer.executeCommand(\"echo ok\"),\n );\n if (cmd.exitCode === 0) {\n computerCheck = { ok: true, latencyMs };\n } else {\n computerCheck = { ok: false, latencyMs, warning: \"Shell returned non-zero\" };\n }\n } catch (err) {\n computerCheck = { ok: false, latencyMs: 0, error: fail(err) };\n }\n\n // --- Sandbox Runtime (OS-level sandboxing) ------------------------------\n let sandboxRuntimeCheck: DiagnoseResult[\"sandboxRuntime\"];\n {\n const { SandboxManager } = await import(\"@anthropic-ai/sandbox-runtime\");\n const supported = SandboxManager.isSupportedPlatform();\n const deps = SandboxManager.checkDependencies();\n const hasErrors = deps.errors.length > 0;\n if (supported && !hasErrors) {\n sandboxRuntimeCheck = {\n ok: true,\n latencyMs: 0,\n platform: process.platform,\n ...(deps.warnings.length > 0 && { warning: deps.warnings.join(\"; \") }),\n };\n } else {\n const reasons: string[] = [];\n if (!supported) reasons.push(`platform ${process.platform} not supported`);\n reasons.push(...deps.errors);\n sandboxRuntimeCheck = {\n ok: false,\n latencyMs: 0,\n warning: reasons.join(\"; \"),\n platform: process.platform,\n };\n }\n }\n\n // --- MCP servers -------------------------------------------------------\n const mcpResults: DiagnoseResult[\"mcp\"] = {};\n if (this.mcpManager) {\n const statuses = this.mcpManager.getConnectionStatus();\n for (const s of statuses) {\n const ok = s.status === \"connected\";\n mcpResults[s.name] = {\n ok,\n latencyMs: 0,\n status: s.status,\n toolCount: s.toolCount,\n ...(!ok && s.status === \"needs-auth\"\n ? { warning: \"Requires OAuth authentication\" }\n : {}),\n ...(!ok && s.status === \"failed\"\n ? { error: \"Connection failed\" }\n : {}),\n };\n }\n }\n\n // --- LSP servers -------------------------------------------------------\n const lspResults: DiagnoseResult[\"lsp\"] = {};\n if (this.lspManager) {\n for (const s of this.lspManager.getServerStatus()) {\n lspResults[s.name] = {\n ok: s.state === \"running\",\n latencyMs: 0,\n state: s.state,\n ...(s.state !== \"running\" && s.state !== \"idle\"\n ? { warning: `Server state: ${s.state}` }\n : {}),\n };\n }\n }\n\n const overall = providerCheck.ok && fsCheck.ok && computerCheck.ok;\n\n return {\n overall,\n provider: providerCheck,\n sandbox: { fs: fsCheck, computer: computerCheck },\n sandboxRuntime: sandboxRuntimeCheck,\n mcp: mcpResults,\n lsp: lspResults,\n timestamp: new Date().toISOString(),\n };\n }\n\n /**\n * Disconnect all MCP clients. Call when done with this Agent instance.\n */\n async close(): Promise<void> {\n const tasks: Promise<void>[] = [];\n if (this.mcpManager) {\n tasks.push(\n this.mcpManager.close().then(() => {\n this.mcpTools = [];\n this.mcpAuthTools = [];\n }),\n );\n }\n if (this.lspManager) {\n tasks.push(this.lspManager.shutdown());\n }\n await Promise.all(tasks);\n }\n}\n","import { Agent } from \"./agent.js\";\nimport type { AIProvider } from \"./providers/types.js\";\nimport { UnsandboxedLocal, type Sandbox } from \"./virtual/sandbox.js\";\nimport type { HookDefinition } from \"./hooks/types.js\";\nimport type { McpServerConfig } from \"./mcp/types.js\";\n\nexport interface PresetOptions {\n /** The AI provider instance (e.g. `new OpenAIProvider({ apiKey })`) */\n provider: AIProvider;\n /** Working directory for the sandbox. Defaults to `process.cwd()`. */\n cwd?: string;\n /** Model name override. Each preset has a sensible default. */\n model?: string;\n /** Custom sandbox. Defaults to `UnsandboxedLocal({ cwd })`. */\n sandbox?: Sandbox;\n /** Extra hooks to attach. */\n hooks?: HookDefinition[];\n /** MCP servers to connect to during `init()`. */\n mcpServers?: Record<string, McpServerConfig>;\n /** Custom system prompt prepended to the built-in prompt. */\n systemPrompt?: string;\n}\n\n/**\n * Full-featured coding agent with subagents, tasks, plan mode, auto-compact,\n * retry, cost tracking, and project context enabled out of the box.\n */\nexport function codingAgent(opts: PresetOptions): Agent {\n const cwd = opts.cwd ?? process.cwd();\n return new Agent({\n provider: opts.provider,\n sandbox: opts.sandbox ?? UnsandboxedLocal({ cwd }),\n options: {\n cwd,\n model: opts.model,\n systemPrompt: opts.systemPrompt,\n permissions: { mode: \"default\" },\n autoCompact: true,\n enableSubagents: true,\n enableTasks: true,\n enablePlanMode: true,\n projectContext: { cwd },\n costTracking: { enabled: true },\n retry: true,\n hooks: opts.hooks,\n mcpServers: opts.mcpServers,\n },\n });\n}\n\n/**\n * Read-only planning agent — can explore the codebase but cannot make changes.\n * Useful for architecture analysis, code review prep, or scoping work.\n */\nexport function planningAgent(opts: PresetOptions): Agent {\n const cwd = opts.cwd ?? process.cwd();\n return new Agent({\n provider: opts.provider,\n sandbox: opts.sandbox ?? UnsandboxedLocal({ cwd }),\n options: {\n cwd,\n model: opts.model,\n systemPrompt: opts.systemPrompt,\n permissions: { mode: \"plan\" },\n autoCompact: true,\n enableSubagents: false,\n enableTasks: false,\n enablePlanMode: true,\n projectContext: { cwd },\n costTracking: { enabled: true },\n retry: true,\n hooks: opts.hooks,\n mcpServers: opts.mcpServers,\n },\n });\n}\n\n/**\n * Code review agent — read-only with web search enabled for looking up\n * documentation, best practices, and security advisories.\n */\nexport function reviewAgent(opts: PresetOptions): Agent {\n const cwd = opts.cwd ?? process.cwd();\n return new Agent({\n provider: opts.provider,\n sandbox: opts.sandbox ?? UnsandboxedLocal({ cwd }),\n options: {\n cwd,\n model: opts.model,\n systemPrompt: opts.systemPrompt,\n permissions: { mode: \"plan\" },\n autoCompact: true,\n enableSubagents: false,\n enableTasks: false,\n enablePlanMode: true,\n projectContext: { cwd },\n costTracking: { enabled: true },\n retry: true,\n hooks: opts.hooks,\n mcpServers: opts.mcpServers,\n webSearch: {\n search: async (query: string) => {\n try {\n const res = await fetch(`https://html.duckduckgo.com/html/?q=${encodeURIComponent(query)}`);\n if (!res.ok) return [];\n return [{ title: query, url: res.url, snippet: `Search results for: ${query}` }];\n } catch { return []; }\n },\n },\n },\n });\n}\n","import type { ChatMessage } from \"../session/types.js\";\nimport type { ThinkingConfig } from \"../thinking/types.js\";\n\nexport interface ToolParameterProperty {\n type: string;\n description?: string;\n enum?: string[];\n default?: unknown;\n minimum?: number;\n maximum?: number;\n}\n\nexport interface ToolDefinition {\n type: \"function\";\n function: {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, ToolParameterProperty>;\n required?: string[];\n };\n };\n}\n\n// Streaming chunk types (OpenAI-compatible)\n\nexport interface ChatStreamDelta {\n role?: \"assistant\";\n content?: string | null;\n thinking_content?: string | null;\n thinking_signature?: string | null;\n tool_calls?: Array<{\n index: number;\n id?: string;\n type?: \"function\";\n function?: {\n name?: string;\n arguments?: string;\n };\n }>;\n}\n\nexport interface ChatStreamChoice {\n index: number;\n delta: ChatStreamDelta;\n finish_reason: string | null;\n}\n\nexport interface ChatStreamChunk {\n id: string;\n choices: ChatStreamChoice[];\n model: string;\n usage?: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n cache_read_tokens?: number;\n cache_creation_tokens?: number;\n thinking_tokens?: number;\n };\n}\n\nexport interface ChatCompletionUsage {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n cache_read_tokens?: number;\n cache_creation_tokens?: number;\n thinking_tokens?: number;\n}\n\n/**\n * Structured output format. When provided, the model is constrained to\n * produce a response matching the given JSON schema.\n *\n * - `json_schema`: the model must produce JSON conforming to the given schema.\n * - `json_object`: the model must produce valid JSON (no specific schema).\n */\nexport type OutputFormat = JsonSchemaOutputFormat | JsonObjectOutputFormat;\n\nexport interface JsonSchemaOutputFormat {\n type: \"json_schema\";\n /** JSON Schema object describing the expected output shape. */\n schema: Record<string, unknown>;\n /** Optional name for the schema (required by some providers). */\n name?: string;\n /** When true, the provider enforces strict schema adherence. */\n strict?: boolean;\n}\n\nexport interface JsonObjectOutputFormat {\n type: \"json_object\";\n}\n\nexport interface ChatParams {\n model: string;\n messages: ChatMessage[];\n tools?: ToolDefinition[];\n max_tokens?: number;\n system?: string;\n temperature?: number;\n thinking?: ThinkingConfig;\n /** Constrain the model to produce structured output matching this schema. */\n outputFormat?: OutputFormat;\n /**\n * When true, the provider should place the cache breakpoint on the\n * second-to-last message instead of the last. Used by subagent forks\n * to avoid writing fork-only tails into the shared prompt cache.\n */\n skipCacheWrite?: boolean;\n}\n\nexport interface AIProvider {\n chat(params: ChatParams): AsyncIterable<ChatStreamChunk>;\n}\n\n/**\n * Extended error type that providers can throw to convey retry-relevant metadata.\n * Consumers (like the retry engine) can inspect these fields without knowing\n * provider-specific SDK error types.\n */\nexport class ChatStreamError extends Error {\n status?: number;\n retryAfter?: string;\n\n constructor(\n message: string,\n opts?: { status?: number; retryAfter?: string; cause?: unknown },\n ) {\n super(message, { cause: opts?.cause });\n this.name = \"ChatStreamError\";\n this.status = opts?.status;\n this.retryAfter = opts?.retryAfter;\n }\n}\n","import type { SwarmMessage } from \"./types.js\";\n\n/**\n * In-memory message queue for communication between swarm members.\n */\nexport class Mailbox {\n private messages: SwarmMessage[] = [];\n private listeners = new Map<string, Array<(msg: SwarmMessage) => void>>();\n\n /**\n * Send a message from one member to another.\n */\n send(from: string, to: string, content: string): void {\n const msg: SwarmMessage = {\n from,\n to,\n content,\n timestamp: new Date().toISOString(),\n };\n this.messages.push(msg);\n\n const handlers = this.listeners.get(to);\n if (handlers) {\n for (const handler of handlers) {\n handler(msg);\n }\n }\n }\n\n /**\n * Broadcast a message to all members except the sender.\n */\n broadcast(from: string, content: string, memberNames: string[]): void {\n for (const name of memberNames) {\n if (name !== from) {\n this.send(from, name, content);\n }\n }\n }\n\n /**\n * Get all messages sent to a specific member.\n */\n getMessagesFor(memberName: string): SwarmMessage[] {\n return this.messages.filter((m) => m.to === memberName);\n }\n\n /**\n * Get all unread messages for a member since the last check.\n */\n getNewMessagesFor(memberName: string, since: string): SwarmMessage[] {\n return this.messages.filter(\n (m) => m.to === memberName && m.timestamp > since,\n );\n }\n\n /**\n * Register a listener for incoming messages to a member.\n */\n onMessage(\n memberName: string,\n handler: (msg: SwarmMessage) => void,\n ): () => void {\n const existing = this.listeners.get(memberName) ?? [];\n existing.push(handler);\n this.listeners.set(memberName, existing);\n\n return () => {\n const handlers = this.listeners.get(memberName);\n if (handlers) {\n const idx = handlers.indexOf(handler);\n if (idx !== -1) handlers.splice(idx, 1);\n }\n };\n }\n\n /**\n * Get all messages in the mailbox.\n */\n getAllMessages(): SwarmMessage[] {\n return [...this.messages];\n }\n}\n","import type {\n SwarmConfig,\n SwarmMember,\n SwarmMemberConfig,\n SwarmMemberStatus,\n SwarmStatus,\n SwarmEvents,\n} from \"./types.js\";\nimport type { SwarmBackend } from \"./backends/types.js\";\nimport type { StreamEvent } from \"../session/types.js\";\nimport { Mailbox } from \"./mailbox.js\";\nimport { generateUUID } from \"../utils/uuid.js\";\n\n/**\n * Orchestrates multiple agent threads running in parallel.\n */\nexport class SwarmManager {\n private members = new Map<string, SwarmMember>();\n private backend: SwarmBackend;\n private mailbox = new Mailbox();\n private config: SwarmConfig;\n private runningTasks = new Map<string, Promise<void>>();\n private eventHandlers: Array<(event: SwarmEvents) => void> = [];\n\n constructor(backend: SwarmBackend, config?: SwarmConfig) {\n this.backend = backend;\n this.config = config ?? {};\n }\n\n /**\n * Register a handler for swarm lifecycle events.\n */\n onEvent(handler: (event: SwarmEvents) => void): () => void {\n this.eventHandlers.push(handler);\n return () => {\n const idx = this.eventHandlers.indexOf(handler);\n if (idx !== -1) this.eventHandlers.splice(idx, 1);\n };\n }\n\n private emit(event: SwarmEvents): void {\n for (const handler of this.eventHandlers) {\n handler(event);\n }\n }\n\n /**\n * Spawn a new swarm member. Returns the member ID.\n */\n async spawn(config: SwarmMemberConfig): Promise<string> {\n const id = generateUUID();\n const member: SwarmMember = {\n id,\n name: config.name,\n status: \"pending\",\n };\n this.members.set(id, member);\n\n const maxConcurrent = this.config.maxConcurrent ?? 4;\n const running = Array.from(this.members.values()).filter(\n (m) => m.status === \"running\",\n ).length;\n\n if (running >= maxConcurrent) {\n // Wait for a slot\n await this.waitForSlot(maxConcurrent);\n }\n\n member.status = \"running\";\n this.emit({\n type: \"swarm_member_start\",\n memberId: id,\n memberName: config.name,\n });\n\n const task = this.runMember(config, member);\n this.runningTasks.set(id, task);\n\n return id;\n }\n\n private async runMember(\n config: SwarmMemberConfig,\n member: SwarmMember,\n ): Promise<void> {\n try {\n const gen = this.backend.spawn(config, member);\n let next = await gen.next();\n while (!next.done) {\n next = await gen.next();\n }\n member.result = next.value;\n member.status = \"completed\";\n this.emit({\n type: \"swarm_member_complete\",\n memberId: member.id,\n memberName: member.name,\n content: member.result,\n });\n } catch (err) {\n member.error = err instanceof Error ? err : new Error(String(err));\n member.status = \"failed\";\n this.emit({\n type: \"swarm_member_failed\",\n memberId: member.id,\n memberName: member.name,\n error: member.error,\n });\n } finally {\n this.runningTasks.delete(member.id);\n }\n }\n\n /**\n * Spawn multiple members concurrently. Returns their IDs.\n */\n async spawnAll(configs: SwarmMemberConfig[]): Promise<string[]> {\n const ids: string[] = [];\n for (const config of configs) {\n ids.push(await this.spawn(config));\n }\n return ids;\n }\n\n /**\n * Send a message between swarm members.\n */\n sendMessage(from: string, to: string, content: string): void {\n this.mailbox.send(from, to, content);\n this.emit({\n type: \"swarm_message\",\n memberId: to,\n memberName: this.getMemberName(to),\n content,\n });\n }\n\n /**\n * Kill a running member.\n */\n async kill(memberId: string): Promise<void> {\n const member = this.members.get(memberId);\n if (!member || member.status !== \"running\") return;\n\n await this.backend.kill(memberId);\n member.status = \"killed\";\n this.runningTasks.delete(memberId);\n }\n\n /**\n * Wait for all running members to complete.\n */\n async waitForAll(): Promise<void> {\n while (this.runningTasks.size > 0) {\n await Promise.race(this.runningTasks.values());\n }\n }\n\n /**\n * Get current swarm status.\n */\n getStatus(): SwarmStatus {\n return {\n members: Array.from(this.members.values()),\n messages: this.mailbox.getAllMessages(),\n };\n }\n\n /**\n * Get a specific member.\n */\n getMember(id: string): SwarmMember | undefined {\n return this.members.get(id);\n }\n\n /**\n * Get the mailbox for direct access.\n */\n getMailbox(): Mailbox {\n return this.mailbox;\n }\n\n private getMemberName(id: string): string {\n return this.members.get(id)?.name ?? id;\n }\n\n private async waitForSlot(maxConcurrent: number): Promise<void> {\n while (true) {\n const running = Array.from(this.members.values()).filter(\n (m) => m.status === \"running\",\n ).length;\n if (running < maxConcurrent) return;\n if (this.runningTasks.size > 0) {\n await Promise.race(this.runningTasks.values());\n } else {\n break;\n }\n }\n }\n}\n","import type { SwarmBackend } from \"./types.js\";\nimport type { SwarmMember, SwarmMemberConfig } from \"../types.js\";\nimport type { StreamEvent } from \"../../session/types.js\";\nimport type { ThreadConfig } from \"../../thread.js\";\nimport { Thread } from \"../../thread.js\";\n\n/**\n * In-process backend: runs each swarm member as a concurrent Thread.\n */\nexport class InProcessBackend implements SwarmBackend {\n private threadConfig: Omit<ThreadConfig, \"systemPrompt\" | \"model\">;\n private abortControllers = new Map<string, AbortController>();\n\n constructor(threadConfig: Omit<ThreadConfig, \"systemPrompt\" | \"model\">) {\n this.threadConfig = threadConfig;\n }\n\n async *spawn(\n config: SwarmMemberConfig,\n member: SwarmMember,\n ): AsyncGenerator<StreamEvent, string, unknown> {\n const ac = new AbortController();\n this.abortControllers.set(member.id, ac);\n\n const childTools = config.allowedTools\n ? (this.threadConfig.tools ?? []).filter((t) =>\n config.allowedTools!.includes(t.name),\n )\n : this.threadConfig.tools;\n\n const thread = new Thread(\n {\n ...this.threadConfig,\n tools: childTools,\n systemPrompt: config.systemPrompt,\n model: config.model,\n },\n { cwd: (this.threadConfig as { cwd?: string }).cwd },\n );\n\n member.sessionId = thread.sessionId;\n let resultText = \"\";\n\n for await (const event of thread.run(config.prompt, {\n signal: ac.signal,\n })) {\n yield event;\n\n if (event.type === \"message_complete\" && event.message.content) {\n resultText += event.message.content;\n }\n }\n\n this.abortControllers.delete(member.id);\n return resultText;\n }\n\n async kill(memberId: string): Promise<void> {\n const ac = this.abortControllers.get(memberId);\n if (ac) {\n ac.abort();\n this.abortControllers.delete(memberId);\n }\n }\n}\n","import type { PermissionContext, PermissionUpdate } from \"./types.js\";\n\n/**\n * Apply a permission update to an in-memory context.\n * Returns the mutated context (same reference).\n */\nexport function applyPermissionUpdate(\n ctx: PermissionContext,\n update: PermissionUpdate,\n): PermissionContext {\n switch (update.type) {\n case \"addRules\":\n ctx.rules.push(...update.rules);\n break;\n\n case \"removeRules\":\n ctx.rules = ctx.rules.filter((r) => {\n if (r.toolName !== update.toolName) return true;\n if (update.behavior && r.behavior !== update.behavior) return true;\n return false;\n });\n break;\n\n case \"setMode\":\n ctx.mode = update.mode;\n break;\n\n case \"addDirectories\":\n for (const dir of update.directories) {\n if (!ctx.workingDirectories.includes(dir)) {\n ctx.workingDirectories.push(dir);\n }\n }\n break;\n\n case \"removeDirectories\":\n ctx.workingDirectories = ctx.workingDirectories.filter(\n (d) => !update.directories.includes(d),\n );\n break;\n }\n\n return ctx;\n}\n\n/**\n * Apply multiple permission updates in order.\n */\nexport function applyPermissionUpdates(\n ctx: PermissionContext,\n updates: PermissionUpdate[],\n): PermissionContext {\n for (const update of updates) {\n applyPermissionUpdate(ctx, update);\n }\n return ctx;\n}\n","import {\n SpanStatusCode,\n type Span,\n type SpanAttributeValue,\n type SpanOptions,\n type Tracer,\n} from \"./types.js\";\nimport { NoopSpan, NoopTracer } from \"./noop.js\";\n\ntype OTelApi = typeof import(\"@opentelemetry/api\");\n\nlet otelApi: OTelApi | null = null;\nlet otelLoadFailed = false;\n\nasync function loadOTelApi(): Promise<OTelApi | null> {\n if (otelApi) return otelApi;\n if (otelLoadFailed) return null;\n try {\n otelApi = await import(\"@opentelemetry/api\");\n return otelApi;\n } catch {\n otelLoadFailed = true;\n return null;\n }\n}\n\nclass OTelSpan implements Span {\n readonly name: string;\n private inner: import(\"@opentelemetry/api\").Span;\n\n constructor(name: string, inner: import(\"@opentelemetry/api\").Span) {\n this.name = name;\n this.inner = inner;\n }\n\n setAttribute(key: string, value: SpanAttributeValue): void {\n this.inner.setAttribute(key, value);\n }\n\n addEvent(name: string, attributes?: Record<string, SpanAttributeValue>): void {\n this.inner.addEvent(name, attributes);\n }\n\n setStatus(code: SpanStatusCode, message?: string): void {\n const otelCode = code === SpanStatusCode.ERROR\n ? 2 /* SpanStatusCode.ERROR in OTEL */\n : 1 /* SpanStatusCode.OK in OTEL */;\n this.inner.setStatus({ code: otelCode, message });\n }\n\n end(): void {\n this.inner.end();\n }\n\n /** Access the underlying OTEL span for advanced use cases. */\n getInnerSpan(): import(\"@opentelemetry/api\").Span {\n return this.inner;\n }\n}\n\n/**\n * Adapter that bridges noumen's `Tracer` interface to an OpenTelemetry\n * `TracerProvider`. The `@opentelemetry/api` package is loaded lazily via\n * dynamic `import()` so it remains an optional peer dependency.\n *\n * Call `OTelTracer.create()` (async factory) to obtain an instance.\n * If `@opentelemetry/api` is not installed, the factory returns a `NoopTracer`.\n */\nexport class OTelTracer implements Tracer {\n private otelTracer: import(\"@opentelemetry/api\").Tracer;\n private api: OTelApi;\n\n private constructor(api: OTelApi, otelTracer: import(\"@opentelemetry/api\").Tracer) {\n this.api = api;\n this.otelTracer = otelTracer;\n }\n\n /**\n * Create an `OTelTracer`. Falls back to `NoopTracer` if\n * `@opentelemetry/api` is not available at runtime.\n */\n static async create(\n serviceName: string = \"noumen\",\n version?: string,\n ): Promise<Tracer> {\n const api = await loadOTelApi();\n if (!api) return new NoopTracer();\n const tracer = api.trace.getTracer(serviceName, version);\n return new OTelTracer(api, tracer);\n }\n\n startSpan(name: string, options?: SpanOptions): Span {\n const parentCtx = options?.parent instanceof OTelSpan\n ? this.api.trace.setSpan(this.api.context.active(), options.parent.getInnerSpan())\n : this.api.context.active();\n\n const otelSpan = this.otelTracer.startSpan(\n name,\n options?.attributes ? { attributes: options.attributes as Record<string, import(\"@opentelemetry/api\").AttributeValue> } : undefined,\n parentCtx,\n );\n\n return new OTelSpan(name, otelSpan);\n }\n}\n","import type { VirtualFs } from \"../virtual/fs.js\";\nimport type { MemoryEntry, MemoryProvider, MemoryType } from \"./types.js\";\n\nconst INDEX_NAME = \"MEMORY.md\";\nconst DEFAULT_MAX_LINES = 200;\nconst DEFAULT_MAX_BYTES = 25_000;\n\nconst MEMORY_TYPES: ReadonlySet<string> = new Set([\n \"user\",\n \"project\",\n \"feedback\",\n \"reference\",\n]);\n\n// ---------------------------------------------------------------------------\n// Frontmatter helpers\n// ---------------------------------------------------------------------------\n\ninterface ParsedFrontmatter {\n name?: string;\n description?: string;\n type?: MemoryType;\n rest: string;\n}\n\nfunction parseFrontmatter(raw: string): ParsedFrontmatter {\n const trimmed = raw.trimStart();\n if (!trimmed.startsWith(\"---\")) {\n return { rest: raw };\n }\n\n const endIdx = trimmed.indexOf(\"---\", 3);\n if (endIdx === -1) {\n return { rest: raw };\n }\n\n const fmBlock = trimmed.slice(3, endIdx).trim();\n const rest = trimmed.slice(endIdx + 3).trim();\n\n let name: string | undefined;\n let description: string | undefined;\n let type: MemoryType | undefined;\n\n for (const line of fmBlock.split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx === -1) continue;\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n if (key === \"name\") name = value;\n else if (key === \"description\") description = value;\n else if (key === \"type\" && MEMORY_TYPES.has(value)) type = value as MemoryType;\n }\n\n return { name, description, type, rest };\n}\n\nfunction serializeEntry(entry: MemoryEntry): string {\n const lines = [\n \"---\",\n `name: ${entry.name}`,\n `description: ${entry.description}`,\n `type: ${entry.type}`,\n \"---\",\n \"\",\n entry.content,\n ];\n return lines.join(\"\\n\");\n}\n\nfunction slugify(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\")\n .slice(0, 60);\n}\n\n// ---------------------------------------------------------------------------\n// Index truncation (ported from claude-code's truncateEntrypointContent)\n// ---------------------------------------------------------------------------\n\nexport interface IndexTruncation {\n content: string;\n lineCount: number;\n byteCount: number;\n wasLineTruncated: boolean;\n wasByteTruncated: boolean;\n}\n\nexport function truncateIndex(\n raw: string,\n maxLines = DEFAULT_MAX_LINES,\n maxBytes = DEFAULT_MAX_BYTES,\n): IndexTruncation {\n const trimmed = raw.trim();\n const contentLines = trimmed.split(\"\\n\");\n const lineCount = contentLines.length;\n const byteCount = trimmed.length;\n\n const wasLineTruncated = lineCount > maxLines;\n const wasByteTruncated = byteCount > maxBytes;\n\n if (!wasLineTruncated && !wasByteTruncated) {\n return { content: trimmed, lineCount, byteCount, wasLineTruncated, wasByteTruncated };\n }\n\n let truncated = wasLineTruncated\n ? contentLines.slice(0, maxLines).join(\"\\n\")\n : trimmed;\n\n if (truncated.length > maxBytes) {\n const cutAt = truncated.lastIndexOf(\"\\n\", maxBytes);\n truncated = truncated.slice(0, cutAt > 0 ? cutAt : maxBytes);\n }\n\n const reason = wasByteTruncated && !wasLineTruncated\n ? `${byteCount} bytes (limit: ${maxBytes})`\n : wasLineTruncated && !wasByteTruncated\n ? `${lineCount} lines (limit: ${maxLines})`\n : `${lineCount} lines and ${byteCount} bytes`;\n\n return {\n content:\n truncated +\n `\\n\\n> WARNING: ${INDEX_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`,\n lineCount,\n byteCount,\n wasLineTruncated,\n wasByteTruncated,\n };\n}\n\n// ---------------------------------------------------------------------------\n// FileMemoryProvider\n// ---------------------------------------------------------------------------\n\n/**\n * Default `MemoryProvider` that stores memories as individual `.md` files\n * with YAML frontmatter, plus a `MEMORY.md` index. All I/O goes through\n * `VirtualFs` so it works with any sandbox backend.\n */\nexport class FileMemoryProvider implements MemoryProvider {\n private fs: VirtualFs;\n private dir: string;\n private maxIndexLines: number;\n\n constructor(fs: VirtualFs, memoryDir: string, maxIndexLines = DEFAULT_MAX_LINES) {\n this.fs = fs;\n this.dir = memoryDir.endsWith(\"/\") ? memoryDir : memoryDir + \"/\";\n this.maxIndexLines = maxIndexLines;\n }\n\n private indexPath(): string {\n return this.dir + INDEX_NAME;\n }\n\n private async ensureDir(): Promise<void> {\n const exists = await this.fs.exists(this.dir);\n if (!exists) {\n await this.fs.mkdir(this.dir, { recursive: true });\n }\n }\n\n async loadIndex(): Promise<string> {\n try {\n const raw = await this.fs.readFile(this.indexPath());\n return truncateIndex(raw, this.maxIndexLines).content;\n } catch {\n return \"\";\n }\n }\n\n async loadEntry(path: string): Promise<MemoryEntry | null> {\n const fullPath = path.startsWith(this.dir) ? path : this.dir + path;\n try {\n const raw = await this.fs.readFile(fullPath);\n const fm = parseFrontmatter(raw);\n const stat = await this.fs.stat(fullPath).catch(() => null);\n return {\n name: fm.name ?? pathToName(path),\n description: fm.description ?? \"\",\n type: fm.type ?? \"project\",\n content: fm.rest,\n path: path.startsWith(this.dir) ? path.slice(this.dir.length) : path,\n updatedAt: stat?.modifiedAt?.toISOString(),\n };\n } catch {\n return null;\n }\n }\n\n async saveEntry(entry: MemoryEntry): Promise<void> {\n await this.ensureDir();\n const relativePath = entry.path ?? slugify(entry.name) + \".md\";\n const fullPath = this.dir + relativePath;\n const content = serializeEntry({ ...entry, path: relativePath });\n await this.fs.writeFile(fullPath, content);\n await this.rebuildIndex();\n }\n\n async removeEntry(path: string): Promise<void> {\n const fullPath = path.startsWith(this.dir) ? path : this.dir + path;\n try {\n await this.fs.deleteFile(fullPath);\n } catch {\n // Already gone\n }\n await this.rebuildIndex();\n }\n\n async listEntries(): Promise<MemoryEntry[]> {\n try {\n const files = await this.fs.readdir(this.dir);\n const entries: MemoryEntry[] = [];\n for (const file of files) {\n if (!file.isFile || !file.name.endsWith(\".md\") || file.name === INDEX_NAME) continue;\n const entry = await this.loadEntry(file.name);\n if (entry) entries.push(entry);\n }\n return entries;\n } catch {\n return [];\n }\n }\n\n async search(query: string): Promise<MemoryEntry[]> {\n const entries = await this.listEntries();\n const lower = query.toLowerCase();\n return entries.filter(\n (e) =>\n e.name.toLowerCase().includes(lower) ||\n e.description.toLowerCase().includes(lower) ||\n e.content.toLowerCase().includes(lower),\n );\n }\n\n private async rebuildIndex(): Promise<void> {\n const entries = await this.listEntries();\n const lines: string[] = [];\n for (const entry of entries) {\n const relativePath = entry.path ?? slugify(entry.name) + \".md\";\n const desc = entry.description ? ` — ${entry.description}` : \"\";\n lines.push(`- [${entry.name}](${relativePath})${desc}`);\n }\n await this.ensureDir();\n await this.fs.writeFile(this.indexPath(), lines.join(\"\\n\") + \"\\n\");\n }\n}\n\nfunction pathToName(p: string): string {\n const base = p.split(\"/\").pop() ?? p;\n return base.replace(/\\.md$/i, \"\").replace(/[_-]/g, \" \");\n}\n"],"mappings":"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","names":["resolve","execCb","fs","resolve","path","resolve","shellEscape","resolve","path","fs","path","resolve","assistantTexts","result","fs","path","fs","fs","join","path","dirname","resolve","DEFAULT_THRESHOLD","DEFAULT_PREVIEW_CHARS","fs","path","path","path","fs","escapeRegex","normalizePath","resolve","applySnipRemovals","fs","stat","resolveProvider","SandboxManager","DEFAULT_MAX_BYTES","MEMORY_TYPES","parseFrontmatter","fs","path","stat"]}
|