{"version":3,"file":"tools-B-JXNZhs.cjs","names":["SandboxFeatureNotSupportedError","z","createTool","isValidationError","z","createTool","createTool","z","MastraError","ErrorDomain","ErrorCategory","z","createTool"],"sources":["../src/tools/code-mode/stub-generator.ts","../src/tools/code-mode/runner.ts","../src/tools/code-mode/transport.ts","../src/tools/code-mode/code-mode.ts","../src/tools/builtin/ask-user.ts","../src/tools/builtin/web-fetch.ts","../src/tools/builtin/web-search.ts","../src/tools/builtin/submit-plan.ts"],"sourcesContent":["/**\n * Code Mode — Type stub generation\n *\n * Converts Mastra tools into TypeScript `declare function external_<id>(...)`\n * stubs and assembles the instructions the model sees. The pipeline is:\n *\n *   tool.inputSchema (StandardSchemaWithJSON)\n *     -> standardSchemaToJSONSchema()  (already in core, zod v3 + v4 + arktype)\n *     -> jsonSchemaToTsString()        (this file, synchronous, dependency-free)\n *     -> stub string\n *\n * Only the subset of JSON Schema that tool schemas actually produce is handled;\n * anything else degrades to `unknown`.\n */\n\nimport type { JSONSchema7, JSONSchema7Definition, JSONSchema7TypeName } from 'json-schema';\nimport type { ToolsInput } from '../../agent/types';\nimport { isStandardSchemaWithJSON, standardSchemaToJSONSchema } from '../../schema';\nimport type { StandardSchemaWithJSON } from '../../schema';\nimport type { CodeModeConfig } from './types';\n\n/** A valid TypeScript identifier? (used to decide quoting of object keys). */\nconst SAFE_IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n/**\n * Convert a JSON Schema (draft-07) node into a TypeScript type string.\n * Unsupported constructs return `unknown`.\n */\nexport function jsonSchemaToTsString(schema: JSONSchema7Definition | undefined): string {\n  if (schema === undefined) return 'unknown';\n  if (typeof schema === 'boolean') return schema ? 'unknown' : 'never';\n\n  // enum / const\n  if (schema.const !== undefined) return literal(schema.const);\n  if (Array.isArray(schema.enum)) {\n    return schema.enum.length ? schema.enum.map(literal).join(' | ') : 'never';\n  }\n\n  // unions\n  const union = schema.anyOf ?? schema.oneOf;\n  if (Array.isArray(union) && union.length) {\n    return union.map(jsonSchemaToTsString).join(' | ');\n  }\n\n  const type = normalizeType(schema.type);\n\n  if (type === 'object' || schema.properties) {\n    return objectType(schema);\n  }\n  if (type === 'array' || schema.items) {\n    return arrayType(schema);\n  }\n\n  switch (type) {\n    case 'string':\n      return 'string';\n    case 'number':\n    case 'integer':\n      return 'number';\n    case 'boolean':\n      return 'boolean';\n    case 'null':\n      return 'null';\n    default:\n      return 'unknown';\n  }\n}\n\nfunction normalizeType(type: JSONSchema7['type']): JSONSchema7TypeName | undefined {\n  if (Array.isArray(type)) {\n    // e.g. ['string', 'null'] — caller folds null in via nullability; pick the\n    // first non-null for the base type.\n    return type.find(t => t !== 'null');\n  }\n  return type;\n}\n\nfunction objectType(schema: JSONSchema7): string {\n  const props = schema.properties ?? {};\n  const required = new Set(schema.required ?? []);\n  const keys = Object.keys(props);\n\n  if (!keys.length) {\n    // Free-form object.\n    const additional = schema.additionalProperties;\n    if (additional !== undefined && additional !== false) {\n      const valueType = typeof additional === 'object' ? jsonSchemaToTsString(additional) : 'unknown';\n      return `Record<string, ${valueType}>`;\n    }\n    return 'Record<string, unknown>';\n  }\n\n  const fields = keys.map(key => {\n    const optional = !required.has(key) ? '?' : '';\n    const k = SAFE_IDENT.test(key) ? key : JSON.stringify(key);\n    return `${k}${optional}: ${jsonSchemaToTsString(props[key])}`;\n  });\n  return `{ ${fields.join('; ')} }`;\n}\n\nfunction arrayType(schema: JSONSchema7): string {\n  const items = schema.items;\n  if (Array.isArray(items)) {\n    // Tuple.\n    return `[${items.map(jsonSchemaToTsString).join(', ')}]`;\n  }\n  const inner = jsonSchemaToTsString(items);\n  // Use `Array<...>` form for top-level unions so `A | B[]` isn't misread as\n  // `A | (B[])`. Object literals and other forms use the `T[]` shorthand.\n  return isTopLevelUnion(inner) ? `Array<${inner}>` : `${inner}[]`;\n}\n\n/** True if `ts` is a union at the top level (a ` | ` not nested in braces/brackets). */\nfunction isTopLevelUnion(ts: string): boolean {\n  let depth = 0;\n  for (let i = 0; i < ts.length; i++) {\n    const c = ts[i];\n    if (c === '{' || c === '[' || c === '(' || c === '<') depth++;\n    else if (c === '}' || c === ']' || c === ')' || c === '>') depth--;\n    else if (c === '|' && depth === 0) return true;\n  }\n  return false;\n}\n\nfunction literal(value: unknown): string {\n  if (typeof value === 'string') return JSON.stringify(value);\n  if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n  if (value === null) return 'null';\n  return 'unknown';\n}\n\nfunction schemaToTs(schema: unknown, io: 'input' | 'output'): string {\n  if (!isStandardSchemaWithJSON(schema)) return 'unknown';\n  try {\n    const json = standardSchemaToJSONSchema(schema as StandardSchemaWithJSON, { io });\n    return jsonSchemaToTsString(json as JSONSchema7);\n  } catch {\n    return 'unknown';\n  }\n}\n\n/**\n * Strip non-identifier characters so a tool id is a legal function-name suffix.\n *\n * Transports that map `external_*` names back to tool ids must use this same\n * sanitizer so their naming stays identical to the generated stubs.\n */\nexport function sanitizeToolId(id: string): string {\n  const cleaned = id.replace(/[^A-Za-z0-9_$]/g, '_');\n  return SAFE_IDENT.test(cleaned) ? cleaned : `_${cleaned}`;\n}\n\n/** A single tool's TS declaration plus the original/sanitized id mapping. */\nexport interface CodeModeStub {\n  /** Original tool id (key used by the RPC dispatcher). */\n  toolId: string;\n  /** Sanitized identifier used in `external_<name>`. */\n  externalName: string;\n  /** The full `declare function ...` line(s). */\n  declaration: string;\n}\n\n/** Generate stubs for every tool in the config. */\nexport function generateStubs(tools: ToolsInput): CodeModeStub[] {\n  // Two distinct tool ids can sanitize to the same `external_*` name (e.g.\n  // `a-b` and `a_b`). Without this check the later binding would silently\n  // overwrite the earlier one in the runner, so fail fast instead.\n  const seen = new Map<string, string>();\n  return Object.entries(tools).map(([key, tool]) => {\n    const toolId = (tool as { id?: string }).id ?? key;\n    const description = (tool as { description?: string }).description;\n    const inputType = schemaToTs((tool as { inputSchema?: unknown }).inputSchema, 'input');\n    const outputType = schemaToTs((tool as { outputSchema?: unknown }).outputSchema, 'output');\n    const externalName = sanitizeToolId(toolId);\n\n    const prior = seen.get(externalName);\n    if (prior !== undefined && prior !== toolId) {\n      throw new Error(`Code Mode tool id collision: \"${prior}\" and \"${toolId}\" both map to external_${externalName}`);\n    }\n    seen.set(externalName, toolId);\n\n    const doc = description ? `/** ${description.replace(/\\*\\//g, '* /')} */\\n` : '';\n    const declaration = `${doc}declare function external_${externalName}(input: ${inputType}): Promise<${outputType}>;`;\n\n    return { toolId, externalName, declaration };\n  });\n}\n\nconst USAGE_CONTRACT = `# Code Mode\n\nYou have an \\`execute_typescript\\` tool. Instead of calling tools one at a time,\nwrite a single TypeScript program that orchestrates them and returns one result.\n\nRules:\n- Call the available tools via the \\`external_*\\` functions declared below. Each\n  returns a Promise — \\`await\\` it.\n- Batch independent calls with \\`Promise.all\\`. Do arithmetic and data shaping in\n  JavaScript, not in your head.\n- End the program by \\`return\\`-ing the final value (objects/arrays are fine).\n- The only supported capabilities are the \\`external_*\\` functions. Do not rely\n  on filesystem, network, or process access — depending on the configured\n  sandbox and transport, the program may run fully isolated with none of those\n  available.\n- Use \\`console.log\\` for debugging; logs are captured and returned.\n\nAvailable functions:`;\n\n/** Build the full instructions string (usage contract + stubs). */\nexport function createCodeModeInstructions(config: CodeModeConfig): string {\n  const stubs = generateStubs(config.tools);\n  const declarations = stubs.map(s => s.declaration).join('\\n\\n');\n  return `${USAGE_CONTRACT}\\n\\n${declarations}`;\n}\n","/**\n * Code Mode — Sandbox runner\n *\n * Builds the JavaScript program that runs *inside* the sandbox. The runner:\n *  - defines an `external_<name>` function per allow-listed tool, each of which\n *    emits a JSON-RPC request on the protocol channel and awaits its response\n *    (matched by `id`, so `Promise.all` calls resolve independently);\n *  - wraps the model's program in an async function, captures `console.*`, and\n *    emits a terminal `done` frame.\n *\n * Protocol (host <-> runner), newline-delimited JSON on stdout/stdin:\n *  - Frames the runner emits are prefixed with FRAME_PREFIX so the host can\n *    tell them apart from any stray output. Forms: `rpc`, `log`, `done`.\n *  - The host writes `rpc-result` frames to the runner stdin (no prefix).\n */\n\n/** Marks a line on stdout as a Code Mode protocol frame. */\nexport const FRAME_PREFIX = '\\u0000CODEMODE\\u0000';\n\nexport interface BuildRunnerOptions {\n  /**\n   * Module specifier the runner imports to obtain the user program. The\n   * referenced module must `export default` an async function (the wrapped\n   * model code). Written as a sibling `.ts` file so the sandbox's `node`\n   * strips the TypeScript types natively at import time.\n   */\n  programModule: string;\n  /** Map of `external_<name>` -> original tool id used in the RPC request. */\n  externals: Array<{ externalName: string; toolId: string }>;\n}\n\n/**\n * Wrap the model's TypeScript program as a default-exported async function\n * module. Written to a `.ts` file; Node strips the type annotations at import.\n * Top-level `return`, `await`, and `const` work because the body lives inside\n * an async function.\n */\nexport function buildProgramModule(program: string): string {\n  return `export default async function () {\\n${program}\\n}\\n`;\n}\n\n/**\n * Produce the full runner source to write into the sandbox and run with node.\n */\nexport function buildRunner({ programModule, externals }: BuildRunnerOptions): string {\n  // `buildRunner` is exported, so a caller could pass a non-sanitized name.\n  // External names become global property suffixes, so reject anything that\n  // isn't a legal identifier instead of producing an unusable global.\n  const SAFE_IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n  const seen = new Map<string, string>();\n  for (const { externalName, toolId } of externals) {\n    if (!SAFE_IDENT.test(externalName)) {\n      throw new Error(`Invalid Code Mode external identifier: ${externalName}`);\n    }\n    // Two tool ids can sanitize to the same external name (e.g. `a-b` and\n    // `a_b` both become `a_b`). The install loop below would silently overwrite\n    // the earlier global, leaving one tool unreachable. Fail fast instead.\n    const existing = seen.get(externalName);\n    if (existing) {\n      throw new Error(\n        `Code Mode external identifier collision: tools \"${existing}\" and \"${toolId}\" both map to external_${externalName}`,\n      );\n    }\n    seen.set(externalName, toolId);\n  }\n\n  // Externals are emitted as JSON data, not interpolated identifiers. The\n  // runner installs each `external_<name>` global in a loop using bracket\n  // assignment, so no caller-derived string is ever spliced into the generated\n  // source as code. This keeps tool ids strictly data, even if `sanitize`\n  // changes.\n  const externalsJson = JSON.stringify(externals.map(({ externalName, toolId }) => ({ externalName, toolId })));\n\n  return `'use strict';\nconst FRAME_PREFIX = ${JSON.stringify(FRAME_PREFIX)};\n\nfunction __emit(frame) {\n  process.stdout.write(FRAME_PREFIX + JSON.stringify(frame) + '\\\\n');\n}\n\nfunction __emitDoneAndExit(frame) {\n  process.stdout.write(FRAME_PREFIX + JSON.stringify(frame) + '\\\\n', () => process.exit(0));\n}\n\n// ---- console capture -------------------------------------------------------\nfor (const level of ['log', 'info', 'warn', 'error']) {\n  console[level] = (...args) => {\n    const message = args\n      .map((a) => (typeof a === 'string' ? a : safeStringify(a)))\n      .join(' ');\n    __emit({ type: 'log', level, message });\n  };\n}\nfunction safeStringify(value) {\n  try { return JSON.stringify(value); } catch { return String(value); }\n}\n\n// ---- RPC bridge ------------------------------------------------------------\nlet __nextId = 0;\nconst __pending = new Map();\n\nfunction __rpc(tool, args) {\n  const id = __nextId++;\n  return new Promise((resolve, reject) => {\n    __pending.set(id, { resolve, reject });\n    __emit({ type: 'rpc', id, tool, args });\n  });\n}\n\nlet __stdinBuffer = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', (chunk) => {\n  __stdinBuffer += chunk;\n  let idx;\n  while ((idx = __stdinBuffer.indexOf('\\\\n')) >= 0) {\n    const line = __stdinBuffer.slice(0, idx);\n    __stdinBuffer = __stdinBuffer.slice(idx + 1);\n    if (!line) continue;\n    let frame;\n    try { frame = JSON.parse(line); } catch { continue; }\n    if (frame && frame.type === 'rpc-result') {\n      const entry = __pending.get(frame.id);\n      if (!entry) continue;\n      __pending.delete(frame.id);\n      if (frame.ok) entry.resolve(frame.result);\n      else {\n        const err = new Error(frame.error?.message || 'external tool failed');\n        if (frame.error?.name) err.name = frame.error.name;\n        entry.reject(err);\n      }\n    }\n  }\n});\n\n// ---- externals -------------------------------------------------------------\nfor (const { externalName, toolId } of ${externalsJson}) {\n  globalThis['external_' + externalName] = (input) => __rpc(toolId, input);\n}\n\n// ---- user program ----------------------------------------------------------\n// The program lives in a sibling .ts module exporting a default async function;\n// node strips its TypeScript types natively on import.\nasync function __main() {\n  const mod = await import(${JSON.stringify(programModule)});\n  return await mod.default();\n}\n\n__main()\n  .then((result) => {\n    __emitDoneAndExit({ type: 'done', ok: true, result });\n  })\n  .catch((error) => {\n    __emitDoneAndExit({\n      type: 'done',\n      ok: false,\n      error: { message: error?.message ?? String(error), name: error?.name },\n    });\n  });\n`;\n}\n","/**\n * Code Mode — stdio JSON-RPC transport (v1)\n *\n * Runs the runner inside the sandbox via `sandbox.processes.spawn`, parses\n * protocol frames off stdout, dispatches `external_*` calls back to the host,\n * and writes results to the runner stdin. Abstracted behind\n * {@link CodeModeTransport} so socket/file-queue transports can be added for\n * remote sandboxes later.\n */\n\nimport { randomBytes } from 'node:crypto';\nimport { mkdtemp, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { SandboxFeatureNotSupportedError } from '../../workspace/errors';\nimport { buildRunner, buildProgramModule, FRAME_PREFIX } from './runner';\nimport { sanitizeToolId } from './stub-generator';\nimport type { CodeModeRunnerFrame, CodeModeToolResult, CodeModeTransport } from './types';\n\n/**\n * Default transport: writes the runner to a temp dir, spawns\n * `node <runner>`, and bridges RPC over stdio.\n */\nexport class StdioCodeModeTransport implements CodeModeTransport {\n  async run(opts: Parameters<CodeModeTransport['run']>[0]): Promise<CodeModeToolResult> {\n    const { sandbox, program, toolIds, dispatch, timeout, abortSignal, onExternalCall, onExternalResult } = opts;\n\n    if (!sandbox) {\n      throw new Error('StdioCodeModeTransport requires a sandbox');\n    }\n    if (!sandbox.processes) {\n      throw new SandboxFeatureNotSupportedError('processes');\n    }\n\n    const externals = toolIds.map(toolId => ({ toolId, externalName: sanitizeToolId(toolId) }));\n    const allowList = new Set(toolIds);\n\n    const dir = await mkdtemp(join(tmpdir(), 'mastra-code-mode-'));\n    const suffix = randomBytes(4).toString('hex');\n    // The model's TypeScript program is written to its own .ts module; node\n    // strips the type annotations when the runner imports it (see the\n    // --experimental-strip-types flag on the spawn below).\n    const programPath = join(dir, `program-${suffix}.ts`);\n    await writeFile(programPath, buildProgramModule(program), 'utf8');\n    const runnerSource = buildRunner({ programModule: pathToFileURL(programPath).href, externals });\n    const runnerPath = join(dir, `runner-${suffix}.mjs`);\n    await writeFile(runnerPath, runnerSource, 'utf8');\n\n    const logs: string[] = [];\n    let done: CodeModeToolResult | undefined;\n    let stdoutBuffer = '';\n\n    // Resolved once a terminal `done` frame arrives.\n    let resolveDone!: () => void;\n    const donePromise = new Promise<void>(resolve => {\n      resolveDone = resolve;\n    });\n\n    try {\n      // `--experimental-strip-types` lets node import the program's `.ts`\n      // module on Node 22.6–22.17 (where type-stripping is still flagged). On\n      // Node 22.18+/24, where stripping is the default, the flag is accepted as\n      // a harmless no-op, so this works across the versions CI and users run.\n      const handle = await sandbox.processes.spawn(`node --experimental-strip-types ${runnerPath}`, {\n        cwd: dir,\n        abortSignal,\n        onStdout: (chunk: string) => {\n          stdoutBuffer += chunk;\n          let idx: number;\n          while ((idx = stdoutBuffer.indexOf('\\n')) >= 0) {\n            const line = stdoutBuffer.slice(0, idx);\n            stdoutBuffer = stdoutBuffer.slice(idx + 1);\n            if (!line.startsWith(FRAME_PREFIX)) continue;\n            let frame: CodeModeRunnerFrame;\n            try {\n              frame = JSON.parse(line.slice(FRAME_PREFIX.length));\n            } catch {\n              continue;\n            }\n            handleFrame(frame);\n          }\n        },\n      });\n\n      function handleFrame(frame: CodeModeRunnerFrame): void {\n        switch (frame.type) {\n          case 'log':\n            logs.push(frame.message);\n            return;\n          case 'done':\n            done = frame.ok\n              ? { success: true, result: frame.result, logs }\n              : { success: false, error: frame.error, logs };\n            resolveDone();\n            return;\n          case 'rpc':\n            // `serveRpc` awaits `respond`, which writes to the child's stdin and\n            // can reject if the process already exited/was killed. Swallow that\n            // so it never surfaces as an unhandled rejection.\n            void serveRpc(frame.id, frame.tool, frame.args).catch(() => {});\n            return;\n        }\n      }\n\n      // Observer hooks are caller-supplied and best-effort: a throwing hook must\n      // never prevent `respond()` from running, or the matching in-sandbox promise\n      // would hang until the timeout.\n      function notifyCall(tool: string, args: unknown): void {\n        try {\n          onExternalCall?.(tool, args);\n        } catch {\n          /* observer errors are non-fatal */\n        }\n      }\n      function notifyResult(tool: string, durationMs: number, error?: Error): void {\n        try {\n          onExternalResult?.(tool, durationMs, error);\n        } catch {\n          /* observer errors are non-fatal */\n        }\n      }\n\n      async function serveRpc(id: number, tool: string, args: unknown): Promise<void> {\n        const started = Date.now();\n        notifyCall(tool, args);\n        // Allow-list enforcement: never invoke a tool that wasn't exposed.\n        if (!allowList.has(tool)) {\n          notifyResult(tool, Date.now() - started, new Error('not allowed'));\n          await respond(id, false, undefined, {\n            message: `Tool \"${tool}\" is not available in Code Mode`,\n            name: 'NotAllowedError',\n          });\n          return;\n        }\n        try {\n          const result = await dispatch(tool, args);\n          notifyResult(tool, Date.now() - started);\n          await respond(id, true, result);\n        } catch (error: any) {\n          notifyResult(tool, Date.now() - started, error);\n          await respond(id, false, undefined, {\n            message: error?.message ?? String(error),\n            name: error?.name,\n          });\n        }\n      }\n\n      async function respond(\n        id: number,\n        ok: boolean,\n        result?: unknown,\n        error?: { message: string; name?: string },\n      ): Promise<void> {\n        await handle.sendStdin(JSON.stringify({ type: 'rpc-result', id, ok, result, error }) + '\\n');\n      }\n\n      // Race completion against process exit and the timeout. Including process\n      // exit means a runner that dies without emitting `done` resolves\n      // immediately instead of waiting out the full timeout.\n      let timer: NodeJS.Timeout | undefined;\n      const timeoutPromise = new Promise<'timeout'>(resolve => {\n        timer = setTimeout(() => resolve('timeout'), timeout);\n      });\n      const exitPromise = handle.wait().then(() => 'exited' as const);\n\n      const outcome = await Promise.race([\n        donePromise.then(() => 'done' as const),\n        exitPromise.catch(() => 'exited' as const),\n        timeoutPromise,\n      ]);\n      if (timer) clearTimeout(timer);\n\n      if (outcome === 'timeout') {\n        await handle.kill().catch(() => {});\n        return {\n          success: false,\n          logs,\n          error: { message: `Code Mode execution timed out after ${timeout}ms`, name: 'TimeoutError' },\n        };\n      }\n\n      // Either `done` arrived or the process exited. If we raced ahead of a\n      // `done` frame still in flight, give it a brief beat to land.\n      if (!done) {\n        await exitPromise.catch(() => {});\n      }\n\n      return (\n        done ?? {\n          success: false,\n          logs,\n          error: { message: 'Program exited without returning a result', name: 'NoResultError' },\n        }\n      );\n    } finally {\n      await rm(dir, { recursive: true, force: true }).catch(() => {});\n    }\n  }\n}\n","/**\n * Code Mode — tool factory\n *\n * `createCodeMode(config)` returns the `execute_typescript` tool plus the\n * generated `instructions`. The tool transpiles the model's TypeScript to JS,\n * runs it in a WorkspaceSandbox via the transport, and bridges each\n * `external_*` call back to the real Mastra tool on the host.\n */\n\nimport { z } from 'zod/v4';\nimport type { WorkspaceSandbox } from '../../workspace/sandbox/sandbox';\nimport { createTool } from '../tool';\nimport type { Tool } from '../tool';\nimport { isValidationError } from '../validation';\nimport { createCodeModeInstructions } from './stub-generator';\nimport { StdioCodeModeTransport } from './transport';\nimport type { CodeModeConfig, CodeModeToolDispatcher, CodeModeToolResult, CodeModeTransport } from './types';\n\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_TOOL_NAME = 'execute_typescript';\n\nconst codeModeInputSchema = z.object({\n  code: z\n    .string()\n    .describe(\n      'A TypeScript program that orchestrates the available external_* tools and returns a final value. ' +\n        'Use Promise.all to batch calls; do arithmetic in JS. End with `return <value>`.',\n    ),\n});\n\nconst codeModeOutputSchema = z.object({\n  success: z.boolean(),\n  result: z.unknown().optional(),\n  logs: z.array(z.string()).optional(),\n  error: z\n    .object({\n      message: z.string(),\n      name: z.string().optional(),\n      line: z.number().optional(),\n    })\n    .optional(),\n});\n\n/** Result of {@link createCodeMode}: the tool plus its generated instructions. */\nexport interface CodeModeResult {\n  tool: Tool<any, any>;\n  instructions: string;\n}\n\n/** Resolve the tool key -> tool map keyed by the tool's effective id. */\nfunction indexToolsById(config: CodeModeConfig): Map<string, { execute?: (args: any, ctx: any) => Promise<any> }> {\n  const map = new Map();\n  for (const [key, tool] of Object.entries(config.tools)) {\n    const id = (tool as { id?: string }).id ?? key;\n    map.set(id, tool);\n  }\n  return map;\n}\n\n/**\n * Create only the `execute_typescript` tool. Most callers want\n * {@link createCodeMode}, which also returns the matching instructions.\n */\nexport function createCodeModeTool(\n  config: CodeModeConfig,\n  transport: CodeModeTransport = new StdioCodeModeTransport(),\n) {\n  const timeout = config.timeout ?? DEFAULT_TIMEOUT;\n  const id = config.id ?? DEFAULT_TOOL_NAME;\n  const toolsById = indexToolsById(config);\n  const toolIds = [...toolsById.keys()];\n\n  return createTool({\n    id,\n    description:\n      'Execute a TypeScript program that orchestrates the available tools in a sandbox. ' +\n      'Prefer this over calling tools one at a time when a task needs multiple tool calls, ' +\n      'batching, aggregation, or arithmetic.',\n    inputSchema: codeModeInputSchema,\n    outputSchema: codeModeOutputSchema,\n    execute: async ({ code }, ctx): Promise<CodeModeToolResult> => {\n      // Resolve sandbox: explicit config -> workspace from context. There is no\n      // implicit fallback: Code Mode runs model-authored code, so the execution\n      // boundary must be chosen deliberately. To run locally (host privileges),\n      // pass `sandbox: new LocalSandbox()` explicitly. Transports that provide\n      // their own execution boundary (e.g. in-process V8 isolates) declare\n      // `requiresSandbox: false` and run without one.\n      const sandbox: WorkspaceSandbox | undefined = config.sandbox ?? ctx?.workspace?.sandbox;\n      if (!sandbox && transport.requiresSandbox !== false) {\n        throw new Error(\n          'Code Mode requires a sandbox to run model-authored code, but none was configured. ' +\n            'Pass one to createCodeMode({ tools, sandbox }), or run the agent in a workspace that provides a sandbox. ' +\n            'To execute on the host (host privileges — only for trusted/local use), pass `sandbox: new LocalSandbox()`.',\n        );\n      }\n\n      // Each external_* call re-enters the real Mastra tool pipeline (validation,\n      // request-context checks, tracing) on the host, with the outer tool's context.\n      const dispatch: CodeModeToolDispatcher = async (toolId, args) => {\n        const tool = toolsById.get(toolId);\n        if (!tool?.execute) {\n          throw new Error(`Tool \"${toolId}\" is not available in Code Mode`);\n        }\n        const result = await tool.execute(args, {\n          mastra: ctx?.mastra,\n          requestContext: ctx?.requestContext,\n          abortSignal: ctx?.abortSignal,\n          workspace: ctx?.workspace,\n        });\n        if (isValidationError(result)) {\n          throw new Error(result.message ?? `Invalid input for tool \"${toolId}\"`);\n        }\n        return result;\n      };\n\n      // The TypeScript program is written to a .ts module by the transport;\n      // the sandbox's node strips the type annotations natively at import.\n      return ctx.observe.span(`code-mode:${id}`, () =>\n        transport.run({\n          sandbox,\n          program: code,\n          toolIds,\n          dispatch,\n          timeout,\n          abortSignal: ctx?.abortSignal,\n          onExternalCall: (tool, args) => ctx.observe.log('info', 'code-mode external call', { tool, args }),\n          onExternalResult: (tool, durationMs, error) =>\n            ctx.observe.log(error ? 'error' : 'info', 'code-mode external result', { tool, durationMs }),\n        }),\n      );\n    },\n  }) as unknown as Tool<any, any>;\n}\n\n/**\n * Create Code Mode: the `execute_typescript` tool plus generated instructions.\n *\n * @example\n * ```ts\n * const { tool, instructions } = createCodeMode({ tools: { getTopProducts, getProductRatings } });\n * const agent = new Agent({ instructions: ['You are helpful.', instructions], tools: { [tool.id]: tool } });\n * ```\n */\nexport function createCodeMode(config: CodeModeConfig, transport?: CodeModeTransport): CodeModeResult {\n  return {\n    tool: createCodeModeTool(config, transport),\n    instructions: createCodeModeInstructions(config),\n  };\n}\n","import { z } from 'zod/v4';\n\nimport { createTool } from '../tool';\n\n/**\n * A structured choice rendered by the host for an `ask_user` prompt.\n *\n * The label is the value returned to the model when the option is selected. The\n * optional description gives the host more context without changing the answer value.\n */\nexport interface AskUserOption {\n  label: string;\n  description?: string;\n}\n\n/**\n * Controls whether an `ask_user` prompt accepts one choice or multiple choices.\n *\n * `single_select` is the default for prompts that provide options, preserving the\n * original one-answer behavior. `multi_select` tells the host that the user may choose\n * more than one option and resume with those selections as an array.\n */\nexport type AskUserSelectionMode = 'single_select' | 'multi_select';\n\n/**\n * Answer shape used to resume a suspended `ask_user` call.\n *\n * Free-text and single-select prompts resume with a string. Multi-select prompts\n * resume with a string array containing each selected option label.\n */\nexport type AskUserAnswer = string | string[];\n\n/**\n * Payload carried by the native `tool-call-suspended` event when `ask_user` pauses.\n * Hosts read this to render the question, choices, and selection mode.\n */\nexport interface AskUserSuspendPayload {\n  question: string;\n  options?: AskUserOption[];\n  selectionMode?: AskUserSelectionMode;\n}\n\nconst optionSchema = z.object({\n  label: z.string().describe('Short display text for this option (1-5 words)'),\n  description: z.string().optional().describe('Explanation of what this option means'),\n});\n\n/**\n * Converts the resume answer into the text returned to the model after `ask_user`\n * resumes. Free-text and single-select prompts already produce a single string,\n * while multi-select prompts resume with an array of selected labels that must be\n * flattened before the tool result is added back into the generation context.\n *\n * The formatter keeps the model-facing output compact by joining multi-select\n * answers with commas, mirroring the single-answer behavior while still preserving\n * every selected option in a readable form.\n */\nexport function formatQuestionAnswer(answer: AskUserAnswer): string {\n  return Array.isArray(answer) ? answer.join(', ') : answer;\n}\n\n/**\n * Built-in, agent-agnostic tool: ask the user a question and wait for their response.\n *\n * The tool supports three prompt shapes. Omitting `options` asks an open-ended\n * free-text question. Providing `options` without `selectionMode` asks the host to\n * render a single-select prompt for backwards compatibility. Providing\n * `selectionMode: 'multi_select'` lets the host resume with multiple selected option\n * labels as a string array.\n *\n * Pausing uses the agent-native tool suspension primitive: the tool calls\n * `suspend({ question, options, selectionMode })`, which makes the agent emit a\n * `tool-call-suspended` event and persist run state. The host renders the question,\n * collects the user's answer, and continues the run via `agent.resumeStream(answer)`;\n * the tool re-runs with `resumeData` set to the answer and returns it to the model.\n *\n * When executed without an agent `suspend` (e.g. direct invocation outside an agent\n * run), the tool returns a readable fallback prompt so the question and choices are\n * still surfaced.\n */\nexport const askUserTool = createTool({\n  id: 'ask_user',\n  description:\n    'Ask the user a question and wait for their response. Use this when you need clarification, want to validate assumptions, or need the user to make a decision between options. Provide options for structured choices (2-4 options), or omit them for open-ended questions. Use selectionMode to choose whether the user can pick one option or multiple options.',\n  inputSchema: z.object({\n    question: z.string().min(1).describe('The question to ask the user. Should be clear and specific.'),\n    options: z\n      .array(optionSchema)\n      .optional()\n      .describe('Optional choices. If provided, shows a selection list. If omitted, shows a free-text input.'),\n    selectionMode: z\n      .enum(['single_select', 'multi_select'])\n      .optional()\n      .describe(\n        'Controls how many provided options the user can select. Defaults to single_select when options are provided. Requires options.',\n      ),\n  }),\n  suspendSchema: z.object({\n    question: z.string(),\n    options: z.array(optionSchema).optional(),\n    selectionMode: z.enum(['single_select', 'multi_select']).optional(),\n  }),\n  resumeSchema: z.union([z.string(), z.array(z.string())]),\n  execute: async ({ question, options, selectionMode }, context) => {\n    try {\n      if (selectionMode && !options?.length) {\n        return {\n          content: 'Failed to ask user: selectionMode requires options.',\n          isError: true,\n        };\n      }\n\n      const resolvedSelectionMode = options?.length ? (selectionMode ?? 'single_select') : undefined;\n\n      const resumeData = context?.agent?.resumeData as AskUserAnswer | undefined;\n      if (resumeData !== undefined) {\n        return { content: `User answered: ${formatQuestionAnswer(resumeData)}`, isError: false };\n      }\n\n      const suspend = context?.agent?.suspend;\n      if (suspend) {\n        await suspend({ question, options, selectionMode: resolvedSelectionMode });\n        return;\n      }\n\n      // No agent context available: surface the question as readable text so non-agent\n      // execution paths still expose the question and available choices to the model.\n      return {\n        content: `[Question for user]: ${question}${\n          options?.length ? '\\nOptions: ' + options.map(o => o.label).join(', ') : ''\n        }${resolvedSelectionMode ? '\\nSelection mode: ' + resolvedSelectionMode : ''}`,\n        isError: false,\n      };\n    } catch (error) {\n      const msg = error instanceof Error ? error.message : 'Unknown error';\n      return { content: `Failed to ask user: ${msg}`, isError: true };\n    }\n  },\n});\n","import { lookup as dnsLookup } from 'node:dns';\nimport type { LookupAddress, LookupOptions } from 'node:dns';\nimport http from 'node:http';\nimport https from 'node:https';\nimport net from 'node:net';\n\nimport { z } from 'zod/v4';\n\nimport { createTool } from '../tool';\n\nconst MAX_CONTENT_LENGTH = 100_000;\nconst MAX_REDIRECTS = 5;\nconst TIMEOUT_MS = 15_000;\n\nclass WebFetchError extends Error {}\n\nfunction parseHttpUrl(url: string): URL | undefined {\n  try {\n    const parsedUrl = new URL(url);\n    return parsedUrl.protocol === 'http:' || parsedUrl.protocol === 'https:' ? parsedUrl : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction isBlockedHostname(hostname: string): boolean {\n  const normalizedHostname = hostname.toLowerCase();\n  return normalizedHostname === 'localhost' || normalizedHostname.endsWith('.localhost');\n}\n\nfunction isBlockedIpv4(address: string): boolean {\n  const parts = address.split('.').map(Number);\n  const [first = 0, second = 0] = parts;\n\n  return (\n    first === 0 ||\n    first === 10 ||\n    first === 127 ||\n    (first === 100 && second >= 64 && second <= 127) ||\n    (first === 169 && second === 254) ||\n    (first === 172 && second >= 16 && second <= 31) ||\n    (first === 192 && second === 0 && parts[2] === 0) ||\n    (first === 192 && second === 0 && parts[2] === 2) ||\n    (first === 192 && second === 168) ||\n    (first === 198 && (second === 18 || second === 19)) ||\n    (first === 198 && second === 51 && parts[2] === 100) ||\n    (first === 203 && second === 0 && parts[2] === 113) ||\n    first >= 224\n  );\n}\n\nfunction normalizeHostname(hostname: string): string {\n  return hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;\n}\n\nfunction parseIpv4MappedGroups(address: string): number[] | undefined {\n  const ipv4Start = address.lastIndexOf(':');\n  const ipv4Address = address.slice(ipv4Start + 1);\n\n  if (!ipv4Address.includes('.')) {\n    return undefined;\n  }\n\n  const ipv4Parts = ipv4Address.split('.').map(Number);\n  if (ipv4Parts.length !== 4 || ipv4Parts.some(part => !Number.isInteger(part) || part < 0 || part > 255)) {\n    return undefined;\n  }\n\n  const [first, second, third, fourth] = ipv4Parts as [number, number, number, number];\n\n  return [...expandIpv6(address.slice(0, ipv4Start), 6), (first << 8) + second, (third << 8) + fourth];\n}\n\nfunction expandIpv6(address: string, expectedGroups = 8): number[] {\n  const [left = '', right = ''] = address.split('::');\n  const leftGroups = left ? left.split(':') : [];\n  const rightGroups = right ? right.split(':') : [];\n  const missingGroups = expectedGroups - leftGroups.length - rightGroups.length;\n  const groups = address.includes('::')\n    ? [...leftGroups, ...Array(missingGroups).fill('0'), ...rightGroups]\n    : leftGroups;\n\n  return groups.map(group => Number.parseInt(group || '0', 16));\n}\n\nfunction isBlockedIpv6(address: string): boolean {\n  const normalizedAddress = normalizeHostname(address).toLowerCase();\n  const groups = normalizedAddress.includes('.')\n    ? parseIpv4MappedGroups(normalizedAddress)\n    : expandIpv6(normalizedAddress);\n\n  if (!groups || groups.length !== 8 || groups.some(group => Number.isNaN(group))) {\n    return false;\n  }\n\n  const [first, second, third, fourth, fifth, sixth, seventh, eighth] = groups as [\n    number,\n    number,\n    number,\n    number,\n    number,\n    number,\n    number,\n    number,\n  ];\n  const isIpv4Mapped = [first, second, third, fourth, fifth].every(group => group === 0) && sixth === 0xffff;\n\n  return (\n    groups.every(group => group === 0) ||\n    (groups.slice(0, 7).every(group => group === 0) && eighth === 1) ||\n    (isIpv4Mapped && isBlockedIpv4([seventh >> 8, seventh & 255, eighth >> 8, eighth & 255].join('.'))) ||\n    (first & 0xfe00) === 0xfc00 ||\n    (first & 0xffc0) === 0xfe80 ||\n    (first & 0xff00) === 0xff00\n  );\n}\n\nfunction isBlockedIp(address: string): boolean {\n  const normalizedAddress = normalizeHostname(address);\n  const ipVersion = net.isIP(normalizedAddress);\n  return ipVersion === 4\n    ? isBlockedIpv4(normalizedAddress)\n    : ipVersion === 6\n      ? isBlockedIpv6(normalizedAddress)\n      : false;\n}\n\nfunction assertAllowedUrl(url: URL): void {\n  const hostname = normalizeHostname(url.hostname);\n\n  if (isBlockedHostname(hostname) || isBlockedIp(hostname)) {\n    throw new WebFetchError('URL resolves to a private or reserved address.');\n  }\n}\n\nfunction createLookup() {\n  return (\n    hostname: string,\n    options: LookupOptions,\n    callback: (error: NodeJS.ErrnoException | null, address: string | LookupAddress[], family?: number) => void,\n  ) => {\n    dnsLookup(hostname, options, (error, address, family) => {\n      if (error) {\n        callback(error, address, family);\n        return;\n      }\n\n      const resolvedAddresses = Array.isArray(address) ? address.map(result => result.address) : [address];\n      const blockedAddress = resolvedAddresses.find(isBlockedIp);\n\n      if (blockedAddress) {\n        callback(new WebFetchError('URL resolves to a private or reserved address.'), address, family);\n        return;\n      }\n\n      callback(null, address, family);\n    });\n  };\n}\n\nasync function readBody(response: http.IncomingMessage): Promise<{ content: string; truncated: boolean }> {\n  const decoder = new TextDecoder();\n  let content = '';\n  let truncated = false;\n\n  for await (const chunk of response) {\n    content += typeof chunk === 'string' ? chunk : decoder.decode(chunk as Buffer, { stream: true });\n\n    if (content.length > MAX_CONTENT_LENGTH) {\n      content = content.slice(0, MAX_CONTENT_LENGTH);\n      truncated = true;\n      response.destroy();\n      break;\n    }\n  }\n\n  if (!truncated) {\n    content += decoder.decode();\n  }\n\n  return { content, truncated };\n}\n\nasync function requestUrl(\n  url: URL,\n  redirectsRemaining = MAX_REDIRECTS,\n): Promise<{\n  content: string;\n  truncated: boolean;\n  status?: number;\n  statusText?: string;\n  contentType?: string | null;\n  url?: string;\n  ok?: boolean;\n}> {\n  assertAllowedUrl(url);\n\n  return new Promise((resolve, reject) => {\n    const requestModule = url.protocol === 'https:' ? https : http;\n    const request = requestModule.request(\n      url,\n      {\n        headers: {\n          'user-agent': 'Mastra Web Fetch Tool/1.0',\n          accept: 'text/html,text/plain,application/json,application/xml;q=0.9,*/*;q=0.8',\n        },\n        lookup: createLookup(),\n        timeout: TIMEOUT_MS,\n      },\n      response => {\n        void (async () => {\n          const location = response.headers.location;\n\n          if (location && response.statusCode && response.statusCode >= 300 && response.statusCode < 400) {\n            response.resume();\n\n            if (redirectsRemaining <= 0) {\n              throw new WebFetchError(`Too many redirects. Maximum is ${MAX_REDIRECTS}.`);\n            }\n\n            const nextUrl = parseHttpUrl(new URL(location, url).toString());\n            if (!nextUrl) {\n              throw new WebFetchError('Redirect target must use HTTP or HTTPS.');\n            }\n\n            resolve(await requestUrl(nextUrl, redirectsRemaining - 1));\n            return;\n          }\n\n          const { content, truncated } = await readBody(response);\n\n          resolve({\n            content,\n            truncated,\n            status: response.statusCode,\n            statusText: response.statusMessage,\n            contentType: Array.isArray(response.headers['content-type'])\n              ? response.headers['content-type'][0]\n              : (response.headers['content-type'] ?? null),\n            url: url.toString(),\n            ok: response.statusCode ? response.statusCode >= 200 && response.statusCode < 300 : false,\n          });\n        })().catch(reject);\n      },\n    );\n\n    request.on('timeout', () => {\n      request.destroy(new WebFetchError(`Request timed out after ${TIMEOUT_MS}ms.`));\n    });\n    request.on('error', reject);\n    request.end();\n  });\n}\n\nfunction getErrorMessage(error: unknown): string {\n  if (error instanceof Error) {\n    return error.message;\n  }\n\n  return 'Unknown error';\n}\n\nexport const webFetchTool = createTool({\n  id: 'web_fetch',\n  description: 'Fetch a web page by URL and return text content with basic response metadata.',\n  inputSchema: z.object({\n    url: z.string().min(1).describe('The fully qualified HTTP or HTTPS URL to fetch.'),\n  }),\n  outputSchema: z.object({\n    content: z.string(),\n    truncated: z.boolean().optional(),\n    status: z.number().optional(),\n    statusText: z.string().optional(),\n    contentType: z.string().nullable().optional(),\n    url: z.string().optional(),\n    ok: z.boolean().optional(),\n    isError: z.boolean().optional(),\n  }),\n  execute: async ({ url }: { url: string }) => {\n    const parsedUrl = parseHttpUrl(url);\n\n    if (!parsedUrl) {\n      return {\n        content: 'Failed to fetch URL: only HTTP and HTTPS URLs are supported.',\n        isError: true,\n      };\n    }\n\n    try {\n      return await requestUrl(parsedUrl);\n    } catch (error) {\n      return {\n        content: `Failed to fetch URL: ${getErrorMessage(error)}`,\n        isError: true,\n      };\n    }\n  },\n});\n","import type { ProviderDefinedTool } from '@internal/external-types';\nimport { ErrorCategory, ErrorDomain, MastraError } from '../../error';\n\nconst WEB_SEARCH_TOOL_MARKER = Symbol.for('mastra.tools.webSearchTool');\n\nexport type WebSearchProvider = 'openai' | 'anthropic' | 'google' | 'xai';\nexport type WebSearchProviderToolId =\n  | 'openai.web_search'\n  | 'anthropic.web_search_20250305'\n  | 'google.google_search'\n  | 'xai.web_search';\n\nexport type WebSearchToolPlaceholder = {\n  readonly [WEB_SEARCH_TOOL_MARKER]: true;\n};\n\nexport const webSearchTool: WebSearchToolPlaceholder = Object.freeze({\n  [WEB_SEARCH_TOOL_MARKER]: true,\n});\n\nexport function isWebSearchTool(tool: unknown): tool is WebSearchToolPlaceholder {\n  return (\n    tool === webSearchTool ||\n    (typeof tool === 'object' && tool !== null && (tool as WebSearchToolPlaceholder)[WEB_SEARCH_TOOL_MARKER] === true)\n  );\n}\n\nexport function normalizeWebSearchProvider(providerOrModel: unknown): WebSearchProvider {\n  const provider = getProviderString(providerOrModel);\n  const supportedProviders = new Set<WebSearchProvider>(['openai', 'anthropic', 'google', 'xai']);\n\n  if (supportedProviders.has(provider as WebSearchProvider)) {\n    return provider as WebSearchProvider;\n  }\n\n  const routerProvider = getRouterProvider(provider);\n  if (supportedProviders.has(routerProvider as WebSearchProvider)) {\n    return routerProvider as WebSearchProvider;\n  }\n\n  throw new MastraError({\n    id: 'WEB_SEARCH_UNSUPPORTED_PROVIDER',\n    domain: ErrorDomain.AGENT,\n    category: ErrorCategory.USER,\n    details: {\n      provider,\n    },\n    text: `The built-in webSearchTool supports OpenAI, Anthropic, Google, and xAI models. Could not infer a supported provider from \"${provider}\".`,\n  });\n}\n\nexport function createWebSearchProviderTool(provider: WebSearchProvider): ProviderDefinedTool {\n  const tool = getWebSearchProviderTool(provider);\n  return {\n    type: 'provider-defined',\n    id: tool.id,\n    name: tool.name,\n    args: {},\n  } as ProviderDefinedTool;\n}\n\nfunction getProviderString(providerOrModel: unknown): string {\n  if (typeof providerOrModel === 'string') {\n    return providerOrModel;\n  }\n\n  if (typeof providerOrModel === 'object' && providerOrModel !== null) {\n    const model = providerOrModel as { provider?: unknown; modelId?: unknown; id?: unknown };\n    if (typeof model.provider === 'string') {\n      if (model.provider === 'openai-compatible') {\n        if (typeof model.modelId === 'string') {\n          return model.modelId;\n        }\n\n        if (typeof model.id === 'string') {\n          return model.id;\n        }\n      }\n\n      return model.provider;\n    }\n\n    if (typeof model.modelId === 'string') {\n      return model.modelId;\n    }\n\n    if (typeof model.id === 'string') {\n      return model.id;\n    }\n  }\n\n  return String(providerOrModel);\n}\n\nfunction getRouterProvider(provider: string): string {\n  const slashIndex = provider.indexOf('/');\n  return slashIndex > 0 ? provider.slice(0, slashIndex) : provider;\n}\n\nfunction getWebSearchProviderTool(provider: WebSearchProvider): { id: WebSearchProviderToolId; name: string } {\n  switch (provider) {\n    case 'openai':\n      return { id: 'openai.web_search', name: 'web_search' };\n    case 'anthropic':\n      return { id: 'anthropic.web_search_20250305', name: 'web_search' };\n    case 'google':\n      return { id: 'google.google_search', name: 'google_search' };\n    case 'xai':\n      return { id: 'xai.web_search', name: 'web_search' };\n  }\n}\n","import { z } from 'zod/v4';\n\nimport { createTool } from '../tool';\n\n/**\n * Payload carried by the native `tool-call-suspended` event when `submit_plan` pauses.\n *\n * The tool knows the plan file `path` on disk. Hosts validate that path, read the plan\n * from it, and fill `title`/`plan` for approval rendering and history replay.\n */\nexport interface SubmitPlanSuspendPayload {\n  path: string;\n  title?: string;\n  plan?: string;\n}\n\n/**\n * The action a host resumes a suspended `submit_plan` call with.\n *\n * `approved` means the user accepted the plan and the agent should proceed. `rejected`\n * means the user wants revisions; the optional `feedback` is surfaced to the model so it\n * can revise and submit again.\n *\n * Hosts that layer additional behavior on approval (e.g. a AgentController switching from a\n * planning mode to an execution mode) drive that from their own response handling; the\n * tool itself only reports the outcome back to the model.\n */\nexport interface SubmitPlanResumeData {\n  action: 'approved' | 'rejected';\n  feedback?: string;\n  path?: string;\n  title?: string;\n  plan?: string;\n}\n\nconst resumeSchema = z.object({\n  action: z.enum(['approved', 'rejected']),\n  feedback: z.string().optional(),\n  path: z.string().optional(),\n  title: z.string().optional(),\n  plan: z.string().optional(),\n});\n\n/**\n * Built-in, agent-agnostic tool: submit an implementation plan for user review.\n *\n * Pausing uses the agent-native tool suspension primitive: the tool calls\n * `suspend({ path })`, which makes the agent emit a `tool-call-suspended` event and\n * persist run state. The host validates the plan file path, reads it, renders it,\n * collects an approve/reject decision, and continues the run via `agent.resumeStream({ action,\n * feedback })`; the tool re-runs with `resumeData` set to that decision and reports it\n * back to the model.\n *\n * This tool is deliberately host-agnostic: it does not know about AgentController modes or any\n * UI. A plain Agent (e.g. embedded in Studio or a customer app) can use it directly, and\n * a AgentController can layer mode-switch behavior on top of the approval in its own response\n * handling without the tool needing to change.\n *\n * The tool takes the plan file `path` — never the plan body. The host reads the plan from\n * disk at that path, so more than one plan can exist over time. When executed without an\n * agent `suspend` (e.g. direct invocation outside an agent run), the tool returns the path\n * as readable text so the submission is still surfaced.\n */\nexport const submitPlanTool = createTool({\n  id: 'submit_plan',\n  description:\n    'Submit a plan you wrote to a markdown file for review. Pass the `path` to that file (e.g. `.mastracode/plans/add-dark-mode.md`). Write/edit the file first — do not paste the plan contents here. Reuse the same file across revisions; only create a new file for a genuinely new plan. The user can approve, reject, or request changes. On approval, the system automatically switches to the default mode so you can implement.',\n  inputSchema: z.object({\n    path: z.string().describe('Path to the plan markdown file on disk (e.g. `.mastracode/plans/add-dark-mode.md`).'),\n  }),\n  suspendSchema: z.object({\n    path: z.string(),\n    title: z.string().optional(),\n    plan: z.string().optional(),\n  }),\n  resumeSchema,\n  execute: async ({ path }, context) => {\n    try {\n      const resumeData = context?.agent?.resumeData as SubmitPlanResumeData | undefined;\n      if (resumeData !== undefined) {\n        if (resumeData.action === 'approved') {\n          return {\n            content: 'Plan approved. Proceed with implementation following the approved plan.',\n            isError: false,\n            submittedPlan: {\n              title: resumeData.title,\n              path: resumeData.path,\n              plan: resumeData.plan,\n            },\n          };\n        }\n\n        if (resumeData.feedback) {\n          return {\n            content: `Plan was not approved. The user wants revisions.\\n\\nUser feedback: ${resumeData.feedback}\\n\\nPlease revise the plan based on the feedback and submit again with submit_plan.`,\n            isError: false,\n            submittedPlan: {\n              title: resumeData.title,\n              path: resumeData.path,\n              plan: resumeData.plan,\n            },\n          };\n        }\n\n        // No inline feedback — the user will provide revision instructions in\n        // their next chat message. Stop and wait for it.\n        return {\n          content:\n            'Plan was not approved. The user will send revision instructions in their next message. Stop now and wait for the user to provide feedback before revising the plan.',\n          isError: false,\n          submittedPlan: {\n            title: resumeData.title,\n            path: resumeData.path,\n            plan: resumeData.plan,\n          },\n        };\n      }\n\n      const suspend = context?.agent?.suspend;\n      if (suspend) {\n        // The host validates `path`, reads that file to render the approval UI, and\n        // fills title/plan into the resume payload for history replay.\n        await suspend({ path });\n        return;\n      }\n\n      // No agent context available: surface the submission as readable text so non-agent\n      // execution paths still expose it to the model.\n      return {\n        content: `[Plan submitted for review]\\n\\nPath: ${path}`,\n        isError: false,\n      };\n    } catch (error) {\n      const msg = error instanceof Error ? error.message : 'Unknown error';\n      return { content: `Failed to submit plan: ${msg}`, isError: true };\n    }\n  },\n});\n"],"mappings":"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"}