pub trait Tool: Send + Sync {
// Required methods
fn definition(&self) -> &ToolDefinition;
fn execute<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, ToolError>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn validate(&self, _args: &Value) -> Result<(), ToolError> { ... }
fn capabilities(&self) -> Vec<Capability> { ... }
fn timeout(&self) -> Duration { ... }
fn is_available(&self) -> bool { ... }
}Expand description
The core Tool trait — interface all tools must implement.
Tools are the bridge between LLM decision-making and real-world actions. Every tool must:
- Provide its definition (name, description, schema)
- Implement async execution
§Security
validate()is called beforeexecute()— reject bad input earlycapabilities()declares what the tool needs for sandboxingtimeout()prevents DoS from hanging operations
§Example
ⓘ
use vex_llm::{Tool, ToolDefinition, ToolError, Capability};
use async_trait::async_trait;
pub struct MyTool {
definition: ToolDefinition,
}
#[async_trait]
impl Tool for MyTool {
fn definition(&self) -> &ToolDefinition {
&self.definition
}
async fn execute(&self, args: serde_json::Value) -> Result<serde_json::Value, ToolError> {
// Your implementation here
Ok(serde_json::json!({"status": "done"}))
}
}Required Methods§
Sourcefn definition(&self) -> &ToolDefinition
fn definition(&self) -> &ToolDefinition
Returns the tool’s metadata (name, description, schema)
Sourcefn execute<'life0, 'async_trait>(
&'life0 self,
args: Value,
) -> Pin<Box<dyn Future<Output = Result<Value, ToolError>> + 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, ToolError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Execute the tool with given arguments.
§Arguments
args- JSON value matching the tool’s parameter schema
§Returns
Ok(Value)- The tool’s output as JSONErr(ToolError)- If execution failed
§Security
Implementations should:
- Validate all inputs (even if validate() passed)
- Sanitize outputs (no raw filesystem paths, etc.)
- Respect timeouts (use tokio::select! if needed)
Provided Methods§
Sourcefn validate(&self, _args: &Value) -> Result<(), ToolError>
fn validate(&self, _args: &Value) -> Result<(), ToolError>
Validate arguments before execution.
Called by ToolExecutor before execute(). Override to add custom validation beyond JSON schema checking.
§Default
Returns Ok(()) — no additional validation.
Sourcefn capabilities(&self) -> Vec<Capability>
fn capabilities(&self) -> Vec<Capability>
Sourcefn is_available(&self) -> bool
fn is_available(&self) -> bool
Whether the tool is currently available.
§Default
Always returns true. Override to implement availability checks
(e.g., API health, rate limiting, maintenance windows).