Repository: mastra-ai/mastra
File: mastracode/src/agents/prompts/tool-guidance.ts (TypeScript)

Code before:
**write_file** — Create new files or overwrite existing ones
- Use this to create new files.
- If overwriting an existing file, you MUST have read it first with \`view\`.
- NEVER create files unless necessary. Prefer editing existing files.`);
  }

  // --- Web tools (all modes, conditionally available) ---

  if (options.hasWebSearch) {
    sections.push(`
**web_search** / **web_extract** — Search the web / extract page content
- Use for looking up documentation, error messages, package APIs.`);
  }

  // --- Task management tools (all modes) ---

  sections.push(`
**task_write** — Track tasks for complex multi-step work
- Use when a task requires 3 or more distinct steps or actions.
- Pass the FULL task list each time (replaces previous list).
- Mark tasks \`in_progress\` BEFORE starting work. Only ONE task should be \`in_progress\` at a time.
- Mark tasks \`completed\` IMMEDIATELY after finishing each task. Do not batch completions.
- Each task has: content (imperative form), status (pending|in_progress|completed), activeForm (present continuous form shown during execution).

**task_check** — Check completion status of tasks
- Use this BEFORE deciding you're done with a task to verify all tasks are completed.
- Returns the number of completed, in progress, and pending tasks.
- If any tasks remain incomplete, continue working on them.
- IMPORTANT: Always check task completion before ending work on a complex task.

**ask_user** — Ask the user a structured question
- Use when you need clarification, want to validate assumptions, or need the user to make a decision.
- Provide clear, specific questions. End with a question mark.
- Include options (2-4 choices) for structured decisions. Omit options for open-ended questions.
- Don't use this for simple yes/no — just ask in your text response.`);

  // --- Plan submission tool (plan mode) ---

  if (modeId === 'plan') {
    sections.push(`
**submit_plan** — Submit a completed implementation plan for user review
- Call this tool when your plan is complete. Do NOT just describe your plan in text — you MUST call this tool.
- The plan will be rendered as markdown and the user can approve, reject, or request changes.
- On approval, the system automatically switches to the default mode so you can implement.
- Takes two arguments: \`title\` (short descriptive title) and \`plan\` (full plan in markdown).`);
  }

  // --- Subagent tool (all modes) ---

  sections.push(`
**subagent** — Delegate a focused task to a specialized subagent

Review comment (performance):
we should generally avoid changing the system prompt as much as possible, but perhaps preventing it is for another PR. anytime we change the system prompt it invalidates the prompt cache and makes the next request much more expensive. In the future we should probably always keep tools and tool descriptions stable, and just have the tool reject with an error if it's denied. For making the model know what's allowed and what isn't, we can inject user messages like `<system-reminder>you are now in X mode, the only tools you can call are $list</system-reminder>`

Code after:
- Good: Run independent commands in parallel when possible.
- Bad: Running \`cat file.txt\` — use the view tool instead.`);
  }

  if (readTools.length > 0) {
    sections.push(readTools.join('\n'));
  }

  // --- Write/edit tools (build & fast only) ---

  if (modeId !== 'plan') {
    const writeTools: string[] = [];

    if (!denied.has('string_replace_lsp')) {
      writeTools.push(`
**string_replace_lsp** — Edit files by replacing exact text
- You MUST read a file with \`view\` before editing it.
- \`old_str\` must be an exact match of existing text in the file.
- Provide enough surrounding context in \`old_str\` to make it unique.
- For creating new files, use \`write_file\` instead.
- Good: Include 2-3 lines of surrounding context to ensure uniqueness.
- Bad: Using just \`return true;\` — too common, will match multiple places.`);
    }

    if (!denied.has('write_file')) {
      writeTools.push(`
**write_file** — Create new files or overwrite existing ones
- Use this to create new files.
- If overwriting an existing file, you MUST have read it first with \`view\`.
- NEVER create files unless necessary. Prefer editing existing files.`);
    }

    if (writeTools.length > 0) {
      sections.push(writeTools.join('\n'));
    }
  }

  // --- Web tools (all modes, conditionally available) ---

  if (options.hasWebSearch) {
    const webTools: string[] = [];
    if (!denied.has('web_search')) webTools.push('**web_search**');
    if (!denied.has('web_extract')) webTools.push('**web_extract**');
    if (webTools.length > 0) {
      sections.push(`
${webTools.join(' / ')} — Search the web / extract page content
- Use for looking up documentation, error messages, package APIs.`);
    }
  }

  // --- Task management tools (all modes) ---