pub trait Tool: Send + Sync {
Show 19 methods
// Required methods
fn execute<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn name(&self) -> &str;
fn description(&self) -> &str;
// Provided methods
fn execute_dual<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<SplitToolResult>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn validate_args(&self, _args: &Value) -> Result<()> { ... }
fn parameter_schema(&self) -> Option<Value> { ... }
fn config_schema(&self) -> Option<Value> { ... }
fn state_schema(&self) -> Option<Value> { ... }
fn prompt_path(&self) -> Option<Cow<'static, str>> { ... }
fn default_permission(&self) -> ToolPolicy { ... }
fn allow_patterns(&self) -> Option<&'static [&'static str]> { ... }
fn deny_patterns(&self) -> Option<&'static [&'static str]> { ... }
fn is_mutating(&self) -> bool { ... }
fn is_parallel_safe(&self) -> bool { ... }
fn kind(&self) -> &'static str { ... }
fn matches_kind(&self, pattern: &str) -> bool { ... }
fn resource_hints(&self, _args: &Value) -> Vec<String> { ... }
fn execution_cost(&self) -> u8 { ... }
fn resolve_and_validate_path<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
workspace_root: &'life1 Path,
path: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
}Expand description
Core trait for all agent tools
Required Methods§
Sourcefn execute<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn execute<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Execute the tool with given arguments
Returns a JSON Value for backward compatibility.
For new tools, consider implementing execute_dual() instead.
Sourcefn description(&self) -> &str
fn description(&self) -> &str
Get the tool’s description
Provided Methods§
Sourcefn execute_dual<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<SplitToolResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn execute_dual<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<SplitToolResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Execute with dual-channel output (LLM summary + UI content)
This method enables significant token savings by separating:
llm_content: Concise summary sent to LLM context (token-optimized)ui_content: Rich output displayed to user (full details)
Default implementation wraps single-channel execute() result for backward compatibility.
Tools can override this to provide optimized dual output.
§Example
use vtcode_core::tools::result::ToolResult as SplitToolResult;
use serde_json::Value;
use anyhow::Result;
async fn execute_dual(&self, args: Value) -> Result<SplitToolResult> {
let full_output = "127 matches across 2,500 tokens...";
let summary = "Found 127 matches in 15 files. Key: src/tools/grep.rs (3)";
Ok(SplitToolResult::new(self.name(), summary, full_output))
}Sourcefn validate_args(&self, _args: &Value) -> Result<()>
fn validate_args(&self, _args: &Value) -> Result<()>
Validate arguments before execution
Sourcefn parameter_schema(&self) -> Option<Value>
fn parameter_schema(&self) -> Option<Value>
Optional JSON schema for the tool’s parameters, if available.
Sourcefn config_schema(&self) -> Option<Value>
fn config_schema(&self) -> Option<Value>
Optional JSON schema for the tool’s configuration, if available.
Sourcefn state_schema(&self) -> Option<Value>
fn state_schema(&self) -> Option<Value>
Optional JSON schema describing state persisted by the tool, if any.
Sourcefn prompt_path(&self) -> Option<Cow<'static, str>>
fn prompt_path(&self) -> Option<Cow<'static, str>>
Optional prompt path metadata (e.g., for loading companion prompts).
Sourcefn default_permission(&self) -> ToolPolicy
fn default_permission(&self) -> ToolPolicy
Default execution policy for this tool.
Sourcefn allow_patterns(&self) -> Option<&'static [&'static str]>
fn allow_patterns(&self) -> Option<&'static [&'static str]>
Optional allowlist patterns the tool considers pre-approved.
Sourcefn deny_patterns(&self) -> Option<&'static [&'static str]>
fn deny_patterns(&self) -> Option<&'static [&'static str]>
Optional denylist patterns the tool considers blocked.
Sourcefn is_mutating(&self) -> bool
fn is_mutating(&self) -> bool
Whether this tool mutates state (files, environment, etc).
Mutating tools require more careful policy evaluation and typically cannot be run in parallel with other tools that touch the same resources.
Default: true (conservative — assume mutation unless overridden).
Per the Rust Patterns guide (Ch 7 — “accept the weakest bound your API
needs”), read-only tools SHOULD override this to return false. The
conservative default exists because accidentally treating a mutating tool
as read-only is worse than the reverse.
Sourcefn is_parallel_safe(&self) -> bool
fn is_parallel_safe(&self) -> bool
Whether this tool is safe to run in parallel with other tools.
Non-mutating read-only tools can often run in parallel. Mutating tools should generally return false.
Default: opposite of is_mutating()
Sourcefn kind(&self) -> &'static str
fn kind(&self) -> &'static str
Get the kind/category of this tool for matching against policies.
Used by ExecPolicyManager to apply category-level rules. Common kinds: “shell”, “file”, “search”, “network”, “system”
Sourcefn matches_kind(&self, pattern: &str) -> bool
fn matches_kind(&self, pattern: &str) -> bool
Check if this tool matches a given kind pattern.
Supports exact matches and wildcard patterns.
Sourcefn resource_hints(&self, _args: &Value) -> Vec<String>
fn resource_hints(&self, _args: &Value) -> Vec<String>
Resources this tool might access (paths, URLs, etc).
Used for conflict detection in parallel execution planning.
Sourcefn execution_cost(&self) -> u8
fn execution_cost(&self) -> u8
Estimated execution cost (1-10 scale).
Used for scheduling and resource management. 1 = instant, 5 = moderate, 10 = expensive/long-running
Sourcefn resolve_and_validate_path<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
workspace_root: &'life1 Path,
path: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn resolve_and_validate_path<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
workspace_root: &'life1 Path,
path: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<PathBuf>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Resolve a path relative to workspace root and validate it is within bounds
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".