@librechat/agents 3.1.78-dev.0 → 3.1.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/graphs/Graph.cjs +7 -0
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/index.cjs +44 -55
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +33 -21
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +0 -4
- package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
- package/dist/cjs/messages/anthropicToolCache.cjs +48 -15
- package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +97 -14
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs +14 -16
- package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +30 -0
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +7 -0
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/anthropic/index.mjs +43 -54
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +33 -21
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs +0 -4
- package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
- package/dist/esm/messages/anthropicToolCache.mjs +48 -15
- package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +97 -14
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/tools/local/LocalExecutionEngine.mjs +14 -16
- package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +30 -0
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/types/llm/anthropic/index.d.ts +1 -9
- package/dist/types/messages/anthropicToolCache.d.ts +5 -5
- package/dist/types/tools/subagent/SubagentExecutor.d.ts +29 -0
- package/package.json +1 -1
- package/src/graphs/Graph.ts +9 -0
- package/src/llm/anthropic/index.ts +55 -64
- package/src/llm/anthropic/llm.spec.ts +585 -0
- package/src/llm/anthropic/utils/message_inputs.ts +36 -21
- package/src/llm/anthropic/utils/message_outputs.ts +0 -4
- package/src/llm/anthropic/utils/server-tool-inputs.test.ts +95 -13
- package/src/messages/__tests__/anthropicToolCache.test.ts +46 -0
- package/src/messages/anthropicToolCache.ts +70 -25
- package/src/messages/format.ts +117 -18
- package/src/messages/formatAgentMessages.test.ts +202 -1
- package/src/scripts/subagent-configurable-inheritance.ts +252 -0
- package/src/specs/summarization.test.ts +3 -3
- package/src/tools/__tests__/LocalExecutionRoots.test.ts +8 -0
- package/src/tools/__tests__/SubagentExecutor.test.ts +148 -0
- package/src/tools/local/LocalExecutionEngine.ts +55 -54
- package/src/tools/subagent/SubagentExecutor.ts +60 -0
- package/src/types/diff.d.ts +15 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalExecutionEngine.mjs","sources":["../../../../src/tools/local/LocalExecutionEngine.ts"],"sourcesContent":["import { tmpdir } from 'os';\nimport { isAbsolute, relative, resolve } from 'path';\nimport { createHash, randomUUID } from 'crypto';\nimport { mkdir, realpath, rm, writeFile } from 'fs/promises';\nimport { createWriteStream } from 'fs';\nimport { spawn } from 'child_process';\nimport type { ChildProcess } from 'child_process';\nimport type { SandboxRuntimeConfig } from '@anthropic-ai/sandbox-runtime';\nimport { runBashAstChecks, bashAstFindingsToErrors } from './bashAst';\nimport { nodeWorkspaceFS } from './workspaceFS';\nimport type { WorkspaceFS } from './workspaceFS';\nimport type * as t from '@/types';\n\nconst DEFAULT_TIMEOUT_MS = 60000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 200000;\n/**\n * Hard cap on total stdout+stderr bytes a child process can stream\n * before we kill its process tree. Independent from `maxOutputChars`\n * (which only affects what the *model* sees) — this is the OOM\n * backstop. Configurable via `local.maxSpawnedBytes`.\n */\nconst DEFAULT_MAX_SPAWNED_BYTES = 50 * 1024 * 1024;\nconst DEFAULT_LOCAL_SESSION_ID = 'local';\nconst DEFAULT_SHELL = process.platform === 'win32' ? 'bash.exe' : 'bash';\n\n// `(?:--\\s+)?` before each destructive-target alternation: GNU/BSD\n// utilities accept `--` as an end-of-options marker, so `rm -rf -- /`\n// is identical in effect to `rm -rf /` but pre-fix it slipped past\n// the guard because the regex required the path to follow option\n// flags directly. Codex P1 #20.\n// `DESTRUCTIVE_TARGET` is the canonical \"protected location\" pattern:\n// matches `/`, `~`, `$HOME`, `${HOME}`, `.`, each optionally followed\n// by a trailing-slash and/or wildcard glob suffix. The suffix matrix:\n// '' — `$HOME` (round 14)\n// '/' — `$HOME/` (round 14, Codex P1 [37])\n// '*' — `$HOME*` (round 15, Codex P1 [42])\n// '/*' — `$HOME/*` (round 15, Codex P1 [42])\n// '.*' — `$HOME.*` (round 17, Codex P1 [47])\n// '/.*' — `$HOME/.*` (round 17, Codex P1 [47]) — the\n// dot-glob form deletes all dotfiles under the protected\n// root, just as destructive as `/*` but the prior matrix\n// missed it.\n// Suffix expression: `(?:\\/?\\.?\\*|\\/)?` — one of:\n// `\\/?\\.?\\*` → `*`, `.*`, `/*`, `/.*`\n// `\\/` → `/`\n// (empty) → bare base\nconst DESTRUCTIVE_TARGET = '(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)(?:\\\\/?\\\\.?\\\\*|\\\\/)?';\n\nconst dangerousCommandPatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n `\\\\brm\\\\s+(?:-[^\\\\s]*[rf][^\\\\s]*\\\\s+|-[^\\\\s]*[r][^\\\\s]*\\\\s+-[^\\\\s]*[f][^\\\\s]*\\\\s+)(?:--\\\\s+)?${DESTRUCTIVE_TARGET}\\\\s*(?:$|[;&|])`\n ),\n /\\b(?:mkfs|mkswap|fdisk|parted|diskutil)\\b/,\n /\\bdd\\s+[^;&|]*\\bof=\\/dev\\//,\n new RegExp(\n `\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?${DESTRUCTIVE_TARGET}(?:$|\\\\s|[;&|])`\n ),\n new RegExp(\n `\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?${DESTRUCTIVE_TARGET}(?:$|\\\\s|[;&|])`\n ),\n /:\\s*\\(\\s*\\)\\s*\\{\\s*:\\s*\\|\\s*:\\s*&\\s*\\}\\s*;\\s*:/,\n];\n\n/**\n * Companion patterns that look for destructive targets *inside*\n * matching quote pairs. These are checked against the ORIGINAL\n * command (not the post-quote-strip `normalized` form), because\n * `stripQuotedContent` blanks the contents of quoted spans —\n * which would otherwise let `rm -rf \"/\"` and friends slip past\n * `dangerousCommandPatterns`.\n *\n * Kept as a separate list so we don't pay false-positive cost on\n * benign uses like `echo \"rm -rf /\"` (the print case): each pattern\n * here REQUIRES a quote *around the destructive path argument*, not\n * just a quote *somewhere* in the command. `echo \"rm -rf /\"` has\n * `/` outside of any quote-pair-around-the-path (the quotes wrap\n * the whole `rm -rf /` text), so it doesn't match here either.\n */\n// Quoted variant uses the same DESTRUCTIVE_TARGET (which accepts an\n// optional trailing slash) so `rm -rf \"$HOME/\"` and `rm -rf \"~/\"`\n// don't slip past. Codex P1 #37.\nconst quotedDestructivePatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n `\\\\brm\\\\s+(?:-[^\\\\s]*[rf][^\\\\s]*\\\\s+){1,3}(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n new RegExp(\n `\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n new RegExp(\n `\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n];\n\n/**\n * Catches destructive operations smuggled inside a nested shell or\n * `eval` call, e.g. `bash -lc \"rm -rf $HOME\"` — the outer command\n * looks benign (`bash -lc \"...\"`) and the destructive `rm` lives\n * inside the quoted payload that `stripQuotedContent` blanks out.\n * Comprehensive review (manual finding C) flagged this as a real\n * bypass of the otherwise-correct quote-strip-then-match approach.\n *\n * Run against the ORIGINAL command (quotes intact) so the inside of\n * the nested-shell payload is visible. Conservative: matches only\n * the same operation set as `dangerousCommandPatterns` (rm -rf,\n * chmod -R 777, chown -R) when they appear inside a `<shell> -[l]?c\n * \"...\"` or `eval \"...\"` payload.\n */\nconst NESTED_SHELL_PREFIX = '(?:(?:ba|z|da|k)?sh|eval)\\\\s+(?:-l?c\\\\s+)?';\nconst nestedShellDestructivePatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\brm\\\\s+-[^\\\\s\"\\']*[rf][^\\\\s\"\\']*\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n];\n\nconst mutatingCommandPattern =\n /\\b(?:rm|mv|cp|touch|mkdir|rmdir|ln|truncate|tee|sed\\s+-i|perl\\s+-pi|python(?:3)?\\s+-c|node\\s+-e|npm\\s+(?:install|ci|update|publish)|pnpm\\s+(?:install|update|publish)|yarn\\s+(?:install|add|publish)|git\\s+(?:add|commit|checkout|switch|reset|clean|rebase|merge|push|pull|stash|tag|branch)|chmod|chown)\\b|(?:^|[^<])>\\s*[^&]|\\bcat\\s+[^|;&]*>\\s*/;\n\ntype SpawnResult = {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n timedOut: boolean;\n /**\n * True when the process was force-killed because total streamed bytes\n * exceeded `maxSpawnedBytes`. Distinct from `timedOut`. Without this\n * flag, callers (`bash_tool`, `execute_code`, etc.) would see a\n * SIGKILL'd process with `exitCode: null` and treat it as success\n * (Codex P1 — runaway commands like `yes` or noisy builds silently\n * looked successful even though their output was truncated).\n */\n overflowKilled?: boolean;\n /**\n * Signal name (e.g. `'SIGKILL'`, `'SIGSEGV'`) when the process was\n * terminated by a signal. Distinct from the overflow-kill path:\n * this captures `kill -9 $$` from inside the script, native crashes,\n * OS OOM killer, etc. Without this, signal-killed processes\n * reported `exitCode: null` and looked like clean runs (Codex P2 —\n * generalization of the overflow-kill fix). When present, the\n * exitCode field is also synthesized to `128 + signum` per the\n * POSIX convention so non-null-exit-code consumers see a failure.\n */\n signal?: string;\n /** Path to the full untruncated stdout/stderr when output exceeded `maxOutputChars`. */\n fullOutputPath?: string;\n};\n\n/**\n * POSIX convention: `128 + signum` when a process is killed by a\n * signal. Maps the common signals; unknown ones default to 1 so the\n * caller still sees a non-zero (failed) exit. Only used when Node's\n * `close` event reports `exitCode === null` (true signal kill).\n */\nconst SIGNAL_TO_EXIT_CODE: Record<string, number> = {\n SIGHUP: 129,\n SIGINT: 130,\n SIGQUIT: 131,\n SIGILL: 132,\n SIGTRAP: 133,\n SIGABRT: 134,\n SIGBUS: 135,\n SIGFPE: 136,\n SIGKILL: 137,\n SIGUSR1: 138,\n SIGSEGV: 139,\n SIGUSR2: 140,\n SIGPIPE: 141,\n SIGALRM: 142,\n SIGTERM: 143,\n};\nfunction exitCodeForSignal(signal: string | null): number {\n if (signal == null) return 1;\n return SIGNAL_TO_EXIT_CODE[signal] ?? 1;\n}\n\ntype RuntimeCommand = {\n command: string;\n args: string[];\n fileName: string;\n source?: string;\n};\n\ntype SandboxRuntimeModule = typeof import('@anthropic-ai/sandbox-runtime');\ntype SandboxManagerType = SandboxRuntimeModule['SandboxManager'];\n\nlet sandboxConfigKey: string | undefined;\nlet sandboxInitialized = false;\nlet sandboxRuntimePromise: Promise<SandboxRuntimeModule> | undefined;\n\nexport type BashValidationResult = {\n valid: boolean;\n errors: string[];\n warnings: string[];\n};\n\nfunction isToolExecutionConfig(\n config: t.ToolExecutionConfig | t.LocalExecutionConfig\n): config is t.ToolExecutionConfig {\n return 'engine' in config || 'local' in config;\n}\n\nexport function resolveLocalExecutionConfig(\n config?: t.ToolExecutionConfig | t.LocalExecutionConfig\n): t.LocalExecutionConfig {\n if (config != null && isToolExecutionConfig(config)) {\n return config.local ?? {};\n }\n return config ?? {};\n}\n\nexport function getLocalCwd(config?: t.LocalExecutionConfig): string {\n return resolve(config?.workspace?.root ?? config?.cwd ?? process.cwd());\n}\n\n/**\n * Resolves the effective workspace boundary: a list of absolute roots\n * that file operations are allowed to touch. The first entry is always\n * the canonical root (`getLocalCwd`); subsequent entries come from\n * `workspace.additionalRoots` when provided.\n *\n * Returns plain absolute paths — callers symlink-resolve when they\n * need realpath equality (see `resolveWorkspacePathSafe`).\n */\nexport function getWorkspaceRoots(\n config?: t.LocalExecutionConfig\n): string[] {\n const root = getLocalCwd(config);\n const extras = config?.workspace?.additionalRoots ?? [];\n if (extras.length === 0) return [root];\n const seen = new Set<string>([root]);\n const out: string[] = [root];\n for (const extra of extras) {\n // Relative `additionalRoots` entries are anchored to the\n // workspace root (so monorepo configs like\n // `additionalRoots: ['../shared']` resolve to a sibling of\n // `root` rather than to `process.cwd()/../shared`, which would\n // mean something completely different on a server with a\n // different cwd).\n const abs = isAbsolute(extra) ? resolve(extra) : resolve(root, extra);\n if (!seen.has(abs)) {\n seen.add(abs);\n out.push(abs);\n }\n }\n return out;\n}\n\n/**\n * Pluggable spawn resolver. Honours `local.exec.spawn` first, falls\n * back to the legacy top-level `local.spawn`, then to Node's\n * `child_process.spawn`. Centralised so engine swapping is one knob.\n */\nexport function getSpawn(\n config?: t.LocalExecutionConfig\n): t.LocalSpawn {\n return (config?.exec?.spawn ?? config?.spawn ?? spawn) as t.LocalSpawn;\n}\n\n/**\n * Pluggable filesystem resolver. Honours `local.exec.fs`, falls back\n * to the Node-host implementation. A future remote engine supplies\n * its own implementation here and inherits every file-touching tool.\n */\nexport function getWorkspaceFS(\n config?: t.LocalExecutionConfig\n): WorkspaceFS {\n return config?.exec?.fs ?? nodeWorkspaceFS;\n}\n\n/**\n * Resolves the workspace boundary for *write* operations. Honours\n * `workspace.allowWriteOutside` (and the deprecated\n * `allowOutsideWorkspace`) by returning `null`, which the path-safety\n * helpers interpret as \"skip the write clamp\".\n */\nexport function getWriteRoots(\n config?: t.LocalExecutionConfig\n): string[] | null {\n // Granular flag wins over the legacy one when explicitly set\n // (true OR false) — otherwise a host tightening access during\n // migration (`allowOutsideWorkspace: true, workspace.\n // allowWriteOutside: false`) would still get the loose behavior\n // because the legacy flag short-circuited the OR. Codex P1 #36.\n const granular = config?.workspace?.allowWriteOutside;\n if (granular === true) return null;\n if (granular === false) return getWorkspaceRoots(config);\n if (config?.allowOutsideWorkspace === true) return null;\n return getWorkspaceRoots(config);\n}\n\n/**\n * Resolves the workspace boundary for *read* operations. Honours\n * `workspace.allowReadOutside` (and the deprecated\n * `allowOutsideWorkspace`) by returning `null`.\n */\nexport function getReadRoots(\n config?: t.LocalExecutionConfig\n): string[] | null {\n // Same precedence as getWriteRoots: granular flag is authoritative\n // when set, legacy flag is the fallback. Codex P1 #36.\n const granular = config?.workspace?.allowReadOutside;\n if (granular === true) return null;\n if (granular === false) return getWorkspaceRoots(config);\n if (config?.allowOutsideWorkspace === true) return null;\n return getWorkspaceRoots(config);\n}\n\nexport function getLocalSessionId(config?: t.LocalExecutionConfig): string {\n const cwd = getLocalCwd(config);\n const digest = createHash('sha1').update(cwd).digest('hex').slice(0, 12);\n return `${DEFAULT_LOCAL_SESSION_ID}:${digest}`;\n}\n\nconst missingSandboxRuntimeMessage = [\n 'Local sandbox is enabled, but @anthropic-ai/sandbox-runtime is not installed.',\n 'Install it with `npm install @anthropic-ai/sandbox-runtime`, or disable local sandboxing with `local.sandbox.enabled: false`.',\n].join(' ');\n\n/** Lazy-loads the ESM-only sandbox runtime only when sandboxing is enabled. */\nfunction loadSandboxRuntime(): Promise<SandboxRuntimeModule> {\n sandboxRuntimePromise ??= import('@anthropic-ai/sandbox-runtime');\n return sandboxRuntimePromise;\n}\n\nfunction shouldUseLocalSandbox(config: t.LocalExecutionConfig): boolean {\n return config.sandbox?.enabled === true;\n}\n\nlet sandboxOffWarned = false;\n\nfunction maybeWarnSandboxOff(config: t.LocalExecutionConfig): void {\n if (sandboxOffWarned || shouldUseLocalSandbox(config)) {\n return;\n }\n sandboxOffWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@librechat/agents] Local execution engine is running without ' +\n '@anthropic-ai/sandbox-runtime wrapping. The agent has full access to ' +\n 'the host filesystem and network. Set toolExecution.local.sandbox.enabled ' +\n '= true to opt into process sandboxing.'\n );\n}\n\n/**\n * Test-only reset hook for the sandbox-off warning latch.\n *\n * @internal Not part of the public SDK surface.\n */\nexport function _resetLocalEngineWarningsForTests(): void {\n sandboxOffWarned = false;\n}\n\nexport function truncateLocalOutput(\n value: string,\n maxChars = DEFAULT_MAX_OUTPUT_CHARS\n): string {\n if (value.length <= maxChars) {\n return value;\n }\n const head = Math.floor(maxChars * 0.6);\n const tail = maxChars - head;\n const omitted = value.length - maxChars;\n return `${value.slice(0, head)}\\n\\n[... ${omitted} characters truncated ...]\\n\\n${value.slice(\n value.length - tail\n )}`;\n}\n\nfunction stripQuotedContent(command: string): string {\n let output = '';\n let quote: '\"' | '\\'' | '`' | undefined;\n let escaped = false;\n\n for (let i = 0; i < command.length; i++) {\n const char = command[i];\n\n if (escaped) {\n escaped = false;\n output += ' ';\n continue;\n }\n\n if (char === '\\\\') {\n escaped = true;\n output += ' ';\n continue;\n }\n\n if (quote != null) {\n if (char === quote) {\n quote = undefined;\n }\n output += ' ';\n continue;\n }\n\n if (char === '\"' || char === '\\'' || char === '`') {\n quote = char;\n output += ' ';\n continue;\n }\n\n if (char === '#') {\n while (i < command.length && command[i] !== '\\n') {\n output += ' ';\n i++;\n }\n output += '\\n';\n continue;\n }\n\n output += char;\n }\n\n return output;\n}\n\nexport async function validateBashCommand(\n command: string,\n config: t.LocalExecutionConfig = {}\n): Promise<BashValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n const normalized = stripQuotedContent(command);\n\n if (command.trim() === '') {\n errors.push('Command is empty.');\n }\n\n if (command.includes('\\0')) {\n errors.push('Command contains a NUL byte.');\n }\n\n if (config.allowDangerousCommands !== true) {\n let blocked = false;\n // Strip-then-match for the bare-form patterns (avoids false\n // positives where the destructive text is buried inside a\n // string the user is just printing).\n for (const pattern of dangerousCommandPatterns) {\n if (pattern.test(normalized)) {\n errors.push('Command matches a destructive command pattern.');\n blocked = true;\n break;\n }\n }\n // Original-form pass for patterns that REQUIRE matching quote\n // pairs around a destructive path. Without this, `rm -rf \"/\"`\n // and `chmod -R 777 \"/\"` slip past the strip-then-match pass\n // because their destructive target is inside quotes.\n if (!blocked) {\n for (const pattern of quotedDestructivePatterns) {\n if (pattern.test(command)) {\n errors.push(\n 'Command matches a destructive command pattern (quoted target).'\n );\n blocked = true;\n break;\n }\n }\n }\n if (!blocked) {\n for (const pattern of nestedShellDestructivePatterns) {\n if (pattern.test(command)) {\n errors.push(\n 'Command matches a destructive command pattern (nested shell payload).'\n );\n break;\n }\n }\n }\n }\n\n const bashAstMode = config.bashAst ?? 'off';\n if (bashAstMode !== 'off' && config.allowDangerousCommands !== true) {\n const findings = runBashAstChecks(normalized, bashAstMode);\n const split = bashAstFindingsToErrors(findings);\n errors.push(...split.errors);\n warnings.push(...split.warnings);\n }\n\n if (config.readOnly === true && mutatingCommandPattern.test(normalized)) {\n errors.push('Command appears to mutate files or repository state in read-only local mode.');\n }\n\n // Use the same shell the actual execution path will use. Hard-coding\n // DEFAULT_SHELL here would reject perfectly valid commands when the\n // host configures `local.shell` to a non-bash binary (or when the\n // runtime doesn't have bash installed at all but does have e.g. zsh).\n const syntaxShell = config.shell ?? DEFAULT_SHELL;\n const syntax = await spawnLocalProcess(\n syntaxShell,\n ['-n', '-c', command],\n {\n ...config,\n timeoutMs: Math.min(config.timeoutMs ?? DEFAULT_TIMEOUT_MS, 5000),\n sandbox: { enabled: false },\n },\n { internal: true }\n ).catch((error: Error): SpawnResult => ({\n stdout: '',\n stderr: error.message,\n exitCode: 1,\n timedOut: false,\n }));\n\n if (syntax.exitCode !== 0) {\n errors.push(\n syntax.stderr.trim() === ''\n ? 'Command failed shell syntax validation.'\n : `Command failed shell syntax validation: ${syntax.stderr.trim()}`\n );\n }\n\n if (/\\bsudo\\b/.test(normalized)) {\n warnings.push('Command requests elevated privileges with sudo.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nasync function ensureSandbox(\n config: t.LocalExecutionConfig,\n cwd: string\n): Promise<SandboxManagerType | undefined> {\n if (!shouldUseLocalSandbox(config)) {\n return undefined;\n }\n\n const runtime = await loadSandboxRuntime().catch((error: Error) => {\n throw new Error(`${missingSandboxRuntimeMessage} Cause: ${error.message}`);\n });\n\n const runtimeConfig = buildSandboxRuntimeConfig(\n config,\n cwd,\n runtime.getDefaultWritePaths\n );\n const nextKey = JSON.stringify(runtimeConfig);\n\n if (sandboxInitialized && sandboxConfigKey === nextKey) {\n return runtime.SandboxManager;\n }\n\n const dependencyCheck = runtime.SandboxManager.checkDependencies();\n if (dependencyCheck.errors.length > 0) {\n if (config.sandbox?.failIfUnavailable === true) {\n throw new Error(\n `Local sandbox requested but unavailable: ${dependencyCheck.errors.join('; ')}`\n );\n }\n return undefined;\n }\n\n if (sandboxInitialized) {\n await runtime.SandboxManager.reset();\n }\n\n // Cast at the runtime boundary — our public `BuiltSandboxRuntimeConfig`\n // is intentionally structural to keep the optional peer dep out of\n // generated `.d.ts` (Codex P1 #22). It's a structural subset of the\n // peer's `SandboxRuntimeConfig`, so the assignment is sound at the\n // one site where the peer is actually loaded.\n await runtime.SandboxManager.initialize(\n runtimeConfig as unknown as SandboxRuntimeConfig\n );\n sandboxInitialized = true;\n sandboxConfigKey = nextKey;\n return runtime.SandboxManager;\n}\n\n/**\n * Loopback addresses the in-process programmatic-tool bridge listens\n * on (`LocalProgrammaticToolCalling.ts` binds 127.0.0.1). Sandboxed\n * code launched by `run_tools_with_code` / `run_tools_with_bash` HTTPs\n * back to that address — without the entries below, the bridge is\n * silently blocked under sandbox.\n */\nconst BRIDGE_LOOPBACK_HOSTS = ['127.0.0.1', 'localhost', '::1'] as const;\n\n/**\n * Structural shape of the sandbox-runtime config we hand to\n * `SandboxManager.initialize()`. Intentionally NOT typed as the peer\n * `SandboxRuntimeConfig` from `@anthropic-ai/sandbox-runtime`: that\n * package is an OPTIONAL peer dep, and exporting a function whose\n * return type references it would make our generated `.d.ts` import\n * a module the consumer may not have installed (Codex P1 #22 — type-\n * checking would fail with `Cannot find module\n * '@anthropic-ai/sandbox-runtime'` for any host that doesn't enable\n * local sandboxing). The shape here is a structural subset; assignable\n * to the real `SandboxRuntimeConfig` at the one runtime call site.\n *\n * @internal\n */\nexport interface BuiltSandboxRuntimeConfig {\n network: {\n allowedDomains: string[];\n deniedDomains: string[];\n allowUnixSockets?: string[];\n allowAllUnixSockets?: boolean;\n allowLocalBinding?: boolean;\n allowMachLookup?: string[];\n };\n filesystem: {\n denyRead: string[];\n allowRead?: string[];\n allowWrite: string[];\n denyWrite: string[];\n allowGitConfig?: boolean;\n };\n}\n\nexport function buildSandboxRuntimeConfig(\n config: t.LocalExecutionConfig,\n cwd: string,\n getDefaultWritePaths: () => string[]\n): BuiltSandboxRuntimeConfig {\n const sandbox = config.sandbox;\n // Seed allowedDomains with loopback so the programmatic-tool bridge\n // works under sandbox. If the host explicitly denied a loopback\n // entry via `deniedDomains`, respect that and skip seeding it.\n const userAllowed = sandbox?.network?.allowedDomains ?? [];\n const denied = new Set(sandbox?.network?.deniedDomains ?? []);\n const seededLoopback = BRIDGE_LOOPBACK_HOSTS.filter(\n (host) => !denied.has(host) && !userAllowed.includes(host)\n );\n const allowedDomains = [...seededLoopback, ...userAllowed];\n // Mirror the file-tools workspace boundary: anything in\n // `additionalRoots` counts as in-workspace, so sandboxed shell/code\n // can write there too. Without this, file_tools can resolve a\n // sibling-root path but `bash`/`execute_code` is denied write\n // access — confusing divergence flagged in Codex P2 #15.\n const workspaceWriteRoots =\n config.workspace?.additionalRoots != null\n ? getWorkspaceRoots(config)\n : [cwd];\n return {\n network: {\n allowedDomains,\n deniedDomains: sandbox?.network?.deniedDomains ?? [],\n ...(sandbox?.network?.allowUnixSockets != null && {\n allowUnixSockets: sandbox.network.allowUnixSockets,\n }),\n ...(sandbox?.network?.allowAllUnixSockets != null && {\n allowAllUnixSockets: sandbox.network.allowAllUnixSockets,\n }),\n ...(sandbox?.network?.allowLocalBinding != null && {\n allowLocalBinding: sandbox.network.allowLocalBinding,\n }),\n ...(sandbox?.network?.allowMachLookup != null && {\n allowMachLookup: sandbox.network.allowMachLookup,\n }),\n },\n filesystem: {\n denyRead: sandbox?.filesystem?.denyRead ?? [],\n allowRead: sandbox?.filesystem?.allowRead,\n allowWrite: sandbox?.filesystem?.allowWrite ?? [\n ...workspaceWriteRoots,\n ...getDefaultWritePaths(),\n ],\n denyWrite: sandbox?.filesystem?.denyWrite ?? [\n '.env',\n '.env.*',\n '.git/config',\n '.git/hooks/**',\n ],\n allowGitConfig: sandbox?.filesystem?.allowGitConfig,\n },\n };\n}\n\n/**\n * Internal options for {@link spawnLocalProcess} that we don't want\n * exposed on the public `LocalExecutionConfig` type.\n *\n * @internal\n */\nexport interface SpawnLocalProcessOptions {\n /**\n * When true, suppress the \"sandbox is off\" warning AND its latch\n * for this spawn. Use for SDK-internal probes (`bash -n` syntax\n * preflight, `rg --version`, etc.) that intentionally run with\n * the sandbox forced off — the warning is noise for those, and\n * letting the latch flip would hide the warning when a *real*\n * unsandboxed execution happens later in the same process.\n */\n internal?: boolean;\n}\n\nexport async function spawnLocalProcess(\n command: string,\n args: string[],\n config: t.LocalExecutionConfig = {},\n options?: SpawnLocalProcessOptions\n): Promise<SpawnResult> {\n const cwd = getLocalCwd(config);\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxOutputChars = config.maxOutputChars ?? DEFAULT_MAX_OUTPUT_CHARS;\n // Streaming caps. Local tools execute arbitrary shell/code, so a noisy\n // command (`yes`, `cat /dev/urandom | base64`, a verbose build) could\n // accumulate gigabytes in memory before hitting the post-close cap.\n // We bound in-memory per-stream and spill the rest to disk; we also\n // hard-kill the child once total streamed bytes pass `maxSpawnedBytes`\n // so a process producing unbounded output gets stopped instead of\n // letting the host OOM.\n const inMemoryCapBytes = maxOutputChars * 2;\n const hardKillBytes =\n config.maxSpawnedBytes ?? DEFAULT_MAX_SPAWNED_BYTES;\n const sandboxManager = await ensureSandbox(config, cwd);\n // Internal probes (validateBashCommand syntax preflight,\n // isRipgrepAvailable, syntax-check probe cache priming) pass\n // `internal: true` so they don't emit a misleading \"sandbox is\n // off\" warning AND don't flip `sandboxOffWarned = true`. Without\n // this Codex P2 path: a run with `sandbox.enabled: true` would\n // see a false warning from the syntax preflight, and the latch\n // flip would suppress the warning in a *later* truly-unsandboxed\n // run — exactly the scenario operators need to see.\n if (sandboxManager == null && options?.internal !== true) {\n maybeWarnSandboxOff(config);\n }\n let spawnCommand = command;\n let spawnArgs = args;\n\n if (sandboxManager != null) {\n const rendered = [command, ...args.map(shellQuote)].join(' ');\n const sandboxed = await sandboxManager.wrapWithSandbox(rendered);\n spawnCommand = config.shell ?? DEFAULT_SHELL;\n spawnArgs = ['-lc', sandboxed];\n }\n\n const launcher = getSpawn(config);\n return new Promise<SpawnResult>((resolveResult, reject) => {\n const child = launcher(spawnCommand, spawnArgs, {\n cwd,\n detached: process.platform !== 'win32',\n env: { ...process.env, ...(config.env ?? {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n let totalSpawnedBytes = 0;\n let overflowKilled = false;\n let spillStream: import('fs').WriteStream | undefined;\n let spillPath: string | undefined;\n let settled = false;\n let timedOut = false;\n let timeout: NodeJS.Timeout | undefined;\n\n const ensureSpill = (): void => {\n if (spillStream != null) return;\n // Lazy-open the temp file the first time a stream's in-memory\n // buffer overflows. Seed it with everything we've buffered so\n // the file holds the FULL output (not just the post-cap tail).\n // Uses the static `createWriteStream` import — `require('fs')`\n // would throw `ReferenceError: require is not defined` in ESM\n // consumers (this package ships both `dist/cjs` and `dist/esm`).\n spillPath = resolve(tmpdir(), `lc-local-output-${randomUUID()}.txt`);\n spillStream = createWriteStream(spillPath);\n spillStream.write('===== stdout =====\\n');\n spillStream.write(stdout);\n spillStream.write('\\n===== stderr =====\\n');\n spillStream.write(stderr);\n spillStream.write('\\n===== overflow stream begins here =====\\n');\n };\n\n const handleChunk = (\n buf: Buffer,\n kind: 'stdout' | 'stderr'\n ): void => {\n totalSpawnedBytes += buf.length;\n // hardKillBytes <= 0 means \"no cap\" per the public config contract\n // (see LocalExecutionConfig.maxSpawnedBytes). Skip the kill check\n // entirely in that case so a single byte doesn't terminate the run.\n if (\n hardKillBytes > 0 &&\n totalSpawnedBytes > hardKillBytes &&\n !overflowKilled\n ) {\n overflowKilled = true;\n killProcessTree(child);\n return;\n }\n const current = kind === 'stdout' ? stdout : stderr;\n if (current.length < inMemoryCapBytes) {\n const text = buf.toString('utf8');\n if (kind === 'stdout') stdout += text;\n else stderr += text;\n if (current.length + text.length >= inMemoryCapBytes) {\n ensureSpill();\n }\n } else {\n ensureSpill();\n spillStream!.write(`[${kind}] `);\n spillStream!.write(buf);\n }\n };\n\n const finish = (result: SpawnResult): void => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeout != null) {\n clearTimeout(timeout);\n }\n const finalize = (): void => {\n const truncated = {\n stdout: truncateLocalOutput(result.stdout, maxOutputChars),\n stderr: truncateLocalOutput(result.stderr, maxOutputChars),\n };\n resolveResult({\n ...result,\n ...truncated,\n ...(spillPath != null ? { fullOutputPath: spillPath } : {}),\n });\n };\n if (spillStream == null) {\n finalize();\n return;\n }\n // Wait for the temp file to flush before reporting the path.\n // Otherwise the model sees `full_output_path: …` for a file\n // that's still being written.\n spillStream.end(() => finalize());\n };\n\n const fail = (error: Error): void => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeout != null) {\n clearTimeout(timeout);\n }\n if (spillStream != null) {\n spillStream.end();\n }\n reject(error);\n };\n\n if (timeoutMs > 0) {\n timeout = setTimeout(() => {\n timedOut = true;\n killProcessTree(child);\n }, timeoutMs);\n }\n\n child.stdout?.on('data', (chunk: Buffer) => {\n handleChunk(chunk, 'stdout');\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n handleChunk(chunk, 'stderr');\n });\n\n child.on('error', fail);\n\n child.on('close', (exitCode, signal) => {\n // Synthesize a non-zero exit code whenever the process exited\n // by signal — Node reports `exitCode: null` in that case and\n // the formatter only prints non-null exit codes, so signal\n // kills (overflow guard, `kill -9 $$` from inside the script,\n // native crashes, OS OOM killer, …) would otherwise look like\n // successful runs (Codex P1 + Codex P2). Overflow path keeps\n // its 137 (SIGKILL) for compatibility; other signals map per\n // POSIX `128 + signum`.\n let finalExit: number | null = exitCode;\n if (finalExit == null) {\n if (overflowKilled) {\n finalExit = 137;\n } else if (signal != null) {\n finalExit = exitCodeForSignal(signal);\n }\n }\n finish({\n stdout,\n stderr,\n exitCode: finalExit,\n timedOut,\n ...(overflowKilled ? { overflowKilled: true } : {}),\n ...(signal != null ? { signal } : {}),\n });\n });\n });\n}\n\nexport async function executeLocalBash(\n command: string,\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n const validation = await validateBashCommand(command, config);\n if (!validation.valid) {\n throw new Error(validation.errors.join('\\n'));\n }\n const shell = config.shell ?? DEFAULT_SHELL;\n return spawnLocalProcess(shell, ['-lc', command], config);\n}\n\n/**\n * Variant of `executeLocalBash` that exposes `args` as positional\n * shell parameters (`$1`, `$2`, …). Mirrors what the other runtimes\n * do in `getRuntimeCommand`. Uses the standard `bash -c <code> --\n * arg0 arg1 …` form: the `--` becomes `$0`, then `args[0]` is `$1`\n * and so on. Same AST validation as the no-args path.\n *\n * Used by both the `execute_code`/`lang:'bash'` path AND the\n * `bash_tool` factory so the schema's `args` contract works\n * identically in both surfaces.\n */\n/**\n * Matches a single arg that, on its own, references a protected\n * location (`/`, `~`, `$HOME`, `${HOME}`, `.`, with optional trailing\n * slash, wildcard, or dot-glob suffix). Used to spot the\n * `command: 'rm -rf \"$1\"', args: ['/']` shape where the destructive\n * target is moved into a positional arg to evade the command regex.\n * Codex P1 [45], extended for dot-glob in Codex P1 [47] (mirrors the\n * `DESTRUCTIVE_TARGET` suffix matrix exactly).\n */\nconst PROTECTED_TARGET_ARG_RE =\n /^(?:\\/|~|\\$\\{?HOME\\}?|\\.)(?:\\/?\\.?\\*|\\/)?$/;\n\n/**\n * Mutating-op recognizer for the args check. Conservative: only the\n * three operations the destructive-command guard already covers\n * directly (`rm -rf …`, `chmod -R …`, `chown -R …`). Other shell\n * builtins might mutate state (`mv`, `cp` over an existing file,\n * etc.) but the destructive guard doesn't try to catch those today,\n * so we don't widen here either.\n */\nconst DESTRUCTIVE_OP_IN_COMMAND_RE =\n /\\b(?:rm\\s+-[^\\s]*[rf]|chmod\\s+-R|chown\\s+-R)\\b/;\n\nexport async function executeLocalBashWithArgs(\n command: string,\n args: readonly string[],\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n const validation = await validateBashCommand(command, config);\n if (!validation.valid) {\n throw new Error(validation.errors.join('\\n'));\n }\n // Per-arg protected-target check (Codex P1 [45]). The command\n // regex can't see `$1`/`$@` substitutions at runtime — `command:\n // 'rm -rf \"$1\"', args: ['/']` would expand to `rm -rf '/'` inside\n // bash but the validator only saw `rm -rf \"$1\"` (no destructive\n // target). Block when (a) the command contains a destructive op\n // AND (b) at least one arg matches the protected-target shape.\n // Skipped when allowDangerousCommands is true (host-opted-in).\n if (\n args.length > 0 &&\n config.allowDangerousCommands !== true &&\n DESTRUCTIVE_OP_IN_COMMAND_RE.test(command)\n ) {\n const offending = args.find((a) => PROTECTED_TARGET_ARG_RE.test(a));\n if (offending !== undefined) {\n throw new Error(\n `Command matches a destructive command pattern (protected target \"${offending}\" passed via positional arg).`\n );\n }\n }\n const shell = config.shell ?? DEFAULT_SHELL;\n return spawnLocalProcess(\n shell,\n ['-lc', command, '--', ...args],\n config\n );\n}\n\nexport async function executeLocalCode(\n input: {\n lang: string;\n code: string;\n args?: string[];\n },\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n if (input.lang === 'bash') {\n // Append `args` as positional parameters via the standard\n // `bash -c <code> -- <args...>` form so `$1`, `$2`, … inside\n // `code` resolve correctly. Honours the same args contract the\n // other runtimes (py, js, …) already support.\n if (input.args != null && input.args.length > 0) {\n return executeLocalBashWithArgs(input.code, input.args, config);\n }\n return executeLocalBash(input.code, config);\n }\n\n const tempDir = resolve(tmpdir(), `lc-local-${randomUUID()}`);\n await mkdir(tempDir, { recursive: true });\n\n try {\n const runtime = getRuntimeCommand(\n input.lang,\n tempDir,\n input.code,\n input.args,\n config.shell\n );\n if (runtime.source != null) {\n await writeFile(resolve(tempDir, runtime.fileName), runtime.source, 'utf8');\n }\n return await spawnLocalProcess(runtime.command, runtime.args, config);\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n}\n\nfunction getRuntimeCommand(\n lang: string,\n tempDir: string,\n code: string,\n args: string[] = [],\n // Override for the shell used by compile-style runtimes (`rs`,\n // `c`, `cpp`, `java`, `d`, `f90`). Threads `local.shell` so a host\n // that doesn't have bash (or wants `/bin/sh` / zsh) can still\n // execute these languages — Codex P2 #29: the bare-bash hardcode\n // mirrored the same gap that Codex P1 #6 fixed for the syntax\n // preflight, but had been missed for these runtime invocations.\n shellOverride?: string\n): RuntimeCommand {\n const fileFor = (name: string): string => resolve(tempDir, name);\n const shell = shellOverride ?? configShell();\n\n switch (lang) {\n case 'py':\n return {\n command: 'python3',\n args: [fileFor('main.py'), ...args],\n fileName: 'main.py',\n source: code,\n };\n case 'js':\n return {\n command: 'node',\n args: [fileFor('main.js'), ...args],\n fileName: 'main.js',\n source: code,\n };\n case 'ts':\n return {\n command: 'npx',\n args: ['--no-install', 'tsx', fileFor('main.ts'), ...args],\n fileName: 'main.ts',\n source: code,\n };\n case 'php':\n return {\n command: 'php',\n args: [fileFor('main.php'), ...args],\n fileName: 'main.php',\n source: code,\n };\n case 'go':\n return {\n command: 'go',\n args: ['run', fileFor('main.go'), ...args],\n fileName: 'main.go',\n source: code,\n };\n case 'rs':\n return {\n command: shell,\n args: [\n '-lc',\n `rustc ${shellQuote(fileFor('main.rs'))} -o ${shellQuote(\n fileFor('main-rs')\n )} && ${shellQuote(fileFor('main-rs'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.rs',\n source: code,\n };\n case 'c':\n return {\n command: shell,\n args: [\n '-lc',\n `cc ${shellQuote(fileFor('main.c'))} -o ${shellQuote(\n fileFor('main-c')\n )} && ${shellQuote(fileFor('main-c'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.c',\n source: code,\n };\n case 'cpp':\n return {\n command: shell,\n args: [\n '-lc',\n `c++ ${shellQuote(fileFor('main.cpp'))} -o ${shellQuote(\n fileFor('main-cpp')\n )} && ${shellQuote(fileFor('main-cpp'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.cpp',\n source: code,\n };\n case 'java':\n return {\n command: shell,\n args: [\n '-lc',\n `javac ${shellQuote(fileFor('Main.java'))} && java -cp ${shellQuote(\n tempDir\n )} Main ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'Main.java',\n source: code,\n };\n case 'r':\n return {\n command: 'Rscript',\n args: [fileFor('main.R'), ...args],\n fileName: 'main.R',\n source: code,\n };\n case 'd':\n return {\n command: shell,\n args: [\n '-lc',\n `dmd ${shellQuote(fileFor('main.d'))} -of=${shellQuote(\n fileFor('main-d')\n )} && ${shellQuote(fileFor('main-d'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.d',\n source: code,\n };\n case 'f90':\n return {\n command: shell,\n args: [\n '-lc',\n `gfortran ${shellQuote(fileFor('main.f90'))} -o ${shellQuote(\n fileFor('main-f90')\n )} && ${shellQuote(fileFor('main-f90'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.f90',\n source: code,\n };\n default:\n throw new Error(`Unsupported local runtime: ${lang}`);\n }\n}\n\nfunction configShell(): string {\n return process.platform === 'win32' ? 'bash.exe' : 'bash';\n}\n\n/**\n * How long after SIGTERM we wait before escalating to SIGKILL. A\n * cooperative process gets a graceful chance to flush + clean up;\n * a process that ignores or traps SIGTERM (`trap '' TERM`) gets\n * killed unconditionally so timeoutMs / maxSpawnedBytes can't be\n * defeated by a hostile script. Codex P1 #28 — pre-fix the spawn\n * promise would never resolve in that case and the entire tool run\n * would hang past the advertised timeout.\n */\nconst SIGKILL_ESCALATION_MS = 2000;\n\nfunction sigterm(child: ChildProcess): void {\n if (child.pid == null) return;\n try {\n if (process.platform === 'win32') {\n child.kill('SIGTERM');\n return;\n }\n process.kill(-child.pid, 'SIGTERM');\n } catch {\n child.kill('SIGTERM');\n }\n}\n\nfunction sigkill(child: ChildProcess): void {\n if (child.pid == null) return;\n if (child.exitCode != null || child.signalCode != null) return;\n try {\n if (process.platform === 'win32') {\n child.kill('SIGKILL');\n return;\n }\n process.kill(-child.pid, 'SIGKILL');\n } catch {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already dead */\n }\n }\n}\n\nfunction killProcessTree(child: ChildProcess): void {\n sigterm(child);\n // Escalate to SIGKILL if the child is still alive after the grace\n // window. Use unref() so the timer doesn't keep the Node process\n // alive past the parent's natural exit.\n const escalation = setTimeout(() => sigkill(child), SIGKILL_ESCALATION_MS);\n escalation.unref?.();\n child.once('close', () => clearTimeout(escalation));\n}\n\nexport function shellQuote(value: string): string {\n if (value === '') {\n return '\\'\\'';\n }\n if (/^[A-Za-z0-9_/:=.,@%+-]+$/.test(value)) {\n return value;\n }\n return `'${value.replace(/'/g, '\\'\\\\\\'\\'')}'`;\n}\n\nexport function resolveWorkspacePath(\n filePath: string,\n config: t.LocalExecutionConfig = {},\n intent: 'read' | 'write' = 'write'\n): string {\n const cwd = getLocalCwd(config);\n const absolutePath = isAbsolute(filePath) ? resolve(filePath) : resolve(cwd, filePath);\n\n const roots = intent === 'write' ? getWriteRoots(config) : getReadRoots(config);\n if (roots == null) return absolutePath; // explicit allow-outside\n\n if (absolutePath === cwd || isInsideAnyRoot(absolutePath, roots)) {\n return absolutePath;\n }\n throw new Error(`Path is outside the local workspace: ${filePath}`);\n}\n\nfunction isInsideAnyRoot(absolutePath: string, roots: string[]): boolean {\n for (const root of roots) {\n if (absolutePath === root) return true;\n const rel = relative(root, absolutePath);\n if (!rel.startsWith('..') && !isAbsolute(rel)) return true;\n }\n return false;\n}\n\ntype RealpathFn = (p: string) => Promise<string>;\n\nasync function realpathOrSelf(\n absolutePath: string,\n realpathImpl: RealpathFn = realpath\n): Promise<string> {\n try {\n return await realpathImpl(absolutePath);\n } catch {\n return absolutePath;\n }\n}\n\n/**\n * Resolves the realpath of `absolutePath`, falling back to the nearest\n * existing ancestor when the target itself does not yet exist (so the\n * containment check still works for `write_file` to a brand-new path).\n *\n * Codex P2 #38: takes the realpath impl as a parameter so callers\n * can route through `WorkspaceFS.realpath` when a custom engine is\n * configured. Pre-fix, host `fs/promises.realpath` would fail on a\n * remote/in-memory FS path and silently fall back to lexical\n * containment, leaving the symlink-escape clamp ineffective on\n * non-default engines.\n */\nasync function realpathOfPathOrAncestor(\n absolutePath: string,\n realpathImpl: RealpathFn = realpath\n): Promise<string> {\n let current = absolutePath;\n let suffix = '';\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n try {\n const real = await realpathImpl(current);\n return suffix === '' ? real : resolve(real, suffix);\n } catch {\n const parent = resolve(current, '..');\n if (parent === current) {\n return absolutePath;\n }\n const base = current.slice(parent.length + 1);\n suffix = suffix === '' ? base : `${base}/${suffix}`;\n current = parent;\n }\n }\n}\n\n/**\n * Resolves a workspace path AND follows any symlinks before checking\n * containment, so a symlink inside the workspace pointing outside is\n * rejected even though the lexical path looks safe. Handles paths that\n * don't yet exist (e.g. write_file targets) by realpath-resolving the\n * nearest existing ancestor and re-attaching the unresolved suffix.\n */\nexport async function resolveWorkspacePathSafe(\n filePath: string,\n config: t.LocalExecutionConfig = {},\n intent: 'read' | 'write' = 'write'\n): Promise<string> {\n const lexical = resolveWorkspacePath(filePath, config, intent);\n const roots = intent === 'write' ? getWriteRoots(config) : getReadRoots(config);\n if (roots == null) {\n return lexical;\n }\n // Route realpath through the configured WorkspaceFS so a custom\n // engine (in-memory, remote) gets the same symlink-escape clamp\n // the host-fs path gets. Codex P2 #38: pre-fix the host realpath\n // would fail on a non-default FS path and silently fall back to\n // lexical containment, leaving the clamp ineffective.\n const fsRealpath: RealpathFn = (p) => getWorkspaceFS(config).realpath(p);\n const realRoots = await Promise.all(\n roots.map((r) => realpathOrSelf(r, fsRealpath))\n );\n const realPath = await realpathOfPathOrAncestor(lexical, fsRealpath);\n if (isInsideAnyRoot(realPath, realRoots)) {\n return lexical;\n }\n throw new Error(\n `Path is outside the local workspace (symlink escape): ${filePath}`\n );\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"LocalExecutionEngine.mjs","sources":["../../../../src/tools/local/LocalExecutionEngine.ts"],"sourcesContent":["import { tmpdir } from 'os';\nimport { isAbsolute, relative, resolve } from 'path';\nimport { createHash, randomUUID } from 'crypto';\nimport { mkdir, realpath, rm, writeFile } from 'fs/promises';\nimport { createWriteStream } from 'fs';\nimport { spawn } from 'child_process';\nimport type { ChildProcess } from 'child_process';\nimport { runBashAstChecks, bashAstFindingsToErrors } from './bashAst';\nimport { nodeWorkspaceFS } from './workspaceFS';\nimport type { WorkspaceFS } from './workspaceFS';\nimport type * as t from '@/types';\n\nconst DEFAULT_TIMEOUT_MS = 60000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 200000;\n/**\n * Hard cap on total stdout+stderr bytes a child process can stream\n * before we kill its process tree. Independent from `maxOutputChars`\n * (which only affects what the *model* sees) — this is the OOM\n * backstop. Configurable via `local.maxSpawnedBytes`.\n */\nconst DEFAULT_MAX_SPAWNED_BYTES = 50 * 1024 * 1024;\nconst DEFAULT_LOCAL_SESSION_ID = 'local';\nconst DEFAULT_SHELL = process.platform === 'win32' ? 'bash.exe' : 'bash';\n\n// `(?:--\\s+)?` before each destructive-target alternation: GNU/BSD\n// utilities accept `--` as an end-of-options marker, so `rm -rf -- /`\n// is identical in effect to `rm -rf /` but pre-fix it slipped past\n// the guard because the regex required the path to follow option\n// flags directly. Codex P1 #20.\n// `DESTRUCTIVE_TARGET` is the canonical \"protected location\" pattern:\n// matches `/`, `~`, `$HOME`, `${HOME}`, `.`, each optionally followed\n// by a trailing-slash and/or wildcard glob suffix. The suffix matrix:\n// '' — `$HOME` (round 14)\n// '/' — `$HOME/` (round 14, Codex P1 [37])\n// '*' — `$HOME*` (round 15, Codex P1 [42])\n// '/*' — `$HOME/*` (round 15, Codex P1 [42])\n// '.*' — `$HOME.*` (round 17, Codex P1 [47])\n// '/.*' — `$HOME/.*` (round 17, Codex P1 [47]) — the\n// dot-glob form deletes all dotfiles under the protected\n// root, just as destructive as `/*` but the prior matrix\n// missed it.\n// Suffix expression: `(?:\\/?\\.?\\*|\\/)?` — one of:\n// `\\/?\\.?\\*` → `*`, `.*`, `/*`, `/.*`\n// `\\/` → `/`\n// (empty) → bare base\nconst DESTRUCTIVE_TARGET = '(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)(?:\\\\/?\\\\.?\\\\*|\\\\/)?';\n\nconst dangerousCommandPatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n `\\\\brm\\\\s+(?:-[^\\\\s]*[rf][^\\\\s]*\\\\s+|-[^\\\\s]*[r][^\\\\s]*\\\\s+-[^\\\\s]*[f][^\\\\s]*\\\\s+)(?:--\\\\s+)?${DESTRUCTIVE_TARGET}\\\\s*(?:$|[;&|])`\n ),\n /\\b(?:mkfs|mkswap|fdisk|parted|diskutil)\\b/,\n /\\bdd\\s+[^;&|]*\\bof=\\/dev\\//,\n new RegExp(\n `\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?${DESTRUCTIVE_TARGET}(?:$|\\\\s|[;&|])`\n ),\n new RegExp(\n `\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?${DESTRUCTIVE_TARGET}(?:$|\\\\s|[;&|])`\n ),\n /:\\s*\\(\\s*\\)\\s*\\{\\s*:\\s*\\|\\s*:\\s*&\\s*\\}\\s*;\\s*:/,\n];\n\n/**\n * Companion patterns that look for destructive targets *inside*\n * matching quote pairs. These are checked against the ORIGINAL\n * command (not the post-quote-strip `normalized` form), because\n * `stripQuotedContent` blanks the contents of quoted spans —\n * which would otherwise let `rm -rf \"/\"` and friends slip past\n * `dangerousCommandPatterns`.\n *\n * Kept as a separate list so we don't pay false-positive cost on\n * benign uses like `echo \"rm -rf /\"` (the print case): each pattern\n * here REQUIRES a quote *around the destructive path argument*, not\n * just a quote *somewhere* in the command. `echo \"rm -rf /\"` has\n * `/` outside of any quote-pair-around-the-path (the quotes wrap\n * the whole `rm -rf /` text), so it doesn't match here either.\n */\n// Quoted variant uses the same DESTRUCTIVE_TARGET (which accepts an\n// optional trailing slash) so `rm -rf \"$HOME/\"` and `rm -rf \"~/\"`\n// don't slip past. Codex P1 #37.\nconst quotedDestructivePatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n `\\\\brm\\\\s+(?:-[^\\\\s]*[rf][^\\\\s]*\\\\s+){1,3}(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n new RegExp(\n `\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n new RegExp(\n `\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?[\"']${DESTRUCTIVE_TARGET}[\"']`\n ),\n];\n\n/**\n * Catches destructive operations smuggled inside a nested shell or\n * `eval` call, e.g. `bash -lc \"rm -rf $HOME\"` — the outer command\n * looks benign (`bash -lc \"...\"`) and the destructive `rm` lives\n * inside the quoted payload that `stripQuotedContent` blanks out.\n * Comprehensive review (manual finding C) flagged this as a real\n * bypass of the otherwise-correct quote-strip-then-match approach.\n *\n * Run against the ORIGINAL command (quotes intact) so the inside of\n * the nested-shell payload is visible. Conservative: matches only\n * the same operation set as `dangerousCommandPatterns` (rm -rf,\n * chmod -R 777, chown -R) when they appear inside a `<shell> -[l]?c\n * \"...\"` or `eval \"...\"` payload.\n */\nconst NESTED_SHELL_PREFIX = '(?:(?:ba|z|da|k)?sh|eval)\\\\s+(?:-l?c\\\\s+)?';\nconst nestedShellDestructivePatterns: ReadonlyArray<RegExp> = [\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\brm\\\\s+-[^\\\\s\"\\']*[rf][^\\\\s\"\\']*\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\bchmod\\\\s+-R\\\\s+(?:777|a\\\\+w)\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n new RegExp(\n NESTED_SHELL_PREFIX +\n '[\"\\'][^\"\\']*\\\\bchown\\\\s+-R\\\\s+[^;&|]+\\\\s+(?:--\\\\s+)?(?:\\\\/|~|\\\\$\\\\{?HOME\\\\}?|\\\\.)'\n ),\n];\n\nconst mutatingCommandPattern =\n /\\b(?:rm|mv|cp|touch|mkdir|rmdir|ln|truncate|tee|sed\\s+-i|perl\\s+-pi|python(?:3)?\\s+-c|node\\s+-e|npm\\s+(?:install|ci|update|publish)|pnpm\\s+(?:install|update|publish)|yarn\\s+(?:install|add|publish)|git\\s+(?:add|commit|checkout|switch|reset|clean|rebase|merge|push|pull|stash|tag|branch)|chmod|chown)\\b|(?:^|[^<])>\\s*[^&]|\\bcat\\s+[^|;&]*>\\s*/;\n\ntype SpawnResult = {\n stdout: string;\n stderr: string;\n exitCode: number | null;\n timedOut: boolean;\n /**\n * True when the process was force-killed because total streamed bytes\n * exceeded `maxSpawnedBytes`. Distinct from `timedOut`. Without this\n * flag, callers (`bash_tool`, `execute_code`, etc.) would see a\n * SIGKILL'd process with `exitCode: null` and treat it as success\n * (Codex P1 — runaway commands like `yes` or noisy builds silently\n * looked successful even though their output was truncated).\n */\n overflowKilled?: boolean;\n /**\n * Signal name (e.g. `'SIGKILL'`, `'SIGSEGV'`) when the process was\n * terminated by a signal. Distinct from the overflow-kill path:\n * this captures `kill -9 $$` from inside the script, native crashes,\n * OS OOM killer, etc. Without this, signal-killed processes\n * reported `exitCode: null` and looked like clean runs (Codex P2 —\n * generalization of the overflow-kill fix). When present, the\n * exitCode field is also synthesized to `128 + signum` per the\n * POSIX convention so non-null-exit-code consumers see a failure.\n */\n signal?: string;\n /** Path to the full untruncated stdout/stderr when output exceeded `maxOutputChars`. */\n fullOutputPath?: string;\n};\n\n/**\n * POSIX convention: `128 + signum` when a process is killed by a\n * signal. Maps the common signals; unknown ones default to 1 so the\n * caller still sees a non-zero (failed) exit. Only used when Node's\n * `close` event reports `exitCode === null` (true signal kill).\n */\nconst SIGNAL_TO_EXIT_CODE: Record<string, number> = {\n SIGHUP: 129,\n SIGINT: 130,\n SIGQUIT: 131,\n SIGILL: 132,\n SIGTRAP: 133,\n SIGABRT: 134,\n SIGBUS: 135,\n SIGFPE: 136,\n SIGKILL: 137,\n SIGUSR1: 138,\n SIGSEGV: 139,\n SIGUSR2: 140,\n SIGPIPE: 141,\n SIGALRM: 142,\n SIGTERM: 143,\n};\nfunction exitCodeForSignal(signal: string | null): number {\n if (signal == null) return 1;\n return SIGNAL_TO_EXIT_CODE[signal] ?? 1;\n}\n\ntype RuntimeCommand = {\n command: string;\n args: string[];\n fileName: string;\n source?: string;\n};\n\ntype SandboxManagerType = {\n checkDependencies(): { errors: string[] };\n initialize(config: BuiltSandboxRuntimeConfig): Promise<void>;\n reset(): Promise<void>;\n wrapWithSandbox(command: string): Promise<string>;\n};\n\ntype SandboxRuntimeModule = {\n getDefaultWritePaths(): string[];\n SandboxManager: SandboxManagerType;\n};\n\nlet sandboxConfigKey: string | undefined;\nlet sandboxInitialized = false;\nlet sandboxRuntimePromise: Promise<SandboxRuntimeModule> | undefined;\n\nexport type BashValidationResult = {\n valid: boolean;\n errors: string[];\n warnings: string[];\n};\n\nfunction isToolExecutionConfig(\n config: t.ToolExecutionConfig | t.LocalExecutionConfig\n): config is t.ToolExecutionConfig {\n return 'engine' in config || 'local' in config;\n}\n\nexport function resolveLocalExecutionConfig(\n config?: t.ToolExecutionConfig | t.LocalExecutionConfig\n): t.LocalExecutionConfig {\n if (config != null && isToolExecutionConfig(config)) {\n return config.local ?? {};\n }\n return config ?? {};\n}\n\nexport function getLocalCwd(config?: t.LocalExecutionConfig): string {\n return resolve(config?.workspace?.root ?? config?.cwd ?? process.cwd());\n}\n\n/**\n * Resolves the effective workspace boundary: a list of absolute roots\n * that file operations are allowed to touch. The first entry is always\n * the canonical root (`getLocalCwd`); subsequent entries come from\n * `workspace.additionalRoots` when provided.\n *\n * Returns plain absolute paths — callers symlink-resolve when they\n * need realpath equality (see `resolveWorkspacePathSafe`).\n */\nexport function getWorkspaceRoots(config?: t.LocalExecutionConfig): string[] {\n const root = getLocalCwd(config);\n const extras = config?.workspace?.additionalRoots ?? [];\n if (extras.length === 0) return [root];\n const seen = new Set<string>([root]);\n const out: string[] = [root];\n for (const extra of extras) {\n // Relative `additionalRoots` entries are anchored to the\n // workspace root (so monorepo configs like\n // `additionalRoots: ['../shared']` resolve to a sibling of\n // `root` rather than to `process.cwd()/../shared`, which would\n // mean something completely different on a server with a\n // different cwd).\n const abs = isAbsolute(extra) ? resolve(extra) : resolve(root, extra);\n if (!seen.has(abs)) {\n seen.add(abs);\n out.push(abs);\n }\n }\n return out;\n}\n\n/**\n * Pluggable spawn resolver. Honours `local.exec.spawn` first, falls\n * back to the legacy top-level `local.spawn`, then to Node's\n * `child_process.spawn`. Centralised so engine swapping is one knob.\n */\nexport function getSpawn(config?: t.LocalExecutionConfig): t.LocalSpawn {\n return (config?.exec?.spawn ?? config?.spawn ?? spawn) as t.LocalSpawn;\n}\n\n/**\n * Pluggable filesystem resolver. Honours `local.exec.fs`, falls back\n * to the Node-host implementation. A future remote engine supplies\n * its own implementation here and inherits every file-touching tool.\n */\nexport function getWorkspaceFS(config?: t.LocalExecutionConfig): WorkspaceFS {\n return config?.exec?.fs ?? nodeWorkspaceFS;\n}\n\n/**\n * Resolves the workspace boundary for *write* operations. Honours\n * `workspace.allowWriteOutside` (and the deprecated\n * `allowOutsideWorkspace`) by returning `null`, which the path-safety\n * helpers interpret as \"skip the write clamp\".\n */\nexport function getWriteRoots(\n config: t.LocalExecutionConfig = {}\n): string[] | null {\n // Granular flag wins over the legacy one when explicitly set\n // (true OR false) — otherwise a host tightening access during\n // migration (`allowOutsideWorkspace: true, workspace.\n // allowWriteOutside: false`) would still get the loose behavior\n // because the legacy flag short-circuited the OR. Codex P1 #36.\n const granular = config.workspace?.allowWriteOutside;\n if (granular === true) return null;\n if (granular === false) return getWorkspaceRoots(config);\n if (config.allowOutsideWorkspace === true) return null;\n return getWorkspaceRoots(config);\n}\n\n/**\n * Resolves the workspace boundary for *read* operations. Honours\n * `workspace.allowReadOutside` (and the deprecated\n * `allowOutsideWorkspace`) by returning `null`.\n */\nexport function getReadRoots(\n config: t.LocalExecutionConfig = {}\n): string[] | null {\n // Same precedence as getWriteRoots: granular flag is authoritative\n // when set, legacy flag is the fallback. Codex P1 #36.\n const granular = config.workspace?.allowReadOutside;\n if (granular === true) return null;\n if (granular === false) return getWorkspaceRoots(config);\n if (config.allowOutsideWorkspace === true) return null;\n return getWorkspaceRoots(config);\n}\n\nexport function getLocalSessionId(config?: t.LocalExecutionConfig): string {\n const cwd = getLocalCwd(config);\n const digest = createHash('sha1').update(cwd).digest('hex').slice(0, 12);\n return `${DEFAULT_LOCAL_SESSION_ID}:${digest}`;\n}\n\nconst missingSandboxRuntimeMessage = [\n 'Local sandbox is enabled, but @anthropic-ai/sandbox-runtime is not installed.',\n 'Install it with `npm install @anthropic-ai/sandbox-runtime`, or disable local sandboxing with `local.sandbox.enabled: false`.',\n].join(' ');\nconst sandboxRuntimePackage = '@anthropic-ai/sandbox-runtime';\n\n/** Lazy-loads the ESM-only sandbox runtime only when sandboxing is enabled. */\nfunction loadSandboxRuntime(): Promise<SandboxRuntimeModule> {\n sandboxRuntimePromise ??= import(\n sandboxRuntimePackage\n ) as Promise<SandboxRuntimeModule>;\n return sandboxRuntimePromise;\n}\n\nfunction shouldUseLocalSandbox(config: t.LocalExecutionConfig): boolean {\n return config.sandbox?.enabled === true;\n}\n\nlet sandboxOffWarned = false;\n\nfunction maybeWarnSandboxOff(config: t.LocalExecutionConfig): void {\n if (sandboxOffWarned || shouldUseLocalSandbox(config)) {\n return;\n }\n sandboxOffWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[@librechat/agents] Local execution engine is running without ' +\n '@anthropic-ai/sandbox-runtime wrapping. The agent has full access to ' +\n 'the host filesystem and network. Set toolExecution.local.sandbox.enabled ' +\n '= true to opt into process sandboxing.'\n );\n}\n\n/**\n * Test-only reset hook for the sandbox-off warning latch.\n *\n * @internal Not part of the public SDK surface.\n */\nexport function _resetLocalEngineWarningsForTests(): void {\n sandboxOffWarned = false;\n}\n\nexport function truncateLocalOutput(\n value: string,\n maxChars = DEFAULT_MAX_OUTPUT_CHARS\n): string {\n if (value.length <= maxChars) {\n return value;\n }\n const head = Math.floor(maxChars * 0.6);\n const tail = maxChars - head;\n const omitted = value.length - maxChars;\n return `${value.slice(0, head)}\\n\\n[... ${omitted} characters truncated ...]\\n\\n${value.slice(\n value.length - tail\n )}`;\n}\n\nfunction stripQuotedContent(command: string): string {\n let output = '';\n let quote: '\"' | '\\'' | '`' | undefined;\n let escaped = false;\n\n for (let i = 0; i < command.length; i++) {\n const char = command[i];\n\n if (escaped) {\n escaped = false;\n output += ' ';\n continue;\n }\n\n if (char === '\\\\') {\n escaped = true;\n output += ' ';\n continue;\n }\n\n if (quote != null) {\n if (char === quote) {\n quote = undefined;\n }\n output += ' ';\n continue;\n }\n\n if (char === '\"' || char === '\\'' || char === '`') {\n quote = char;\n output += ' ';\n continue;\n }\n\n if (char === '#') {\n while (i < command.length && command[i] !== '\\n') {\n output += ' ';\n i++;\n }\n output += '\\n';\n continue;\n }\n\n output += char;\n }\n\n return output;\n}\n\nexport async function validateBashCommand(\n command: string,\n config: t.LocalExecutionConfig = {}\n): Promise<BashValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n const normalized = stripQuotedContent(command);\n\n if (command.trim() === '') {\n errors.push('Command is empty.');\n }\n\n if (command.includes('\\0')) {\n errors.push('Command contains a NUL byte.');\n }\n\n if (config.allowDangerousCommands !== true) {\n let blocked = false;\n // Strip-then-match for the bare-form patterns (avoids false\n // positives where the destructive text is buried inside a\n // string the user is just printing).\n for (const pattern of dangerousCommandPatterns) {\n if (pattern.test(normalized)) {\n errors.push('Command matches a destructive command pattern.');\n blocked = true;\n break;\n }\n }\n // Original-form pass for patterns that REQUIRE matching quote\n // pairs around a destructive path. Without this, `rm -rf \"/\"`\n // and `chmod -R 777 \"/\"` slip past the strip-then-match pass\n // because their destructive target is inside quotes.\n if (!blocked) {\n for (const pattern of quotedDestructivePatterns) {\n if (pattern.test(command)) {\n errors.push(\n 'Command matches a destructive command pattern (quoted target).'\n );\n blocked = true;\n break;\n }\n }\n }\n if (!blocked) {\n for (const pattern of nestedShellDestructivePatterns) {\n if (pattern.test(command)) {\n errors.push(\n 'Command matches a destructive command pattern (nested shell payload).'\n );\n break;\n }\n }\n }\n }\n\n const bashAstMode = config.bashAst ?? 'off';\n if (bashAstMode !== 'off' && config.allowDangerousCommands !== true) {\n const findings = runBashAstChecks(normalized, bashAstMode);\n const split = bashAstFindingsToErrors(findings);\n errors.push(...split.errors);\n warnings.push(...split.warnings);\n }\n\n if (config.readOnly === true && mutatingCommandPattern.test(normalized)) {\n errors.push(\n 'Command appears to mutate files or repository state in read-only local mode.'\n );\n }\n\n // Use the same shell the actual execution path will use. Hard-coding\n // DEFAULT_SHELL here would reject perfectly valid commands when the\n // host configures `local.shell` to a non-bash binary (or when the\n // runtime doesn't have bash installed at all but does have e.g. zsh).\n const syntaxShell = config.shell ?? DEFAULT_SHELL;\n const syntax = await spawnLocalProcess(\n syntaxShell,\n ['-n', '-c', command],\n {\n ...config,\n timeoutMs: Math.min(config.timeoutMs ?? DEFAULT_TIMEOUT_MS, 5000),\n sandbox: { enabled: false },\n },\n { internal: true }\n ).catch(\n (error: Error): SpawnResult => ({\n stdout: '',\n stderr: error.message,\n exitCode: 1,\n timedOut: false,\n })\n );\n\n if (syntax.exitCode !== 0) {\n errors.push(\n syntax.stderr.trim() === ''\n ? 'Command failed shell syntax validation.'\n : `Command failed shell syntax validation: ${syntax.stderr.trim()}`\n );\n }\n\n if (/\\bsudo\\b/.test(normalized)) {\n warnings.push('Command requests elevated privileges with sudo.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\nasync function ensureSandbox(\n config: t.LocalExecutionConfig,\n cwd: string\n): Promise<SandboxManagerType | undefined> {\n if (!shouldUseLocalSandbox(config)) {\n return undefined;\n }\n\n const runtime = await loadSandboxRuntime().catch((error: Error) => {\n throw new Error(`${missingSandboxRuntimeMessage} Cause: ${error.message}`);\n });\n\n const runtimeConfig = buildSandboxRuntimeConfig(\n config,\n cwd,\n runtime.getDefaultWritePaths\n );\n const nextKey = JSON.stringify(runtimeConfig);\n\n if (sandboxInitialized && sandboxConfigKey === nextKey) {\n return runtime.SandboxManager;\n }\n\n const dependencyCheck = runtime.SandboxManager.checkDependencies();\n if (dependencyCheck.errors.length > 0) {\n if (config.sandbox?.failIfUnavailable === true) {\n throw new Error(\n `Local sandbox requested but unavailable: ${dependencyCheck.errors.join('; ')}`\n );\n }\n return undefined;\n }\n\n if (sandboxInitialized) {\n await runtime.SandboxManager.reset();\n }\n\n await runtime.SandboxManager.initialize(runtimeConfig);\n sandboxInitialized = true;\n sandboxConfigKey = nextKey;\n return runtime.SandboxManager;\n}\n\n/**\n * Loopback addresses the in-process programmatic-tool bridge listens\n * on (`LocalProgrammaticToolCalling.ts` binds 127.0.0.1). Sandboxed\n * code launched by `run_tools_with_code` / `run_tools_with_bash` HTTPs\n * back to that address — without the entries below, the bridge is\n * silently blocked under sandbox.\n */\nconst BRIDGE_LOOPBACK_HOSTS = ['127.0.0.1', 'localhost', '::1'] as const;\n\n/**\n * Structural shape of the sandbox-runtime config we hand to\n * `SandboxManager.initialize()`. Intentionally NOT typed as the peer\n * `SandboxRuntimeConfig` from `@anthropic-ai/sandbox-runtime`: that\n * package is an OPTIONAL peer dep, and exporting a function whose\n * return type references it would make our generated `.d.ts` import\n * a module the consumer may not have installed (Codex P1 #22 — type-\n * checking would fail with `Cannot find module\n * '@anthropic-ai/sandbox-runtime'` for any host that doesn't enable\n * local sandboxing). The shape here is a structural subset; assignable\n * to the real `SandboxRuntimeConfig` at the one runtime call site.\n *\n * @internal\n */\nexport interface BuiltSandboxRuntimeConfig {\n network: {\n allowedDomains: string[];\n deniedDomains: string[];\n allowUnixSockets?: string[];\n allowAllUnixSockets?: boolean;\n allowLocalBinding?: boolean;\n allowMachLookup?: string[];\n };\n filesystem: {\n denyRead: string[];\n allowRead?: string[];\n allowWrite: string[];\n denyWrite: string[];\n allowGitConfig?: boolean;\n };\n}\n\nexport function buildSandboxRuntimeConfig(\n config: t.LocalExecutionConfig,\n cwd: string,\n getDefaultWritePaths: () => string[]\n): BuiltSandboxRuntimeConfig {\n const sandbox = config.sandbox;\n // Seed allowedDomains with loopback so the programmatic-tool bridge\n // works under sandbox. If the host explicitly denied a loopback\n // entry via `deniedDomains`, respect that and skip seeding it.\n const userAllowed = sandbox?.network?.allowedDomains ?? [];\n const denied = new Set(sandbox?.network?.deniedDomains ?? []);\n const seededLoopback = BRIDGE_LOOPBACK_HOSTS.filter(\n (host) => !denied.has(host) && !userAllowed.includes(host)\n );\n const allowedDomains = [...seededLoopback, ...userAllowed];\n // Mirror the file-tools workspace boundary: anything in\n // `additionalRoots` counts as in-workspace, so sandboxed shell/code\n // can write there too. Without this, file_tools can resolve a\n // sibling-root path but `bash`/`execute_code` is denied write\n // access — confusing divergence flagged in Codex P2 #15.\n const workspaceWriteRoots =\n config.workspace?.additionalRoots != null\n ? getWorkspaceRoots(config)\n : [cwd];\n return {\n network: {\n allowedDomains,\n deniedDomains: sandbox?.network?.deniedDomains ?? [],\n ...(sandbox?.network?.allowUnixSockets != null && {\n allowUnixSockets: sandbox.network.allowUnixSockets,\n }),\n ...(sandbox?.network?.allowAllUnixSockets != null && {\n allowAllUnixSockets: sandbox.network.allowAllUnixSockets,\n }),\n ...(sandbox?.network?.allowLocalBinding != null && {\n allowLocalBinding: sandbox.network.allowLocalBinding,\n }),\n ...(sandbox?.network?.allowMachLookup != null && {\n allowMachLookup: sandbox.network.allowMachLookup,\n }),\n },\n filesystem: {\n denyRead: sandbox?.filesystem?.denyRead ?? [],\n allowRead: sandbox?.filesystem?.allowRead,\n allowWrite: sandbox?.filesystem?.allowWrite ?? [\n ...workspaceWriteRoots,\n ...getDefaultWritePaths(),\n ],\n denyWrite: sandbox?.filesystem?.denyWrite ?? [\n '.env',\n '.env.*',\n '.git/config',\n '.git/hooks/**',\n ],\n allowGitConfig: sandbox?.filesystem?.allowGitConfig,\n },\n };\n}\n\n/**\n * Internal options for {@link spawnLocalProcess} that we don't want\n * exposed on the public `LocalExecutionConfig` type.\n *\n * @internal\n */\nexport interface SpawnLocalProcessOptions {\n /**\n * When true, suppress the \"sandbox is off\" warning AND its latch\n * for this spawn. Use for SDK-internal probes (`bash -n` syntax\n * preflight, `rg --version`, etc.) that intentionally run with\n * the sandbox forced off — the warning is noise for those, and\n * letting the latch flip would hide the warning when a *real*\n * unsandboxed execution happens later in the same process.\n */\n internal?: boolean;\n}\n\nexport async function spawnLocalProcess(\n command: string,\n args: string[],\n config: t.LocalExecutionConfig = {},\n options?: SpawnLocalProcessOptions\n): Promise<SpawnResult> {\n const cwd = getLocalCwd(config);\n const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const maxOutputChars = config.maxOutputChars ?? DEFAULT_MAX_OUTPUT_CHARS;\n // Streaming caps. Local tools execute arbitrary shell/code, so a noisy\n // command (`yes`, `cat /dev/urandom | base64`, a verbose build) could\n // accumulate gigabytes in memory before hitting the post-close cap.\n // We bound in-memory per-stream and spill the rest to disk; we also\n // hard-kill the child once total streamed bytes pass `maxSpawnedBytes`\n // so a process producing unbounded output gets stopped instead of\n // letting the host OOM.\n const inMemoryCapBytes = maxOutputChars * 2;\n const hardKillBytes = config.maxSpawnedBytes ?? DEFAULT_MAX_SPAWNED_BYTES;\n const sandboxManager = await ensureSandbox(config, cwd);\n // Internal probes (validateBashCommand syntax preflight,\n // isRipgrepAvailable, syntax-check probe cache priming) pass\n // `internal: true` so they don't emit a misleading \"sandbox is\n // off\" warning AND don't flip `sandboxOffWarned = true`. Without\n // this Codex P2 path: a run with `sandbox.enabled: true` would\n // see a false warning from the syntax preflight, and the latch\n // flip would suppress the warning in a *later* truly-unsandboxed\n // run — exactly the scenario operators need to see.\n if (sandboxManager == null && options?.internal !== true) {\n maybeWarnSandboxOff(config);\n }\n let spawnCommand = command;\n let spawnArgs = args;\n\n if (sandboxManager != null) {\n const rendered = [command, ...args.map(shellQuote)].join(' ');\n const sandboxed = await sandboxManager.wrapWithSandbox(rendered);\n spawnCommand = config.shell ?? DEFAULT_SHELL;\n spawnArgs = ['-lc', sandboxed];\n }\n\n const launcher = getSpawn(config);\n return new Promise<SpawnResult>((resolveResult, reject) => {\n const child = launcher(spawnCommand, spawnArgs, {\n cwd,\n detached: process.platform !== 'win32',\n env: { ...process.env, ...(config.env ?? {}) },\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n let totalSpawnedBytes = 0;\n let overflowKilled = false;\n let spillStream: import('fs').WriteStream | undefined;\n let spillPath: string | undefined;\n let settled = false;\n let timedOut = false;\n let timeout: NodeJS.Timeout | undefined;\n\n const ensureSpill = (): void => {\n if (spillStream != null) return;\n // Lazy-open the temp file the first time a stream's in-memory\n // buffer overflows. Seed it with everything we've buffered so\n // the file holds the FULL output (not just the post-cap tail).\n // Uses the static `createWriteStream` import — `require('fs')`\n // would throw `ReferenceError: require is not defined` in ESM\n // consumers (this package ships both `dist/cjs` and `dist/esm`).\n spillPath = resolve(tmpdir(), `lc-local-output-${randomUUID()}.txt`);\n spillStream = createWriteStream(spillPath);\n spillStream.write('===== stdout =====\\n');\n spillStream.write(stdout);\n spillStream.write('\\n===== stderr =====\\n');\n spillStream.write(stderr);\n spillStream.write('\\n===== overflow stream begins here =====\\n');\n };\n\n const handleChunk = (buf: Buffer, kind: 'stdout' | 'stderr'): void => {\n totalSpawnedBytes += buf.length;\n // hardKillBytes <= 0 means \"no cap\" per the public config contract\n // (see LocalExecutionConfig.maxSpawnedBytes). Skip the kill check\n // entirely in that case so a single byte doesn't terminate the run.\n if (\n hardKillBytes > 0 &&\n totalSpawnedBytes > hardKillBytes &&\n !overflowKilled\n ) {\n overflowKilled = true;\n killProcessTree(child);\n return;\n }\n const current = kind === 'stdout' ? stdout : stderr;\n if (current.length < inMemoryCapBytes) {\n const text = buf.toString('utf8');\n if (kind === 'stdout') stdout += text;\n else stderr += text;\n if (current.length + text.length >= inMemoryCapBytes) {\n ensureSpill();\n }\n } else {\n ensureSpill();\n spillStream!.write(`[${kind}] `);\n spillStream!.write(buf);\n }\n };\n\n const finish = (result: SpawnResult): void => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeout != null) {\n clearTimeout(timeout);\n }\n const finalize = (): void => {\n const truncated = {\n stdout: truncateLocalOutput(result.stdout, maxOutputChars),\n stderr: truncateLocalOutput(result.stderr, maxOutputChars),\n };\n resolveResult({\n ...result,\n ...truncated,\n ...(spillPath != null ? { fullOutputPath: spillPath } : {}),\n });\n };\n if (spillStream == null) {\n finalize();\n return;\n }\n // Wait for the temp file to flush before reporting the path.\n // Otherwise the model sees `full_output_path: …` for a file\n // that's still being written.\n spillStream.end(() => finalize());\n };\n\n const fail = (error: Error): void => {\n if (settled) {\n return;\n }\n settled = true;\n if (timeout != null) {\n clearTimeout(timeout);\n }\n if (spillStream != null) {\n spillStream.end();\n }\n reject(error);\n };\n\n if (timeoutMs > 0) {\n timeout = setTimeout(() => {\n timedOut = true;\n killProcessTree(child);\n }, timeoutMs);\n }\n\n child.stdout.on('data', (chunk: Buffer) => {\n handleChunk(chunk, 'stdout');\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n handleChunk(chunk, 'stderr');\n });\n\n child.on('error', fail);\n\n child.on('close', (exitCode, signal) => {\n // Synthesize a non-zero exit code whenever the process exited\n // by signal — Node reports `exitCode: null` in that case and\n // the formatter only prints non-null exit codes, so signal\n // kills (overflow guard, `kill -9 $$` from inside the script,\n // native crashes, OS OOM killer, …) would otherwise look like\n // successful runs (Codex P1 + Codex P2). Overflow path keeps\n // its 137 (SIGKILL) for compatibility; other signals map per\n // POSIX `128 + signum`.\n let finalExit: number | null = exitCode;\n if (finalExit == null) {\n if (overflowKilled) {\n finalExit = 137;\n } else if (signal != null) {\n finalExit = exitCodeForSignal(signal);\n }\n }\n finish({\n stdout,\n stderr,\n exitCode: finalExit,\n timedOut,\n ...(overflowKilled ? { overflowKilled: true } : {}),\n ...(signal != null ? { signal } : {}),\n });\n });\n });\n}\n\nexport async function executeLocalBash(\n command: string,\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n const validation = await validateBashCommand(command, config);\n if (!validation.valid) {\n throw new Error(validation.errors.join('\\n'));\n }\n const shell = config.shell ?? DEFAULT_SHELL;\n return spawnLocalProcess(shell, ['-lc', command], config);\n}\n\n/**\n * Variant of `executeLocalBash` that exposes `args` as positional\n * shell parameters (`$1`, `$2`, …). Mirrors what the other runtimes\n * do in `getRuntimeCommand`. Uses the standard `bash -c <code> --\n * arg0 arg1 …` form: the `--` becomes `$0`, then `args[0]` is `$1`\n * and so on. Same AST validation as the no-args path.\n *\n * Used by both the `execute_code`/`lang:'bash'` path AND the\n * `bash_tool` factory so the schema's `args` contract works\n * identically in both surfaces.\n */\n/**\n * Matches a single arg that, on its own, references a protected\n * location (`/`, `~`, `$HOME`, `${HOME}`, `.`, with optional trailing\n * slash, wildcard, or dot-glob suffix). Used to spot the\n * `command: 'rm -rf \"$1\"', args: ['/']` shape where the destructive\n * target is moved into a positional arg to evade the command regex.\n * Codex P1 [45], extended for dot-glob in Codex P1 [47] (mirrors the\n * `DESTRUCTIVE_TARGET` suffix matrix exactly).\n */\nconst PROTECTED_TARGET_ARG_RE = /^(?:\\/|~|\\$\\{?HOME\\}?|\\.)(?:\\/?\\.?\\*|\\/)?$/;\n\n/**\n * Mutating-op recognizer for the args check. Conservative: only the\n * three operations the destructive-command guard already covers\n * directly (`rm -rf …`, `chmod -R …`, `chown -R …`). Other shell\n * builtins might mutate state (`mv`, `cp` over an existing file,\n * etc.) but the destructive guard doesn't try to catch those today,\n * so we don't widen here either.\n */\nconst DESTRUCTIVE_OP_IN_COMMAND_RE =\n /\\b(?:rm\\s+-[^\\s]*[rf]|chmod\\s+-R|chown\\s+-R)\\b/;\n\nexport async function executeLocalBashWithArgs(\n command: string,\n args: readonly string[],\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n const validation = await validateBashCommand(command, config);\n if (!validation.valid) {\n throw new Error(validation.errors.join('\\n'));\n }\n // Per-arg protected-target check (Codex P1 [45]). The command\n // regex can't see `$1`/`$@` substitutions at runtime — `command:\n // 'rm -rf \"$1\"', args: ['/']` would expand to `rm -rf '/'` inside\n // bash but the validator only saw `rm -rf \"$1\"` (no destructive\n // target). Block when (a) the command contains a destructive op\n // AND (b) at least one arg matches the protected-target shape.\n // Skipped when allowDangerousCommands is true (host-opted-in).\n if (\n args.length > 0 &&\n config.allowDangerousCommands !== true &&\n DESTRUCTIVE_OP_IN_COMMAND_RE.test(command)\n ) {\n const offending = args.find((a) => PROTECTED_TARGET_ARG_RE.test(a));\n if (offending !== undefined) {\n throw new Error(\n `Command matches a destructive command pattern (protected target \"${offending}\" passed via positional arg).`\n );\n }\n }\n const shell = config.shell ?? DEFAULT_SHELL;\n return spawnLocalProcess(shell, ['-lc', command, '--', ...args], config);\n}\n\nexport async function executeLocalCode(\n input: {\n lang: string;\n code: string;\n args?: string[];\n },\n config: t.LocalExecutionConfig = {}\n): Promise<SpawnResult> {\n if (input.lang === 'bash') {\n // Append `args` as positional parameters via the standard\n // `bash -c <code> -- <args...>` form so `$1`, `$2`, … inside\n // `code` resolve correctly. Honours the same args contract the\n // other runtimes (py, js, …) already support.\n if (input.args != null && input.args.length > 0) {\n return executeLocalBashWithArgs(input.code, input.args, config);\n }\n return executeLocalBash(input.code, config);\n }\n\n const tempDir = resolve(tmpdir(), `lc-local-${randomUUID()}`);\n await mkdir(tempDir, { recursive: true });\n\n try {\n const runtime = getRuntimeCommand(\n input.lang,\n tempDir,\n input.code,\n input.args,\n config.shell\n );\n if (runtime.source != null) {\n await writeFile(\n resolve(tempDir, runtime.fileName),\n runtime.source,\n 'utf8'\n );\n }\n return await spawnLocalProcess(runtime.command, runtime.args, config);\n } finally {\n await rm(tempDir, { recursive: true, force: true });\n }\n}\n\nfunction getRuntimeCommand(\n lang: string,\n tempDir: string,\n code: string,\n args: string[] = [],\n // Override for the shell used by compile-style runtimes (`rs`,\n // `c`, `cpp`, `java`, `d`, `f90`). Threads `local.shell` so a host\n // that doesn't have bash (or wants `/bin/sh` / zsh) can still\n // execute these languages — Codex P2 #29: the bare-bash hardcode\n // mirrored the same gap that Codex P1 #6 fixed for the syntax\n // preflight, but had been missed for these runtime invocations.\n shellOverride?: string\n): RuntimeCommand {\n const fileFor = (name: string): string => resolve(tempDir, name);\n const shell = shellOverride ?? configShell();\n\n switch (lang) {\n case 'py':\n return {\n command: 'python3',\n args: [fileFor('main.py'), ...args],\n fileName: 'main.py',\n source: code,\n };\n case 'js':\n return {\n command: 'node',\n args: [fileFor('main.js'), ...args],\n fileName: 'main.js',\n source: code,\n };\n case 'ts':\n return {\n command: 'npx',\n args: ['--no-install', 'tsx', fileFor('main.ts'), ...args],\n fileName: 'main.ts',\n source: code,\n };\n case 'php':\n return {\n command: 'php',\n args: [fileFor('main.php'), ...args],\n fileName: 'main.php',\n source: code,\n };\n case 'go':\n return {\n command: 'go',\n args: ['run', fileFor('main.go'), ...args],\n fileName: 'main.go',\n source: code,\n };\n case 'rs':\n return {\n command: shell,\n args: [\n '-lc',\n `rustc ${shellQuote(fileFor('main.rs'))} -o ${shellQuote(\n fileFor('main-rs')\n )} && ${shellQuote(fileFor('main-rs'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.rs',\n source: code,\n };\n case 'c':\n return {\n command: shell,\n args: [\n '-lc',\n `cc ${shellQuote(fileFor('main.c'))} -o ${shellQuote(\n fileFor('main-c')\n )} && ${shellQuote(fileFor('main-c'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.c',\n source: code,\n };\n case 'cpp':\n return {\n command: shell,\n args: [\n '-lc',\n `c++ ${shellQuote(fileFor('main.cpp'))} -o ${shellQuote(\n fileFor('main-cpp')\n )} && ${shellQuote(fileFor('main-cpp'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.cpp',\n source: code,\n };\n case 'java':\n return {\n command: shell,\n args: [\n '-lc',\n `javac ${shellQuote(fileFor('Main.java'))} && java -cp ${shellQuote(\n tempDir\n )} Main ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'Main.java',\n source: code,\n };\n case 'r':\n return {\n command: 'Rscript',\n args: [fileFor('main.R'), ...args],\n fileName: 'main.R',\n source: code,\n };\n case 'd':\n return {\n command: shell,\n args: [\n '-lc',\n `dmd ${shellQuote(fileFor('main.d'))} -of=${shellQuote(\n fileFor('main-d')\n )} && ${shellQuote(fileFor('main-d'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.d',\n source: code,\n };\n case 'f90':\n return {\n command: shell,\n args: [\n '-lc',\n `gfortran ${shellQuote(fileFor('main.f90'))} -o ${shellQuote(\n fileFor('main-f90')\n )} && ${shellQuote(fileFor('main-f90'))} ${args.map(shellQuote).join(' ')}`,\n ],\n fileName: 'main.f90',\n source: code,\n };\n default:\n throw new Error(`Unsupported local runtime: ${lang}`);\n }\n}\n\nfunction configShell(): string {\n return process.platform === 'win32' ? 'bash.exe' : 'bash';\n}\n\n/**\n * How long after SIGTERM we wait before escalating to SIGKILL. A\n * cooperative process gets a graceful chance to flush + clean up;\n * a process that ignores or traps SIGTERM (`trap '' TERM`) gets\n * killed unconditionally so timeoutMs / maxSpawnedBytes can't be\n * defeated by a hostile script. Codex P1 #28 — pre-fix the spawn\n * promise would never resolve in that case and the entire tool run\n * would hang past the advertised timeout.\n */\nconst SIGKILL_ESCALATION_MS = 2000;\n\nfunction sigterm(child: ChildProcess): void {\n if (child.pid == null) return;\n try {\n if (process.platform === 'win32') {\n child.kill('SIGTERM');\n return;\n }\n process.kill(-child.pid, 'SIGTERM');\n } catch {\n child.kill('SIGTERM');\n }\n}\n\nfunction sigkill(child: ChildProcess): void {\n if (child.pid == null) return;\n if (child.exitCode != null || child.signalCode != null) return;\n try {\n if (process.platform === 'win32') {\n child.kill('SIGKILL');\n return;\n }\n process.kill(-child.pid, 'SIGKILL');\n } catch {\n try {\n child.kill('SIGKILL');\n } catch {\n /* already dead */\n }\n }\n}\n\nfunction killProcessTree(child: ChildProcess): void {\n sigterm(child);\n // Escalate to SIGKILL if the child is still alive after the grace\n // window. Use unref() so the timer doesn't keep the Node process\n // alive past the parent's natural exit.\n const escalation = setTimeout(() => sigkill(child), SIGKILL_ESCALATION_MS);\n escalation.unref();\n child.once('close', () => clearTimeout(escalation));\n}\n\nexport function shellQuote(value: string): string {\n if (value === '') {\n return '\\'\\'';\n }\n if (/^[A-Za-z0-9_/:=.,@%+-]+$/.test(value)) {\n return value;\n }\n return `'${value.replace(/'/g, '\\'\\\\\\'\\'')}'`;\n}\n\nexport function resolveWorkspacePath(\n filePath: string,\n config: t.LocalExecutionConfig = {},\n intent: 'read' | 'write' = 'write'\n): string {\n const cwd = getLocalCwd(config);\n const absolutePath = isAbsolute(filePath)\n ? resolve(filePath)\n : resolve(cwd, filePath);\n\n const roots =\n intent === 'write' ? getWriteRoots(config) : getReadRoots(config);\n if (roots == null) return absolutePath; // explicit allow-outside\n\n if (absolutePath === cwd || isInsideAnyRoot(absolutePath, roots)) {\n return absolutePath;\n }\n throw new Error(`Path is outside the local workspace: ${filePath}`);\n}\n\nfunction isInsideAnyRoot(absolutePath: string, roots: string[]): boolean {\n for (const root of roots) {\n if (absolutePath === root) return true;\n const rel = relative(root, absolutePath);\n if (!rel.startsWith('..') && !isAbsolute(rel)) return true;\n }\n return false;\n}\n\ntype RealpathFn = (p: string) => Promise<string>;\n\nasync function realpathOrSelf(\n absolutePath: string,\n realpathImpl: RealpathFn = realpath\n): Promise<string> {\n try {\n return await realpathImpl(absolutePath);\n } catch {\n return absolutePath;\n }\n}\n\n/**\n * Resolves the realpath of `absolutePath`, falling back to the nearest\n * existing ancestor when the target itself does not yet exist (so the\n * containment check still works for `write_file` to a brand-new path).\n *\n * Codex P2 #38: takes the realpath impl as a parameter so callers\n * can route through `WorkspaceFS.realpath` when a custom engine is\n * configured. Pre-fix, host `fs/promises.realpath` would fail on a\n * remote/in-memory FS path and silently fall back to lexical\n * containment, leaving the symlink-escape clamp ineffective on\n * non-default engines.\n */\nasync function realpathOfPathOrAncestor(\n absolutePath: string,\n realpathImpl: RealpathFn = realpath\n): Promise<string> {\n let current = absolutePath;\n let suffix = '';\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n try {\n const real = await realpathImpl(current);\n return suffix === '' ? real : resolve(real, suffix);\n } catch {\n const parent = resolve(current, '..');\n if (parent === current) {\n return absolutePath;\n }\n const base = current.slice(parent.length + 1);\n suffix = suffix === '' ? base : `${base}/${suffix}`;\n current = parent;\n }\n }\n}\n\n/**\n * Resolves a workspace path AND follows any symlinks before checking\n * containment, so a symlink inside the workspace pointing outside is\n * rejected even though the lexical path looks safe. Handles paths that\n * don't yet exist (e.g. write_file targets) by realpath-resolving the\n * nearest existing ancestor and re-attaching the unresolved suffix.\n */\nexport async function resolveWorkspacePathSafe(\n filePath: string,\n config: t.LocalExecutionConfig = {},\n intent: 'read' | 'write' = 'write'\n): Promise<string> {\n const lexical = resolveWorkspacePath(filePath, config, intent);\n const roots =\n intent === 'write' ? getWriteRoots(config) : getReadRoots(config);\n if (roots == null) {\n return lexical;\n }\n // Route realpath through the configured WorkspaceFS so a custom\n // engine (in-memory, remote) gets the same symlink-escape clamp\n // the host-fs path gets. Codex P2 #38: pre-fix the host realpath\n // would fail on a non-default FS path and silently fall back to\n // lexical containment, leaving the clamp ineffective.\n const fsRealpath: RealpathFn = (p) => getWorkspaceFS(config).realpath(p);\n const realRoots = await Promise.all(\n roots.map((r) => realpathOrSelf(r, fsRealpath))\n );\n const realPath = await realpathOfPathOrAncestor(lexical, fsRealpath);\n if (isInsideAnyRoot(realPath, realRoots)) {\n return lexical;\n }\n throw new Error(\n `Path is outside the local workspace (symlink escape): ${filePath}`\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -150,6 +150,35 @@ class SubagentExecutor {
|
|
|
150
150
|
* nested trace pollution).
|
|
151
151
|
*/
|
|
152
152
|
const callbacks = forwarder ? [forwarder] : [];
|
|
153
|
+
/**
|
|
154
|
+
* Inherit the parent's `configurable` verbatim — host-set fields
|
|
155
|
+
* (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-
|
|
156
|
+
* identity fields (`run_id`, `parent_run_id`, `thread_id`) all
|
|
157
|
+
* propagate.
|
|
158
|
+
*
|
|
159
|
+
* Run-identity propagation is intentional and matches the
|
|
160
|
+
* convention this executor itself already uses for `SubagentStart`
|
|
161
|
+
* / `SubagentStop` hooks (`sessionId: this.parentRunId`): the
|
|
162
|
+
* subagent runs under the parent's session scope, not its own.
|
|
163
|
+
* Forwarding `run_id` / `parent_run_id` / `thread_id` makes
|
|
164
|
+
* `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),
|
|
165
|
+
* `ToolOutputReferenceRegistry` keying, and trace lineage all
|
|
166
|
+
* resolve to the parent's session for tools dispatched from the
|
|
167
|
+
* subagent — so `PreToolUse` / `PostToolUse` hooks the host
|
|
168
|
+
* registered against the parent's run fire for subagent tool
|
|
169
|
+
* calls too. "Same run" matches the user-perceptual mental model.
|
|
170
|
+
*
|
|
171
|
+
* `thread_id` falls back to `childRunId` only when the parent
|
|
172
|
+
* didn't supply one (legacy behavior preserved for hosts that
|
|
173
|
+
* never set thread_id).
|
|
174
|
+
*
|
|
175
|
+
* NOTE: a future revision will likely make this configurable per
|
|
176
|
+
* spawn type — e.g. a background / async subagent that runs after
|
|
177
|
+
* the parent's run completes wants isolation, not inheritance.
|
|
178
|
+
* For now the inheritance path matches LibreChat's primary use
|
|
179
|
+
* case (synchronous subagents within a single user turn).
|
|
180
|
+
*/
|
|
181
|
+
const inheritedConfigurable = params.parentConfigurable ?? {};
|
|
153
182
|
result = await workflow.invoke({ messages: [new HumanMessage(description)] }, {
|
|
154
183
|
recursionLimit: maxTurns * RECURSION_MULTIPLIER,
|
|
155
184
|
signal: this.parentSignal,
|
|
@@ -157,6 +186,7 @@ class SubagentExecutor {
|
|
|
157
186
|
runName: `subagent:${subagentType}`,
|
|
158
187
|
configurable: {
|
|
159
188
|
thread_id: childRunId,
|
|
189
|
+
...inheritedConfigurable,
|
|
160
190
|
},
|
|
161
191
|
});
|
|
162
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SubagentExecutor.mjs","sources":["../../../../src/tools/subagent/SubagentExecutor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type {\n AgentInputs,\n StandardGraphInput,\n ResolvedSubagentConfig,\n SubagentConfig,\n SubagentUpdateEvent,\n SubagentUpdatePhase,\n ToolExecuteBatchRequest,\n TokenCounter,\n} from '@/types';\nimport type { AggregatedHookResult, HookRegistry } from '@/hooks';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type { StandardGraph } from '@/graphs/Graph';\nimport { GraphEvents, Callback } from '@/common';\nimport type { HandlerRegistry } from '@/events';\nimport { executeHooks } from '@/hooks';\n\nconst DEFAULT_MAX_TURNS = 25;\nconst RECURSION_MULTIPLIER = 3;\nconst ERROR_MESSAGE_MAX_CHARS = 200;\n\nconst HOOK_FALLBACK: AggregatedHookResult = Object.freeze({\n additionalContexts: [] as string[],\n errors: [] as string[],\n});\n\nexport type SubagentExecuteParams = {\n description: string;\n subagentType: string;\n threadId?: string;\n /**\n * Parent-side `tool_call_id` of the `subagent` tool invocation that\n * triggered this execution. Surfaced on {@link SubagentUpdateEvent} so\n * hosts can correlate child updates back to the originating tool call\n * without relying on event ordering heuristics.\n */\n parentToolCallId?: string;\n};\n\nexport type SubagentExecuteResult = {\n content: string;\n messages: BaseMessage[];\n};\n\n/**\n * Factory that constructs a child graph for subagent execution. Injected\n * rather than imported so that `SubagentExecutor` does not have a runtime\n * dependency on `StandardGraph` — this avoids a circular dependency between\n * `src/graphs/Graph.ts` and `src/tools/subagent/` that would otherwise break\n * Rollup's chunking under `preserveModules`.\n */\nexport type ChildGraphFactory = (input: StandardGraphInput) => StandardGraph;\n\nexport type SubagentExecutorOptions = {\n configs: Map<string, ResolvedSubagentConfig>;\n parentSignal?: AbortSignal;\n hookRegistry?: HookRegistry;\n parentRunId: string;\n parentAgentId?: string;\n tokenCounter?: TokenCounter;\n /** Remaining nesting budget. 0 or negative blocks execution. */\n maxDepth?: number;\n /**\n * Factory for constructing the isolated child graph. Callers pass\n * `(input) => new StandardGraph(input)` — injected to break a circular\n * module dependency.\n */\n createChildGraph: ChildGraphFactory;\n /**\n * Parent's event handler registry. When provided, child-graph events are\n * forwarded through this registry so hosts can:\n * (a) execute event-driven tools (`ON_TOOL_EXECUTE` routed to parent's handler),\n * (b) surface child activity to a UI via wrapped {@link GraphEvents.ON_SUBAGENT_UPDATE}.\n * When omitted, the child runs fully isolated (legacy behavior).\n *\n * Can be a direct `HandlerRegistry` or a zero-arg getter — use the getter\n * form when the registry is assigned to the graph AFTER the executor is\n * constructed (the current `Run.create` flow sets `handlerRegistry`\n * post-`createWorkflow`, so `createAgentNode` must capture lazily).\n */\n parentHandlerRegistry?: HandlerRegistry | (() => HandlerRegistry | undefined);\n};\n\nexport class SubagentExecutor {\n private readonly configs: Map<string, ResolvedSubagentConfig>;\n private readonly parentSignal?: AbortSignal;\n private readonly hookRegistry?: HookRegistry;\n private readonly parentRunId: string;\n private readonly parentAgentId?: string;\n private readonly tokenCounter?: TokenCounter;\n private readonly maxDepth: number;\n private readonly createChildGraph: ChildGraphFactory;\n private readonly resolveParentHandlerRegistry?: () =>\n | HandlerRegistry\n | undefined;\n\n constructor(options: SubagentExecutorOptions) {\n this.configs = options.configs;\n this.parentSignal = options.parentSignal;\n this.hookRegistry = options.hookRegistry;\n this.parentRunId = options.parentRunId;\n this.parentAgentId = options.parentAgentId;\n this.tokenCounter = options.tokenCounter;\n this.maxDepth = options.maxDepth ?? 1;\n this.createChildGraph = options.createChildGraph;\n const rawRegistry = options.parentHandlerRegistry;\n if (typeof rawRegistry === 'function') {\n this.resolveParentHandlerRegistry = rawRegistry;\n } else if (rawRegistry != null) {\n this.resolveParentHandlerRegistry = (): HandlerRegistry => rawRegistry;\n }\n }\n\n /** Snapshot of the parent's registry at the moment a subagent is dispatched. */\n private getParentHandlerRegistry(): HandlerRegistry | undefined {\n return this.resolveParentHandlerRegistry?.();\n }\n\n async execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult> {\n const { description, subagentType, threadId, parentToolCallId } = params;\n const config = this.configs.get(subagentType);\n\n if (!config) {\n const available = [...this.configs.keys()].join(', ');\n return {\n content: `Error: Unknown subagent type \"${subagentType}\". Available types: ${available}`,\n messages: [],\n };\n }\n\n if (this.maxDepth <= 0) {\n return {\n content: 'Error: Maximum subagent nesting depth exceeded.',\n messages: [],\n };\n }\n\n const childAgentId =\n config.agentInputs.agentId ||\n `${this.parentAgentId ?? 'agent'}_sub_${nanoid(8)}`;\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStart', this.parentRunId) === true\n ) {\n const hookResult = await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStart',\n runId: this.parentRunId,\n threadId,\n parentAgentId: this.parentAgentId,\n agentId: childAgentId,\n agentType: subagentType,\n inputs: [new HumanMessage(description)],\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch((): AggregatedHookResult => HOOK_FALLBACK);\n\n /**\n * `ask` is treated identically to `deny` in the subagent context:\n * subagents are non-interactive, so there is no prompt path for `ask`.\n * Both decisions block execution and return a \"Blocked\" tool result.\n */\n if (hookResult.decision === 'deny' || hookResult.decision === 'ask') {\n return {\n content: `Blocked: ${hookResult.reason ?? 'Blocked by hook'}`,\n messages: [],\n };\n }\n }\n\n const parentRegistry = this.getParentHandlerRegistry();\n const forwardingEnabled = parentRegistry != null;\n /**\n * Keep `toolDefinitions` only when the host has actually wired an\n * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,\n * so treating any registry as \"forwarding enabled\" would leak\n * `toolDefinitions` into children whose hosts cannot execute them — the\n * child's `ToolNode` batch promise would hang forever with no handler to\n * resolve/reject. Gating on the tool-execute handler preserves the\n * recoverable \"no tools\" path for registry-but-no-handler configs.\n */\n const hasToolExecuteHandler =\n parentRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) != null;\n const childInputs = buildChildInputs(\n config,\n childAgentId,\n this.maxDepth,\n /* keepToolDefinitions */ hasToolExecuteHandler\n );\n const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;\n const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;\n\n const childGraph = this.createChildGraph({\n runId: childRunId,\n signal: this.parentSignal,\n agents: [childInputs],\n tokenCounter: this.tokenCounter,\n });\n\n const forwarder = forwardingEnabled\n ? this.createForwarderCallback({\n parentRegistry: parentRegistry!,\n subagentType,\n subagentAgentId: childAgentId,\n childRunId,\n parentToolCallId,\n })\n : undefined;\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'start',\n label: `Subagent \"${subagentType}\" started`,\n });\n }\n\n let result: { messages: BaseMessage[] };\n try {\n const workflow = childGraph.createWorkflow();\n /**\n * When `parentHandlerRegistry` is provided (forwarding mode), attach a\n * lightweight callback that intercepts the child's `on_custom_event`\n * dispatches and routes them to the parent's registry — either as\n * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE\n * envelopes. Native LangChain streaming events (on_chat_model_stream,\n * etc.) still do NOT propagate to the parent's outer streamEvents\n * iterator — the `callbacks` array REPLACES the inherited chain, so\n * parent handlers won't receive child stream chunks and raise \"No\n * agent context found\" lookups on the parent's agentContexts map.\n *\n * When no registry is provided (legacy isolation), `callbacks: []`\n * fully detaches the child.\n *\n * `runName` gives the child a distinct LangSmith trace root (avoids\n * nested trace pollution).\n */\n const callbacks: Callbacks = forwarder ? [forwarder] : [];\n result = await workflow.invoke(\n { messages: [new HumanMessage(description)] },\n {\n recursionLimit: maxTurns * RECURSION_MULTIPLIER,\n signal: this.parentSignal,\n callbacks,\n runName: `subagent:${subagentType}`,\n configurable: {\n thread_id: childRunId,\n },\n }\n );\n } catch (error) {\n const errorMessage = truncateErrorMessage(error);\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'error',\n label: `Subagent \"${subagentType}\" errored: ${errorMessage}`,\n data: { message: errorMessage },\n });\n }\n childGraph.clearHeavyState();\n return {\n content: `Subagent error: ${errorMessage}`,\n messages: [],\n };\n }\n\n const filteredContent = filterSubagentResult(result.messages);\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStop', this.parentRunId) === true\n ) {\n /**\n * Awaited (not fire-and-forget) for deterministic test synchronization\n * and consistency with PostCompact. The parent is already waiting on the\n * tool result, so the small extra latency is acceptable. Errors are\n * swallowed — SubagentStop is observational.\n */\n await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStop',\n runId: this.parentRunId,\n threadId,\n agentId: childAgentId,\n agentType: subagentType,\n messages: result.messages,\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch(() => {\n /* SubagentStop is observational — swallow errors */\n });\n }\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'stop',\n label: `Subagent \"${subagentType}\" finished`,\n });\n }\n\n childGraph.clearHeavyState();\n\n return { content: filteredContent, messages: result.messages };\n }\n\n /**\n * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the\n * parent's handler registry. Silent no-op when no parent registry is set.\n * Errors are swallowed — update events are observational.\n */\n private async emitSubagentUpdate(\n parentRegistry: HandlerRegistry,\n args: {\n childRunId: string;\n subagentType: string;\n subagentAgentId: string;\n parentToolCallId?: string;\n phase: SubagentUpdatePhase;\n data?: unknown;\n label?: string;\n }\n ): Promise<void> {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: this.parentRunId,\n subagentRunId: args.childRunId,\n subagentType: args.subagentType,\n subagentAgentId: args.subagentAgentId,\n parentAgentId: this.parentAgentId,\n parentToolCallId: args.parentToolCallId,\n phase: args.phase,\n data: args.data,\n label: args.label,\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n }\n\n /**\n * Builds a BaseCallbackHandler that intercepts the child graph's custom\n * events. Routing rules:\n * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE\n * handler (so event-driven tools work identically for child and parent).\n * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /\n * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a\n * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable\n * label, delivered to the parent's subagent-update handler.\n * - Everything else → ignored (keeps parent's UI scoped to the events it\n * cares about; host apps can extend by registering more phases).\n */\n private createForwarderCallback(args: {\n parentRegistry: HandlerRegistry;\n subagentType: string;\n subagentAgentId: string;\n childRunId: string;\n parentToolCallId?: string;\n }): BaseCallbackHandler {\n const {\n parentRegistry,\n subagentType,\n subagentAgentId,\n childRunId,\n parentToolCallId,\n } = args;\n const parentRunId = this.parentRunId;\n const parentAgentId = this.parentAgentId;\n\n const wrap = async (\n eventName: string,\n phase: SubagentUpdatePhase,\n data: unknown\n ): Promise<void> => {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: parentRunId,\n subagentRunId: childRunId,\n subagentType,\n subagentAgentId,\n parentAgentId,\n parentToolCallId,\n phase,\n data,\n label: summarizeEvent(eventName, data),\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n };\n\n const handler = BaseCallbackHandler.fromMethods({\n [Callback.CUSTOM_EVENT]: async (\n eventName: string,\n data: unknown\n ): Promise<void> => {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const toolHandler = parentRegistry.getHandler(\n GraphEvents.ON_TOOL_EXECUTE\n );\n if (toolHandler) {\n await toolHandler.handle(\n GraphEvents.ON_TOOL_EXECUTE,\n data as ToolExecuteBatchRequest\n );\n }\n /**\n * We also surface a short notice in the subagent-update stream so\n * the UI can show \"calling <tool>\" for each tool the child spawns.\n */\n await wrap(eventName, 'run_step', data);\n return;\n }\n\n if (eventName === GraphEvents.ON_RUN_STEP) {\n await wrap(eventName, 'run_step', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {\n await wrap(eventName, 'run_step_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n await wrap(eventName, 'run_step_completed', data);\n return;\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n await wrap(eventName, 'message_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_REASONING_DELTA) {\n await wrap(eventName, 'reasoning_delta', data);\n return;\n }\n },\n });\n /**\n * `awaitHandlers = true` is required so the child's `ToolNode` actually\n * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves\n * the batch request. The same flag applies to observational events\n * (message_delta, run_step, …), which means a slow\n * `ON_SUBAGENT_UPDATE` handler on the host serializes the child\n * stream. If host-side latency becomes a concern, a future\n * refinement could split operational and observational events into\n * separate callback handlers with distinct await semantics.\n */\n handler.awaitHandlers = true;\n return handler;\n }\n}\n\n/**\n * Produces a short single-line label for an arbitrary forwarded child event.\n * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show\n * a compact status ticker without parsing the raw payload.\n */\nexport function summarizeEvent(eventName: string, data: unknown): string {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const req = data as { toolCalls?: Array<{ name?: string }> };\n const names = (req.toolCalls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0 ? `Calling ${names.join(', ')}` : 'Calling tool';\n }\n if (eventName === GraphEvents.ON_RUN_STEP) {\n const step = data as {\n type?: string;\n stepDetails?: { type?: string; tool_calls?: Array<{ name?: string }> };\n };\n const detailType = step.stepDetails?.type ?? step.type ?? 'step';\n if (detailType === 'tool_calls') {\n const names = (step.stepDetails?.tool_calls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0\n ? `Using tool: ${names.join(', ')}`\n : 'Planning tool call';\n }\n if (detailType === 'message_creation') {\n return 'Thinking…';\n }\n return `Step: ${detailType}`;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const step = data as {\n result?: {\n type?: string;\n tool_call?: { name?: string; output?: string };\n };\n };\n const tool = step.result?.tool_call;\n if (tool?.name != null && tool.name !== '') {\n return `Tool ${tool.name} complete`;\n }\n return 'Step complete';\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n return 'Streaming…';\n }\n return eventName;\n}\n\n/**\n * Walk messages from last to first, returning the text content of the most\n * recent AIMessage that has any. Non-text blocks (tool_use, thinking,\n * redacted_thinking, tool_result) are stripped. If the last AIMessage is\n * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk\n * continues to earlier AIMessages so partial progress is salvaged — this\n * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.\n * Returns \"Task completed\" only when no AIMessage in the history contains\n * any text.\n */\nexport function filterSubagentResult(messages: BaseMessage[]): string {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]._getType() !== 'ai') {\n continue;\n }\n\n const content = messages[i].content;\n\n if (typeof content === 'string') {\n if (content) return content;\n continue;\n }\n\n if (!Array.isArray(content)) {\n continue;\n }\n\n const textParts: string[] = [];\n for (const block of content) {\n if (typeof block === 'string') {\n textParts.push(block);\n } else if ('type' in block && block.type === 'text' && 'text' in block) {\n textParts.push(block.text as string);\n }\n }\n\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return 'Task completed';\n}\n\n/**\n * Resolve self-spawn configs by filling in agentInputs from the parent context.\n * Returns configs with agentInputs guaranteed present. Throws on duplicate\n * `type` values to prevent silent config shadowing.\n */\nexport function resolveSubagentConfigs(\n configs: SubagentConfig[],\n parentContext: AgentContext\n): ResolvedSubagentConfig[] {\n const resolved = configs\n .map((config) => {\n if (config.agentInputs != null) {\n return config as ResolvedSubagentConfig;\n }\n if (config.self !== true || parentContext._sourceInputs == null) {\n return null;\n }\n return {\n ...config,\n agentInputs: { ...parentContext._sourceInputs },\n } as ResolvedSubagentConfig;\n })\n .filter((c): c is ResolvedSubagentConfig => c != null);\n\n const seenTypes = new Set<string>();\n for (const config of resolved) {\n if (seenTypes.has(config.type)) {\n throw new Error(\n `Duplicate subagent type \"${config.type}\". Each SubagentConfig must have a unique \"type\" field.`\n );\n }\n seenTypes.add(config.type);\n }\n\n return resolved;\n}\n\n/**\n * Build child AgentInputs from a resolved config, stripping nesting and\n * (optionally) event-driven fields. When `allowNested: true`, the child's\n * `maxSubagentDepth` is decremented so that depth is consumed as the call\n * chain deepens across graph boundaries — the parent's executor-level check\n * alone cannot see into the child graph's separate executor.\n *\n * When `keepToolDefinitions` is `true`, the child retains the parent's\n * `toolDefinitions` so event-driven tools remain usable. This is only safe\n * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a\n * registered handler — otherwise the child will hang on tool dispatch.\n *\n * @remarks Advanced utility: exported primarily for testing and by\n * {@link SubagentExecutor}. Host applications configuring subagents should\n * not need to call this directly — it is invoked internally when a subagent\n * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,\n * child's decremented `maxSubagentDepth` on the returned inputs) is the\n * mechanism that bounds nesting across graph boundaries; callers must\n * respect it.\n */\nexport function buildChildInputs(\n config: ResolvedSubagentConfig,\n childAgentId: string,\n parentMaxDepth: number,\n keepToolDefinitions: boolean = false\n): AgentInputs {\n const { agentInputs } = config;\n const childInputs: AgentInputs = {\n ...agentInputs,\n agentId: childAgentId,\n toolDefinitions: keepToolDefinitions\n ? agentInputs.toolDefinitions\n : undefined,\n /**\n * Subagents run in an isolated context by contract. Parent-run-scoped\n * fields that would otherwise survive the shallow-spread clone — the\n * cross-run conversation summary and the prior-turn tool-discovery\n * set — are cleared here so the child starts fresh. Host applications\n * that want a subagent to see parent context must thread it in\n * explicitly (e.g. via the `description` argument to the subagent\n * tool), not via inherited state.\n */\n initialSummary: undefined,\n discoveredTools: undefined,\n };\n\n if (config.allowNested === true) {\n childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);\n } else {\n childInputs.subagentConfigs = undefined;\n childInputs.maxSubagentDepth = undefined;\n }\n\n return childInputs;\n}\n\nfunction truncateErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n if (message.length <= ERROR_MESSAGE_MAX_CHARS) {\n return message;\n }\n return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SubagentExecutor.mjs","sources":["../../../../src/tools/subagent/SubagentExecutor.ts"],"sourcesContent":["import { nanoid } from 'nanoid';\nimport { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type {\n AgentInputs,\n StandardGraphInput,\n ResolvedSubagentConfig,\n SubagentConfig,\n SubagentUpdateEvent,\n SubagentUpdatePhase,\n ToolExecuteBatchRequest,\n TokenCounter,\n} from '@/types';\nimport type { AggregatedHookResult, HookRegistry } from '@/hooks';\nimport type { AgentContext } from '@/agents/AgentContext';\nimport type { StandardGraph } from '@/graphs/Graph';\nimport { GraphEvents, Callback } from '@/common';\nimport type { HandlerRegistry } from '@/events';\nimport { executeHooks } from '@/hooks';\n\nconst DEFAULT_MAX_TURNS = 25;\nconst RECURSION_MULTIPLIER = 3;\nconst ERROR_MESSAGE_MAX_CHARS = 200;\n\nconst HOOK_FALLBACK: AggregatedHookResult = Object.freeze({\n additionalContexts: [] as string[],\n errors: [] as string[],\n});\n\nexport type SubagentExecuteParams = {\n description: string;\n subagentType: string;\n threadId?: string;\n /**\n * Parent-side `tool_call_id` of the `subagent` tool invocation that\n * triggered this execution. Surfaced on {@link SubagentUpdateEvent} so\n * hosts can correlate child updates back to the originating tool call\n * without relying on event ordering heuristics.\n */\n parentToolCallId?: string;\n /**\n * Snapshot of the parent invocation's `config.configurable` at the\n * spawn-tool call site. Inherited verbatim into the child workflow's\n * `configurable` so host-set fields (`requestBody`, `user`,\n * `userMCPAuthMap`, etc.) propagate — fixing MCP body-placeholder\n * substitution and per-user lookups for subagent tool calls.\n *\n * Inheritance details (verified empirically against LangGraph):\n * - host-set keys propagate as-is into the child's tool dispatches;\n * - `thread_id` propagates (with `childRunId` as a fallback when\n * parent did not supply one) — matches the \"subagent is part of\n * the same conversation\" mental model and aligns with the\n * `sessionId: this.parentRunId` convention this executor already\n * uses for `SubagentStart` / `SubagentStop` hooks;\n * - `parent_run_id` propagates when the host put it on parent's\n * configurable;\n * - `run_id` is *overwritten by the LangGraph runtime* at child\n * invoke time regardless of what we forward — child's tool\n * dispatches see the child graph's runtime runId in\n * `configurable.run_id`, not the parent's. Hosts that need\n * parent-scoped run identity for downstream consumers should\n * plumb it via a host-defined key (e.g. `requestBody.messageId`),\n * not `run_id`.\n *\n * A future revision will likely make this inheritance configurable\n * per spawn type — background / async subagents may want isolation\n * rather than sharing parent's host context.\n */\n parentConfigurable?: Record<string, unknown>;\n};\n\nexport type SubagentExecuteResult = {\n content: string;\n messages: BaseMessage[];\n};\n\n/**\n * Factory that constructs a child graph for subagent execution. Injected\n * rather than imported so that `SubagentExecutor` does not have a runtime\n * dependency on `StandardGraph` — this avoids a circular dependency between\n * `src/graphs/Graph.ts` and `src/tools/subagent/` that would otherwise break\n * Rollup's chunking under `preserveModules`.\n */\nexport type ChildGraphFactory = (input: StandardGraphInput) => StandardGraph;\n\nexport type SubagentExecutorOptions = {\n configs: Map<string, ResolvedSubagentConfig>;\n parentSignal?: AbortSignal;\n hookRegistry?: HookRegistry;\n parentRunId: string;\n parentAgentId?: string;\n tokenCounter?: TokenCounter;\n /** Remaining nesting budget. 0 or negative blocks execution. */\n maxDepth?: number;\n /**\n * Factory for constructing the isolated child graph. Callers pass\n * `(input) => new StandardGraph(input)` — injected to break a circular\n * module dependency.\n */\n createChildGraph: ChildGraphFactory;\n /**\n * Parent's event handler registry. When provided, child-graph events are\n * forwarded through this registry so hosts can:\n * (a) execute event-driven tools (`ON_TOOL_EXECUTE` routed to parent's handler),\n * (b) surface child activity to a UI via wrapped {@link GraphEvents.ON_SUBAGENT_UPDATE}.\n * When omitted, the child runs fully isolated (legacy behavior).\n *\n * Can be a direct `HandlerRegistry` or a zero-arg getter — use the getter\n * form when the registry is assigned to the graph AFTER the executor is\n * constructed (the current `Run.create` flow sets `handlerRegistry`\n * post-`createWorkflow`, so `createAgentNode` must capture lazily).\n */\n parentHandlerRegistry?: HandlerRegistry | (() => HandlerRegistry | undefined);\n};\n\nexport class SubagentExecutor {\n private readonly configs: Map<string, ResolvedSubagentConfig>;\n private readonly parentSignal?: AbortSignal;\n private readonly hookRegistry?: HookRegistry;\n private readonly parentRunId: string;\n private readonly parentAgentId?: string;\n private readonly tokenCounter?: TokenCounter;\n private readonly maxDepth: number;\n private readonly createChildGraph: ChildGraphFactory;\n private readonly resolveParentHandlerRegistry?: () =>\n | HandlerRegistry\n | undefined;\n\n constructor(options: SubagentExecutorOptions) {\n this.configs = options.configs;\n this.parentSignal = options.parentSignal;\n this.hookRegistry = options.hookRegistry;\n this.parentRunId = options.parentRunId;\n this.parentAgentId = options.parentAgentId;\n this.tokenCounter = options.tokenCounter;\n this.maxDepth = options.maxDepth ?? 1;\n this.createChildGraph = options.createChildGraph;\n const rawRegistry = options.parentHandlerRegistry;\n if (typeof rawRegistry === 'function') {\n this.resolveParentHandlerRegistry = rawRegistry;\n } else if (rawRegistry != null) {\n this.resolveParentHandlerRegistry = (): HandlerRegistry => rawRegistry;\n }\n }\n\n /** Snapshot of the parent's registry at the moment a subagent is dispatched. */\n private getParentHandlerRegistry(): HandlerRegistry | undefined {\n return this.resolveParentHandlerRegistry?.();\n }\n\n async execute(params: SubagentExecuteParams): Promise<SubagentExecuteResult> {\n const { description, subagentType, threadId, parentToolCallId } = params;\n const config = this.configs.get(subagentType);\n\n if (!config) {\n const available = [...this.configs.keys()].join(', ');\n return {\n content: `Error: Unknown subagent type \"${subagentType}\". Available types: ${available}`,\n messages: [],\n };\n }\n\n if (this.maxDepth <= 0) {\n return {\n content: 'Error: Maximum subagent nesting depth exceeded.',\n messages: [],\n };\n }\n\n const childAgentId =\n config.agentInputs.agentId ||\n `${this.parentAgentId ?? 'agent'}_sub_${nanoid(8)}`;\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStart', this.parentRunId) === true\n ) {\n const hookResult = await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStart',\n runId: this.parentRunId,\n threadId,\n parentAgentId: this.parentAgentId,\n agentId: childAgentId,\n agentType: subagentType,\n inputs: [new HumanMessage(description)],\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch((): AggregatedHookResult => HOOK_FALLBACK);\n\n /**\n * `ask` is treated identically to `deny` in the subagent context:\n * subagents are non-interactive, so there is no prompt path for `ask`.\n * Both decisions block execution and return a \"Blocked\" tool result.\n */\n if (hookResult.decision === 'deny' || hookResult.decision === 'ask') {\n return {\n content: `Blocked: ${hookResult.reason ?? 'Blocked by hook'}`,\n messages: [],\n };\n }\n }\n\n const parentRegistry = this.getParentHandlerRegistry();\n const forwardingEnabled = parentRegistry != null;\n /**\n * Keep `toolDefinitions` only when the host has actually wired an\n * `ON_TOOL_EXECUTE` handler. `Run` always constructs a `HandlerRegistry`,\n * so treating any registry as \"forwarding enabled\" would leak\n * `toolDefinitions` into children whose hosts cannot execute them — the\n * child's `ToolNode` batch promise would hang forever with no handler to\n * resolve/reject. Gating on the tool-execute handler preserves the\n * recoverable \"no tools\" path for registry-but-no-handler configs.\n */\n const hasToolExecuteHandler =\n parentRegistry?.getHandler(GraphEvents.ON_TOOL_EXECUTE) != null;\n const childInputs = buildChildInputs(\n config,\n childAgentId,\n this.maxDepth,\n /* keepToolDefinitions */ hasToolExecuteHandler\n );\n const childRunId = `${this.parentRunId}_sub_${nanoid(8)}`;\n const maxTurns = config.maxTurns ?? DEFAULT_MAX_TURNS;\n\n const childGraph = this.createChildGraph({\n runId: childRunId,\n signal: this.parentSignal,\n agents: [childInputs],\n tokenCounter: this.tokenCounter,\n });\n\n const forwarder = forwardingEnabled\n ? this.createForwarderCallback({\n parentRegistry: parentRegistry!,\n subagentType,\n subagentAgentId: childAgentId,\n childRunId,\n parentToolCallId,\n })\n : undefined;\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'start',\n label: `Subagent \"${subagentType}\" started`,\n });\n }\n\n let result: { messages: BaseMessage[] };\n try {\n const workflow = childGraph.createWorkflow();\n /**\n * When `parentHandlerRegistry` is provided (forwarding mode), attach a\n * lightweight callback that intercepts the child's `on_custom_event`\n * dispatches and routes them to the parent's registry — either as\n * operational events (ON_TOOL_EXECUTE) or wrapped ON_SUBAGENT_UPDATE\n * envelopes. Native LangChain streaming events (on_chat_model_stream,\n * etc.) still do NOT propagate to the parent's outer streamEvents\n * iterator — the `callbacks` array REPLACES the inherited chain, so\n * parent handlers won't receive child stream chunks and raise \"No\n * agent context found\" lookups on the parent's agentContexts map.\n *\n * When no registry is provided (legacy isolation), `callbacks: []`\n * fully detaches the child.\n *\n * `runName` gives the child a distinct LangSmith trace root (avoids\n * nested trace pollution).\n */\n const callbacks: Callbacks = forwarder ? [forwarder] : [];\n /**\n * Inherit the parent's `configurable` verbatim — host-set fields\n * (`requestBody`, `user`, `userMCPAuthMap`, etc.) AND the run-\n * identity fields (`run_id`, `parent_run_id`, `thread_id`) all\n * propagate.\n *\n * Run-identity propagation is intentional and matches the\n * convention this executor itself already uses for `SubagentStart`\n * / `SubagentStop` hooks (`sessionId: this.parentRunId`): the\n * subagent runs under the parent's session scope, not its own.\n * Forwarding `run_id` / `parent_run_id` / `thread_id` makes\n * `ToolNode`'s hook lookups (`hasHookFor(eventName, runId)`),\n * `ToolOutputReferenceRegistry` keying, and trace lineage all\n * resolve to the parent's session for tools dispatched from the\n * subagent — so `PreToolUse` / `PostToolUse` hooks the host\n * registered against the parent's run fire for subagent tool\n * calls too. \"Same run\" matches the user-perceptual mental model.\n *\n * `thread_id` falls back to `childRunId` only when the parent\n * didn't supply one (legacy behavior preserved for hosts that\n * never set thread_id).\n *\n * NOTE: a future revision will likely make this configurable per\n * spawn type — e.g. a background / async subagent that runs after\n * the parent's run completes wants isolation, not inheritance.\n * For now the inheritance path matches LibreChat's primary use\n * case (synchronous subagents within a single user turn).\n */\n const inheritedConfigurable: Record<string, unknown> =\n params.parentConfigurable ?? {};\n result = await workflow.invoke(\n { messages: [new HumanMessage(description)] },\n {\n recursionLimit: maxTurns * RECURSION_MULTIPLIER,\n signal: this.parentSignal,\n callbacks,\n runName: `subagent:${subagentType}`,\n configurable: {\n thread_id: childRunId,\n ...inheritedConfigurable,\n },\n }\n );\n } catch (error) {\n const errorMessage = truncateErrorMessage(error);\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'error',\n label: `Subagent \"${subagentType}\" errored: ${errorMessage}`,\n data: { message: errorMessage },\n });\n }\n childGraph.clearHeavyState();\n return {\n content: `Subagent error: ${errorMessage}`,\n messages: [],\n };\n }\n\n const filteredContent = filterSubagentResult(result.messages);\n\n if (\n this.hookRegistry?.hasHookFor('SubagentStop', this.parentRunId) === true\n ) {\n /**\n * Awaited (not fire-and-forget) for deterministic test synchronization\n * and consistency with PostCompact. The parent is already waiting on the\n * tool result, so the small extra latency is acceptable. Errors are\n * swallowed — SubagentStop is observational.\n */\n await executeHooks({\n registry: this.hookRegistry,\n input: {\n hook_event_name: 'SubagentStop',\n runId: this.parentRunId,\n threadId,\n agentId: childAgentId,\n agentType: subagentType,\n messages: result.messages,\n },\n sessionId: this.parentRunId,\n matchQuery: subagentType,\n }).catch(() => {\n /* SubagentStop is observational — swallow errors */\n });\n }\n\n if (forwarder) {\n await this.emitSubagentUpdate(parentRegistry!, {\n childRunId,\n subagentType,\n subagentAgentId: childAgentId,\n parentToolCallId,\n phase: 'stop',\n label: `Subagent \"${subagentType}\" finished`,\n });\n }\n\n childGraph.clearHeavyState();\n\n return { content: filteredContent, messages: result.messages };\n }\n\n /**\n * Emits a single {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope through the\n * parent's handler registry. Silent no-op when no parent registry is set.\n * Errors are swallowed — update events are observational.\n */\n private async emitSubagentUpdate(\n parentRegistry: HandlerRegistry,\n args: {\n childRunId: string;\n subagentType: string;\n subagentAgentId: string;\n parentToolCallId?: string;\n phase: SubagentUpdatePhase;\n data?: unknown;\n label?: string;\n }\n ): Promise<void> {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: this.parentRunId,\n subagentRunId: args.childRunId,\n subagentType: args.subagentType,\n subagentAgentId: args.subagentAgentId,\n parentAgentId: this.parentAgentId,\n parentToolCallId: args.parentToolCallId,\n phase: args.phase,\n data: args.data,\n label: args.label,\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n }\n\n /**\n * Builds a BaseCallbackHandler that intercepts the child graph's custom\n * events. Routing rules:\n * - `ON_TOOL_EXECUTE` → forwarded as-is to the parent's ON_TOOL_EXECUTE\n * handler (so event-driven tools work identically for child and parent).\n * - `ON_RUN_STEP` / `ON_RUN_STEP_DELTA` / `ON_RUN_STEP_COMPLETED` /\n * `ON_MESSAGE_DELTA` / `ON_REASONING_DELTA` → wrapped in a\n * {@link GraphEvents.ON_SUBAGENT_UPDATE} envelope with a human-readable\n * label, delivered to the parent's subagent-update handler.\n * - Everything else → ignored (keeps parent's UI scoped to the events it\n * cares about; host apps can extend by registering more phases).\n */\n private createForwarderCallback(args: {\n parentRegistry: HandlerRegistry;\n subagentType: string;\n subagentAgentId: string;\n childRunId: string;\n parentToolCallId?: string;\n }): BaseCallbackHandler {\n const {\n parentRegistry,\n subagentType,\n subagentAgentId,\n childRunId,\n parentToolCallId,\n } = args;\n const parentRunId = this.parentRunId;\n const parentAgentId = this.parentAgentId;\n\n const wrap = async (\n eventName: string,\n phase: SubagentUpdatePhase,\n data: unknown\n ): Promise<void> => {\n const handler = parentRegistry.getHandler(GraphEvents.ON_SUBAGENT_UPDATE);\n if (!handler) {\n return;\n }\n const event: SubagentUpdateEvent = {\n runId: parentRunId,\n subagentRunId: childRunId,\n subagentType,\n subagentAgentId,\n parentAgentId,\n parentToolCallId,\n phase,\n data,\n label: summarizeEvent(eventName, data),\n timestamp: new Date().toISOString(),\n };\n try {\n await handler.handle(GraphEvents.ON_SUBAGENT_UPDATE, event);\n } catch {\n /* observational — swallow */\n }\n };\n\n const handler = BaseCallbackHandler.fromMethods({\n [Callback.CUSTOM_EVENT]: async (\n eventName: string,\n data: unknown\n ): Promise<void> => {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const toolHandler = parentRegistry.getHandler(\n GraphEvents.ON_TOOL_EXECUTE\n );\n if (toolHandler) {\n await toolHandler.handle(\n GraphEvents.ON_TOOL_EXECUTE,\n data as ToolExecuteBatchRequest\n );\n }\n /**\n * We also surface a short notice in the subagent-update stream so\n * the UI can show \"calling <tool>\" for each tool the child spawns.\n */\n await wrap(eventName, 'run_step', data);\n return;\n }\n\n if (eventName === GraphEvents.ON_RUN_STEP) {\n await wrap(eventName, 'run_step', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_DELTA) {\n await wrap(eventName, 'run_step_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n await wrap(eventName, 'run_step_completed', data);\n return;\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n await wrap(eventName, 'message_delta', data);\n return;\n }\n if (eventName === GraphEvents.ON_REASONING_DELTA) {\n await wrap(eventName, 'reasoning_delta', data);\n return;\n }\n },\n });\n /**\n * `awaitHandlers = true` is required so the child's `ToolNode` actually\n * blocks on the parent's `ON_TOOL_EXECUTE` handler until it resolves\n * the batch request. The same flag applies to observational events\n * (message_delta, run_step, …), which means a slow\n * `ON_SUBAGENT_UPDATE` handler on the host serializes the child\n * stream. If host-side latency becomes a concern, a future\n * refinement could split operational and observational events into\n * separate callback handlers with distinct await semantics.\n */\n handler.awaitHandlers = true;\n return handler;\n }\n}\n\n/**\n * Produces a short single-line label for an arbitrary forwarded child event.\n * Used to populate {@link SubagentUpdateEvent.label} so the host UI can show\n * a compact status ticker without parsing the raw payload.\n */\nexport function summarizeEvent(eventName: string, data: unknown): string {\n if (eventName === GraphEvents.ON_TOOL_EXECUTE) {\n const req = data as { toolCalls?: Array<{ name?: string }> };\n const names = (req.toolCalls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0 ? `Calling ${names.join(', ')}` : 'Calling tool';\n }\n if (eventName === GraphEvents.ON_RUN_STEP) {\n const step = data as {\n type?: string;\n stepDetails?: { type?: string; tool_calls?: Array<{ name?: string }> };\n };\n const detailType = step.stepDetails?.type ?? step.type ?? 'step';\n if (detailType === 'tool_calls') {\n const names = (step.stepDetails?.tool_calls ?? [])\n .map((c) => c.name)\n .filter((n): n is string => typeof n === 'string');\n return names.length > 0\n ? `Using tool: ${names.join(', ')}`\n : 'Planning tool call';\n }\n if (detailType === 'message_creation') {\n return 'Thinking…';\n }\n return `Step: ${detailType}`;\n }\n if (eventName === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const step = data as {\n result?: {\n type?: string;\n tool_call?: { name?: string; output?: string };\n };\n };\n const tool = step.result?.tool_call;\n if (tool?.name != null && tool.name !== '') {\n return `Tool ${tool.name} complete`;\n }\n return 'Step complete';\n }\n if (eventName === GraphEvents.ON_MESSAGE_DELTA) {\n return 'Streaming…';\n }\n return eventName;\n}\n\n/**\n * Walk messages from last to first, returning the text content of the most\n * recent AIMessage that has any. Non-text blocks (tool_use, thinking,\n * redacted_thinking, tool_result) are stripped. If the last AIMessage is\n * pure tool_use (e.g. the subagent hit `maxTurns` mid-tool-call), the walk\n * continues to earlier AIMessages so partial progress is salvaged — this\n * matches Claude Code's behavior in `agentToolUtils.finalizeAgentTool`.\n * Returns \"Task completed\" only when no AIMessage in the history contains\n * any text.\n */\nexport function filterSubagentResult(messages: BaseMessage[]): string {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i]._getType() !== 'ai') {\n continue;\n }\n\n const content = messages[i].content;\n\n if (typeof content === 'string') {\n if (content) return content;\n continue;\n }\n\n if (!Array.isArray(content)) {\n continue;\n }\n\n const textParts: string[] = [];\n for (const block of content) {\n if (typeof block === 'string') {\n textParts.push(block);\n } else if ('type' in block && block.type === 'text' && 'text' in block) {\n textParts.push(block.text as string);\n }\n }\n\n if (textParts.length > 0) {\n return textParts.join('\\n');\n }\n }\n\n return 'Task completed';\n}\n\n/**\n * Resolve self-spawn configs by filling in agentInputs from the parent context.\n * Returns configs with agentInputs guaranteed present. Throws on duplicate\n * `type` values to prevent silent config shadowing.\n */\nexport function resolveSubagentConfigs(\n configs: SubagentConfig[],\n parentContext: AgentContext\n): ResolvedSubagentConfig[] {\n const resolved = configs\n .map((config) => {\n if (config.agentInputs != null) {\n return config as ResolvedSubagentConfig;\n }\n if (config.self !== true || parentContext._sourceInputs == null) {\n return null;\n }\n return {\n ...config,\n agentInputs: { ...parentContext._sourceInputs },\n } as ResolvedSubagentConfig;\n })\n .filter((c): c is ResolvedSubagentConfig => c != null);\n\n const seenTypes = new Set<string>();\n for (const config of resolved) {\n if (seenTypes.has(config.type)) {\n throw new Error(\n `Duplicate subagent type \"${config.type}\". Each SubagentConfig must have a unique \"type\" field.`\n );\n }\n seenTypes.add(config.type);\n }\n\n return resolved;\n}\n\n/**\n * Build child AgentInputs from a resolved config, stripping nesting and\n * (optionally) event-driven fields. When `allowNested: true`, the child's\n * `maxSubagentDepth` is decremented so that depth is consumed as the call\n * chain deepens across graph boundaries — the parent's executor-level check\n * alone cannot see into the child graph's separate executor.\n *\n * When `keepToolDefinitions` is `true`, the child retains the parent's\n * `toolDefinitions` so event-driven tools remain usable. This is only safe\n * when the caller has wired a forwarder for `ON_TOOL_EXECUTE` to a\n * registered handler — otherwise the child will hang on tool dispatch.\n *\n * @remarks Advanced utility: exported primarily for testing and by\n * {@link SubagentExecutor}. Host applications configuring subagents should\n * not need to call this directly — it is invoked internally when a subagent\n * tool is dispatched. The depth-countdown contract (parent's `maxDepth` in,\n * child's decremented `maxSubagentDepth` on the returned inputs) is the\n * mechanism that bounds nesting across graph boundaries; callers must\n * respect it.\n */\nexport function buildChildInputs(\n config: ResolvedSubagentConfig,\n childAgentId: string,\n parentMaxDepth: number,\n keepToolDefinitions: boolean = false\n): AgentInputs {\n const { agentInputs } = config;\n const childInputs: AgentInputs = {\n ...agentInputs,\n agentId: childAgentId,\n toolDefinitions: keepToolDefinitions\n ? agentInputs.toolDefinitions\n : undefined,\n /**\n * Subagents run in an isolated context by contract. Parent-run-scoped\n * fields that would otherwise survive the shallow-spread clone — the\n * cross-run conversation summary and the prior-turn tool-discovery\n * set — are cleared here so the child starts fresh. Host applications\n * that want a subagent to see parent context must thread it in\n * explicitly (e.g. via the `description` argument to the subagent\n * tool), not via inherited state.\n */\n initialSummary: undefined,\n discoveredTools: undefined,\n };\n\n if (config.allowNested === true) {\n childInputs.maxSubagentDepth = Math.max(0, parentMaxDepth - 1);\n } else {\n childInputs.subagentConfigs = undefined;\n childInputs.maxSubagentDepth = undefined;\n }\n\n return childInputs;\n}\n\nfunction truncateErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error);\n if (message.length <= ERROR_MESSAGE_MAX_CHARS) {\n return message;\n }\n return `${message.slice(0, ERROR_MESSAGE_MAX_CHARS)}...`;\n}\n"],"names":[],"mappings":"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"}
|