Tools

Tool system for extending agent capabilities in PraisonAI Rust SDK

Tools extend agent capabilities by providing callable functions for actions like searching, calculating, or API calls.

Diagram

Tool System

🤖 Agent

🔧 ToolRegistry

Search

Calculate

Custom

Quick Start

  1. Create a Tool with #[tool] Macro
    rust
    use praisonai::{Agent, tool};
    
    #[tool]
    fn search(query: String) -> String {
        format!("Results for: {}", query)
    }
    
    let agent = Agent::new()
        .name("Researcher")
        .instructions("Use the search tool when asked")
        .tool(search)
        .build()?;
    
    let response = agent.chat("Search for Rust programming").await?;
  2. Tool with Description
    rust
    use praisonai::tool;
    
    #[tool(description = "Calculate a mathematical expression")]
    fn calculate(expression: String) -> String {
        // Parse and evaluate expression
        format!("Result: {}", expression)
    }
  3. Async Tool
    rust
    use praisonai::tool;
    
    #[tool(description = "Fetch data from a URL")]
    async fn fetch_url(url: String) -> String {
        // Async HTTP request
        format!("Fetched content from: {}", url)
    }

User Interaction Flow

Diagram
ToolToolRegistryLLMAgentUserToolToolRegistryLLMAgentUser“Search for X”Messages + tool definitionsTool call request: search(X)execute(“search”, args)execute(args)ResultToolResultContinue with resultFinal responseResponse with search results

Tool Trait

Define custom tools by implementing the Tool trait:

rust
#[async_trait]
pub trait Tool: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn parameters_schema(&self) -> Value;
    async fn execute(&self, args: Value) -> Result<Value>;
    fn definition(&self) -> ToolDefinition;  // default impl
}

Trait Methods

MethodSignatureDescription
name()fn name(&self) -> &strTool identifier
description()fn description(&self) -> &strHuman-readable description
parameters_schema()fn parameters_schema(&self) -> ValueJSON Schema for parameters
execute(args)`async fn execute(&self, Value) -> Result

| Run the tool | | definition() | fn definition(&self) -> ToolDefinition` | Get LLM function definition |


ToolRegistry

Manages a collection of tools for an agent.

rust
pub struct ToolRegistry {
    tools: HashMap<String, Arc<dyn Tool>>,
}

Methods

MethodSignatureDescription
new()fn new() -> SelfCreate empty registry
register(tool)fn register(&mut self, impl Tool + 'static)Add a tool
get(name)fn get(&self, &str) -> Option<Arc<dyn Tool>>Get tool by name
has(name)fn has(&self, &str) -> boolCheck if tool exists
list()fn list(&self) -> Vec<&str>List all tool names
definitions()`fn definitions(&self) -> Vec

| Get all definitions | | execute(name, args) | async fn execute(&self, &str, Value) -> Result

| Run tool | | len() | fn len(&self) -> usize` | Number of tools |


ToolResult

Result returned from tool execution.

rust
pub struct ToolResult {
    pub name: String,
    pub value: Value,
    pub success: bool,
    pub error: Option<String>,
}

Factory Methods

MethodSignatureDescription
success(name, value)`fn success(impl Into

, Value) -> Self | Create success result | | failure(name, error) | fn failure(impl Into

, impl Into

) -> Self` | Create error result |


ToolDefinition

Definition sent to LLM for function calling.

rust
pub struct ToolDefinition {
    pub name: String,
    pub description: String,
    pub parameters: Value,  // JSON Schema
}

Creating Tools

Using #[tool] Macro (Recommended)

rust
use praisonai::tool;

// Basic tool
#[tool]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

// With description
#[tool(description = "Add two numbers together")]
fn add(a: i32, b: i32) -> i32 {
    a + b
}

// Async tool
#[tool(description = "Fetch weather data")]
async fn get_weather(city: String) -> String {
    format!("Weather in {}: Sunny", city)
}

Using FunctionTool

rust
use praisonai::FunctionTool;
use serde_json::json;

let tool = FunctionTool::new(
    "greet",
    "Greet a person by name",
    json!({
        "type": "object",
        "properties": {
            "name": {"type": "string"}
        },
        "required": ["name"]
    }),
    |args| async move {
        let name = args["name"].as_str().unwrap_or("World");
        Ok(json!(format!("Hello, {}!", name)))
    }
);

Implementing Tool Trait

rust
use praisonai::{Tool, async_trait};
use serde_json::{Value, json};

struct MyTool;

#[async_trait]
impl Tool for MyTool {
    fn name(&self) -> &str { "my_tool" }

    fn description(&self) -> &str { "Custom tool implementation" }

    fn parameters_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "input": {"type": "string"}
            }
        })
    }

    async fn execute(&self, args: Value) -> Result<Value> {
        let input = args["input"].as_str().unwrap_or("");
        Ok(json!(format!("Processed: {}", input)))
    }
}

Multiple Tools Example

rust
use praisonai::{Agent, tool};

#[tool(description = "Search the web for information")]
fn web_search(query: String) -> String {
    format!("Web results for: {}", query)
}

#[tool(description = "Calculate a math expression")]
fn calculate(expr: String) -> String {
    format!("Calculation: {} = 42", expr)
}

#[tool(description = "Get current time")]
fn get_time() -> String {
    "Current time: 12:34 PM".to_string()
}

let agent = Agent::new()
    .name("MultiTool Agent")
    .instructions("Use available tools to help the user")
    .tool(web_search)
    .tool(calculate)
    .tool(get_time)
    .build()?;

let response = agent.chat("What time is it and search for today's weather").await?;

Best Practices

Use descriptive tool names

Names should clearly indicate what the tool does: web_search, calculate_tax, send_email.

Write clear descriptions

The LLM uses descriptions to decide when to call tools. Be specific and clear.

Handle errors gracefully

Return meaningful error messages that help the agent recover.

Keep tools focused

Each tool should do one thing well. Compose multiple tools for complex operations.


Related