SchemaTool

Trait SchemaTool 

Source
pub trait SchemaTool: Send + Sync {
    type Input: JsonSchema + DeserializeOwned + Send;

    const NAME: &'static str;
    const DESCRIPTION: &'static str;
    const STRICT: bool = false;

    // Required method
    fn handle<'life0, 'life1, 'async_trait>(
        &'life0 self,
        input: Self::Input,
        context: &'life1 ExecutionContext,
    ) -> Pin<Box<dyn Future<Output = ToolResult> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided method
    fn input_schema() -> Value { ... }
}
Expand description

Schema-based tool trait with automatic JSON schema generation.

Provides a higher-level abstraction over Tool with typed inputs and automatic schema derivation via schemars.

Required Associated Constants§

Source

const NAME: &'static str

Source

const DESCRIPTION: &'static str

Provided Associated Constants§

Source

const STRICT: bool = false

Required Associated Types§

Required Methods§

Source

fn handle<'life0, 'life1, 'async_trait>( &'life0 self, input: Self::Input, context: &'life1 ExecutionContext, ) -> Pin<Box<dyn Future<Output = ToolResult> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Provided Methods§

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl SchemaTool for TaskOutputTool

Source§

const NAME: &'static str = "TaskOutput"

Source§

const DESCRIPTION: &'static str = r#" - Retrieves output from a running or completed task (background shell, agent, or remote session) - Takes a task_id parameter identifying the task - Returns the task output along with status information - Use block=true (default) to wait for task completion - Use block=false for non-blocking check of current status - Task IDs can be found using the Task tool response - Works with all task types: background shells, async agents, and remote sessions - Output is limited to prevent excessive memory usage; for larger outputs, consider streaming - Important: task_id is the Task tool's returned ID, NOT a process PID"#

Source§

type Input = TaskOutputInput

Source§

impl SchemaTool for TaskTool

Source§

const NAME: &'static str = "Task"

Source§

const DESCRIPTION: &'static str = r#"Launch a new agent to handle complex, multi-step tasks autonomously. The Task tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it. Available agent types and the tools they have access to: - general: General-purpose agent for researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. (Tools: *) - explore: Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (e.g., "src/**/*.ts"), search code for keywords (e.g., "API endpoints"), or answer questions about the codebase (e.g., "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions. (Tools: Read, Grep, Glob, Bash) - plan: Software architect agent for designing implementation plans. Use this when you need to plan the implementation strategy for a task. Returns step-by-step plans, identifies critical files, and considers architectural trade-offs. (Tools: *) When using the Task tool, you must specify a subagent_type parameter to select which agent type to use. When NOT to use the Task tool: - If you want to read a specific file path, use the Read or Glob tool instead of the Task tool, to find the match more quickly - If you are searching for a specific class definition like "class Foo", use the Grep tool instead, to find the match more quickly - If you are searching for code within a specific file or set of 2-3 files, use the Read tool instead of the Task tool, to find the match more quickly - Other tasks that are not related to the agent descriptions above Usage notes: - Always include a short description (3-5 words) summarizing what the agent will do - Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses - When the agent is done, it will return a single message back to you along with its agent_id. You can use this ID to resume the agent later if needed for follow-up work. - You can optionally run agents in the background using the run_in_background parameter. When an agent runs in the background, you will need to use TaskOutput to retrieve its results once it's done. You can continue to work while background agents run - when you need their results to continue you can use TaskOutput in blocking mode to pause and wait for their results. - Agents can be resumed using the `resume` parameter by passing the agent ID from a previous invocation. When resumed, the agent continues with its full previous context preserved. When NOT resuming, each invocation starts fresh and you should provide a detailed task description with all necessary context. - Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need. - The agent's outputs should generally be trusted - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent - If you need to launch multiple agents in parallel, send a single message with multiple Task tool calls. - Use model="haiku" for quick, straightforward tasks to minimize cost and latency"#

Source§

type Input = TaskInput

Source§

impl SchemaTool for SkillTool

Source§

const NAME: &'static str = "Skill"

Source§

const DESCRIPTION: &'static str = r#"Execute a skill within the main conversation <skills_instructions> When users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge. When users ask you to run a "slash command" or reference "/<something>" (e.g., "/commit", "/review-pr"), they are referring to a skill. Use this tool to invoke the corresponding skill. <example> User: "run /commit" Assistant: [Calls Skill tool with skill: "commit"] </example> How to invoke: - Use this tool with the skill name and optional arguments - Examples: - `skill: "pdf"` - invoke the pdf skill - `skill: "commit", args: "-m 'Fix bug'"` - invoke with arguments - `skill: "review-pr", args: "123"` - invoke with arguments - `skill: "ms-office-suite:pdf"` - invoke using fully qualified name Important: - When a skill is relevant, you must invoke this tool IMMEDIATELY as your first action - NEVER just announce or mention a skill in your text response without actually calling this tool - This is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task - Only use skills that are registered and available - Do not invoke a skill that is already running </skills_instructions> Note: For the full list of available skills, use description_with_skills() method when building system prompts."#

Source§

type Input = SkillInput

Source§

impl SchemaTool for BashTool

Source§

const NAME: &'static str = "Bash"

Source§

const DESCRIPTION: &'static str = r#"Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures. IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead. Before executing the command, please follow these steps: 1. Directory Verification: - If the command will create new directories or files, first use `ls` to verify the parent directory exists and is the correct location - For example, before running "mkdir foo/bar", first use `ls foo` to check that "foo" exists and is the intended parent directory 2. Command Execution: - Always quote file paths that contain spaces with double quotes (e.g., cd "path with spaces/file.txt") - Examples of proper quoting: - cd "/Users/name/My Documents" (correct) - cd /Users/name/My Documents (incorrect - will fail) - python "/path/with spaces/script.py" (correct) - python /path/with spaces/script.py (incorrect - will fail) - After ensuring proper quoting, execute the command. - Capture the output of the command. Usage notes: - The command argument is required. - You can specify an optional timeout in milliseconds (up to 600000ms / 10 minutes). If not specified, commands will timeout after 120000ms (2 minutes). - It is very helpful if you write a clear, concise description of what this command does in 5-10 words. - If the output exceeds 30000 characters, output will be truncated before being returned to you. - You can use the `run_in_background` parameter to run the command in the background, which allows you to continue working while the command runs. You can monitor the output using the Bash tool as it becomes available. You do not need to use '&' at the end of the command when using this parameter. - Avoid using Bash with the `find`, `grep`, `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or when these commands are truly necessary for the task. Instead, always prefer using the dedicated tools for these commands: - File search: Use Glob (NOT find or ls) - Content search: Use Grep (NOT grep or rg) - Read files: Use Read (NOT cat/head/tail) - Edit files: Use Edit (NOT sed/awk) - Write files: Use Write (NOT echo >/cat <<EOF) - Communication: Output text directly (NOT echo/printf) - When issuing multiple commands: - If the commands are independent and can run in parallel, make multiple Bash tool calls in a single message. For example, if you need to run "git status" and "git diff", send a single message with two Bash tool calls in parallel. - If the commands depend on each other and must run sequentially, use a single Bash call with '&&' to chain them together (e.g., `git add . && git commit -m "message" && git push`). For instance, if one operation must complete before another starts (like mkdir before cp, Write before Bash for git operations, or git add before git commit), run these operations sequentially instead. - Use ';' only when you need to run commands sequentially but don't care if earlier commands fail - DO NOT use newlines to separate commands (newlines are ok in quoted strings) - Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of `cd`. You may use `cd` if the User explicitly requests it. <good-example> pytest /foo/bar/tests </good-example> <bad-example> cd /foo/bar && pytest tests </bad-example>"#

Source§

type Input = BashInput

Source§

impl SchemaTool for EditTool

Source§

const NAME: &'static str = "Edit"

Source§

const DESCRIPTION: &'static str = r#"Performs exact string replacements in files. Usage: - You must use your `Read` tool at least once in the conversation before editing. This tool will error if you attempt an edit without reading the file. - When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: spaces + line number + tab. Everything after that tab is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string. - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required. - Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked. - The edit will FAIL if `old_string` is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use `replace_all` to change every instance of `old_string`. - Use `replace_all` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance."#

Source§

type Input = EditInput

Source§

impl SchemaTool for GlobTool

Source§

const NAME: &'static str = "Glob"

Source§

const DESCRIPTION: &'static str = r#"- Fast file pattern matching tool that works with any codebase size - Supports glob patterns like "**/*.js" or "src/**/*.ts" - Returns matching file paths sorted by modification time - Use this tool when you need to find files by name patterns - When you are doing an open ended search that may require multiple rounds of globbing and grepping, use the Task tool instead - You can call multiple tools in a single response. It is always better to speculatively perform multiple searches in parallel if they are potentially useful."#

Source§

type Input = GlobInput

Source§

impl SchemaTool for GrepTool

Source§

const NAME: &'static str = "Grep"

Source§

const DESCRIPTION: &'static str = r#"A powerful search tool built on ripgrep Usage: - ALWAYS use Grep for search tasks. NEVER invoke `grep` or `rg` as a Bash command. The Grep tool has been optimized for correct permissions and access. - Supports full regex syntax (e.g., "log.*Error", "function\s+\w+") - Filter files with glob parameter (e.g., "*.js", "**/*.tsx") or type parameter (e.g., "js", "py", "rust") - Output modes: "content" shows matching lines, "files_with_matches" shows only file paths (default), "count" shows match counts - Use Task tool for open-ended searches requiring multiple rounds - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use `interface\{\}` to find `interface{}` in Go code) - Multiline matching: By default patterns match within single lines only. For cross-line patterns like `struct \{[\s\S]*?field`, use `multiline: true`"#

Source§

type Input = GrepInput

Source§

impl SchemaTool for KillShellTool

Source§

const NAME: &'static str = "KillShell"

Source§

const DESCRIPTION: &'static str = r#" - Kills a running background bash shell by its ID - Takes a shell_id parameter identifying the shell to kill - Returns a success or failure status - Use this tool when you need to terminate a long-running shell - Shell IDs can be obtained from Bash tool responses when using run_in_background"#

Source§

type Input = KillShellInput

Source§

impl SchemaTool for PlanTool

Source§

const NAME: &'static str = "Plan"

Source§

const DESCRIPTION: &'static str = r#"Manage structured planning workflow for complex implementation tasks. ## Actions - **start**: Begin plan mode for complex tasks (creates Draft plan) - **complete**: Finalize plan and proceed to implementation (approves plan) - **cancel**: Abort current plan - **update**: Update plan content while in plan mode - **status**: Check current plan state ## When to Use Plan Mode Use `action: "start"` for implementation tasks unless they're simple: 1. **New Feature Implementation**: Adding meaningful new functionality 2. **Multiple Valid Approaches**: Task can be solved in several ways 3. **Code Modifications**: Changes affecting existing behavior 4. **Architectural Decisions**: Choosing between patterns or technologies 5. **Multi-File Changes**: Task touching more than 2-3 files 6. **Unclear Requirements**: Need exploration before understanding scope ## When NOT to Use Skip for simple tasks: - Single-line fixes (typos, obvious bugs) - Adding a single function with clear requirements - Tasks with specific, detailed instructions - Pure research (use Task tool with Explore agent) ## Workflow 1. Call with `action: "start"` to enter plan mode 2. Explore codebase using Glob, Grep, Read tools 3. Call with `action: "update"` to record your plan 4. Call with `action: "complete"` to finalize and proceed ## Examples ```json // Start planning {"action": "start", "name": "Add user authentication"} // Update plan content {"action": "update", "content": "1. Add JWT middleware\n2. Create auth routes"} // Complete and proceed {"action": "complete"} // Check status {"action": "status"} // Cancel if needed {"action": "cancel"} ``` ## Integration - Use Plan for high-level approach and exploration - Use TodoWrite for granular task tracking during execution - Plan content persists across session compaction"#

Source§

type Input = PlanInput

Source§

impl SchemaTool for ReadTool

Source§

const NAME: &'static str = "Read"

Source§

const DESCRIPTION: &'static str = r#"Reads a file from the local filesystem. You can access any file directly by using this tool. Assume this tool is able to read all files on the machine. If a path to a file is provided assume that path is valid. It is okay to read a file that does not exist; an error will be returned. Usage: - The file_path parameter must be an absolute path, not a relative path - By default, it reads up to 2000 lines starting from the beginning of the file - You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters - Any lines longer than 2000 characters will be truncated - Results are returned using cat -n format, with line numbers starting at 1 - This tool can read images (eg PNG, JPG, etc). When reading an image file the contents are returned as base64-encoded data URI for multimodal processing. - This tool can read PDF files (.pdf). PDFs are processed page by page, extracting both text and visual content for analysis. - This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations. - This tool can only read files, not directories. To read a directory, use an ls command via the Bash tool. - You can call multiple tools in a single response. It is always better to speculatively read multiple potentially useful files in parallel. - If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents."#

Source§

type Input = ReadInput

Source§

impl SchemaTool for TodoWriteTool

Source§

const NAME: &'static str = "TodoWrite"

Source§

const DESCRIPTION: &'static str = r#"Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user. It also helps the user understand the progress of the task and overall progress of their requests. ## When to Use This Tool Use this tool proactively in these scenarios: 1. Complex multi-step tasks - When a task requires 3 or more distinct steps or actions 2. Non-trivial and complex tasks - Tasks that require careful planning or multiple operations 3. User explicitly requests todo list - When the user directly asks you to use the todo list 4. User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated) 5. After receiving new instructions - Immediately capture user requirements as todos 6. When you start working on a task - Mark it as in_progress BEFORE beginning work. Ideally you should only have one todo as in_progress at a time 7. After completing a task - Mark it as completed and add any new follow-up tasks discovered during implementation ## When NOT to Use This Tool Skip using this tool when: 1. There is only a single, straightforward task 2. The task is trivial and tracking it provides no organizational benefit 3. The task can be completed in less than 3 trivial steps 4. The task is purely conversational or informational NOTE that you should not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly. ## Examples of When to Use the Todo List <example> User: I want to add a dark mode toggle to the application settings. Make sure you run the tests and build when you're done! Assistant: I'll help you add a dark mode toggle to your application settings. Let me create a todo list to track this implementation. *Creates todo list with the following items:* 1. Creating dark mode toggle component in Settings page 2. Adding dark mode state management (context/store) 3. Implementing CSS-in-JS styles for dark theme 4. Updating existing components to support theme switching 5. Running tests and build process, addressing any failures or errors that occur *Begins working on the first task* <reasoning> The assistant used the todo list because: 1. Adding dark mode is a multi-step feature requiring UI, state management, and styling changes 2. The user explicitly requested tests and build be run afterward 3. The assistant inferred that tests and build need to pass by adding "Ensure tests and build succeed" as the final task </reasoning> </example> <example> User: Help me rename the function getCwd to getCurrentWorkingDirectory across my project Assistant: Let me first search through your codebase to find all occurrences of 'getCwd'. *Uses grep or search tools to locate all instances of getCwd in the codebase* Assistant: I've found 15 instances of 'getCwd' across 8 different files. Let me create a todo list to track these changes. *Creates todo list with specific items for each file that needs updating* <reasoning> The assistant used the todo list because: 1. First, the assistant searched to understand the scope of the task 2. Upon finding multiple occurrences across different files, it determined this was a complex task with multiple steps 3. The todo list helps ensure every instance is tracked and updated systematically 4. This approach prevents missing any occurrences and maintains code consistency </reasoning> </example> <example> User: I need to implement these features for my e-commerce site: user registration, product catalog, shopping cart, and checkout flow. Assistant: I'll help implement these features. First, let's add all the features to the todo list. *Creates a todo list breaking down each feature into specific tasks based on the project architecture* Assistant: Let's start with user registration. This will involve creating database models, API endpoints, and frontend forms that integrate with your existing authentication system. <reasoning> The assistant used the todo list because: 1. The user provided multiple complex features to implement in a comma separated list 2. The todo list helps organize these large features into manageable tasks 3. This approach allows for tracking progress across the entire implementation </reasoning> </example> <example> User: Can you help optimize my React application? It's rendering slowly and has performance issues.</user> Assistant: I'll help optimize your React application. First, let me examine your codebase to identify potential performance bottlenecks. *Reviews component structure, render patterns, state management, and data fetching* Assistant: After analyzing your codebase, I've identified several performance issues. Let me create a todo list to track our optimization efforts. *Creates todo list with items like: 1) Implementing memoization for expensive calculations in ProductList, 2) Adding virtualization for long lists in Dashboard, 3) Optimizing image loading in Gallery component, 4) Fixing state update loops in ShoppingCart, 5) Reviewing bundle size and implementing code splitting* Let's start by implementing memoization for the expensive calculations in your ProductList component.</assistant> <reasoning> The assistant used the todo list because: 1. First, the assistant examined the codebase to identify specific performance issues 2. Based on this analysis, it identified multiple optimization opportunities 3. Performance optimization is a non-trivial task requiring multiple steps 4. The todo list helps methodically track improvements across different components 5. This systematic approach ensures all performance bottlenecks are addressed </reasoning> </example> ## Examples of When NOT to Use the Todo List <example> User: How do I print 'Hello World' in Python? Assistant: In Python, you can print "Hello World" with this simple code: python print("Hello World") This will output the text "Hello World" to the console when executed.</assistant> <reasoning> The assistant did not use the todo list because this is a single, trivial task that can be completed in one step. There's no need to track multiple tasks or steps for such a straightforward request. </reasoning> </example> <example> User: What does the git status command do? Assistant: The git status command shows the current state of your working directory and staging area. It displays which changes have been staged, which haven't, and which files aren't being tracked by Git. This is a fundamental command for understanding the current state of your repository before making commits. <reasoning> The assistant did not use the todo list because this is an informational request with no actual coding task to complete. The user is simply asking for an explanation, not for the assistant to perform multiple steps or tasks. </reasoning> </example> <example> User: Can you add a comment to the calculateTotal function to explain what it does? Assistant: Sure, let me add a comment to the calculateTotal function to explain what it does. * Uses the Edit tool to add a comment to the calculateTotal function * <reasoning> The assistant did not use the todo list because this is a single, straightforward task confined to one location in the code. Adding a comment doesn't require tracking multiple steps or systematic organization. </reasoning> </example> <example> User: Run npm install for me and tell me what happens. Assistant: I'll run the npm install command for you. *Executes: npm install* The command completed successfully. Here's the output: [Output of npm install command] All dependencies have been installed according to your package.json file. <reasoning> The assistant did not use the todo list because this is a single command execution with immediate results. There are no multiple steps to track or organize, making the todo list unnecessary for this straightforward task. </reasoning> </example> ## Task States and Management 1. **Task States**: Use these states to track progress: - pending: Task not yet started - in_progress: Currently working on (limit to ONE task at a time) - completed: Task finished successfully **IMPORTANT**: Task descriptions must have two forms: - content: The imperative form describing what needs to be done (e.g., "Run tests", "Build the project") - activeForm: The present continuous form shown during execution (e.g., "Running tests", "Building the project") 2. **Task Management**: - Update task status in real-time as you work - Mark tasks complete IMMEDIATELY after finishing (don't batch completions) - Exactly ONE task must be in_progress at any time (not less, not more) - Complete current tasks before starting new ones - Remove tasks that are no longer relevant from the list entirely 3. **Task Completion Requirements**: - ONLY mark a task as completed when you have FULLY accomplished it - If you encounter errors, blockers, or cannot finish, keep the task as in_progress - When blocked, create a new task describing what needs to be resolved - Never mark a task as completed if: - Tests are failing - Implementation is partial - You encountered unresolved errors - You couldn't find necessary files or dependencies 4. **Task Breakdown**: - Create specific, actionable items - Break complex tasks into smaller, manageable steps - Use clear, descriptive task names - Always provide both forms: - content: "Fix authentication bug" - activeForm: "Fixing authentication bug" When in doubt, use this tool. Being proactive with task management demonstrates attentiveness and ensures you complete all requirements successfully."#

Source§

type Input = TodoWriteInput

Source§

impl SchemaTool for WriteTool

Source§

const NAME: &'static str = "Write"

Source§

const DESCRIPTION: &'static str = r#"Writes a file to the local filesystem. Usage: - This tool will overwrite the existing file if there is one at the provided path. - If this is an existing file, you MUST use the Read tool first to read the file's contents. This tool will fail if you did not read the file first. - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required. - NEVER proactively create documentation files (*.md) or README files. Only create documentation files if explicitly requested by the User. - Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked."#

Source§

type Input = WriteInput