ToolBuilder

Struct ToolBuilder 

Source
pub struct ToolBuilder { /* private fields */ }
Expand description

A builder for creating tools with a simplified API.

§Example

use helios_engine::ToolBuilder;
use serde_json::Value;

async fn my_calculator(args: Value) -> helios_engine::Result<helios_engine::ToolResult> {
    let a = args.get("a").and_then(|v| v.as_f64()).unwrap_or(0.0);
    let b = args.get("b").and_then(|v| v.as_f64()).unwrap_or(0.0);
    Ok(helios_engine::ToolResult::success((a + b).to_string()))
}

let tool = ToolBuilder::new("add_numbers")
    .description("Add two numbers together")
    .parameter("a", "number", "First number", true)
    .parameter("b", "number", "Second number", true)
    .function(my_calculator)
    .build();

Implementations§

Source§

impl ToolBuilder

Source

pub fn new(name: impl Into<String>) -> Self

Creates a new ToolBuilder with the given name.

§Arguments
  • name - The name of the tool (e.g., “calculator”, “weather_api”)
Examples found in repository?
examples/tool_builder_demo.rs (line 60)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn from_fn<F>( func_name: impl Into<String>, description: impl Into<String>, params: impl Into<String>, func: F, ) -> Self
where F: Fn(Value) -> Result<ToolResult> + Send + Sync + 'static,

Creates a ToolBuilder from an existing function, automatically deriving the tool name.

This method extracts the function name and uses it as the tool name, making it extremely simple to convert existing functions into tools without redefining anything.

§Arguments
  • func_name - The name to use for the tool (typically the function name)
  • description - A description of what the tool does
  • params - Parameter definitions in the format “name:type:description, …”
  • func - The function to execute
§Example
use helios_engine::{ToolBuilder, ToolResult};

fn calculate_area(length: f64, width: f64) -> f64 {
    length * width
}

let tool = ToolBuilder::from_fn(
    "calculate_area",
    "Calculate the area of a rectangle",
    "length:f64:The length of the rectangle, width:f64:The width of the rectangle",
    |args| {
        let length = args.get("length").and_then(|v| v.as_f64()).unwrap_or(0.0);
        let width = args.get("width").and_then(|v| v.as_f64()).unwrap_or(0.0);
        let area = calculate_area(length, width);
        Ok(ToolResult::success(format!("The area is {} square units", area)))
    }
).build();
Source

pub fn simple( name: impl Into<String>, description: impl Into<String>, params: impl Into<String>, ) -> Self

Creates a tool from a simple function with automatic parameter extraction.

This is the SIMPLEST API - just provide name, description, parameters, and the function. The function will be automatically wrapped and its parameters extracted from JSON.

§Example with inline function
use helios_engine::ToolBuilder;

fn adder(x: i32, y: i32) -> i32 {
    x + y
}

let tool = ToolBuilder::simple(
    "add_numbers",
    "Add two integers together",
    "x:i32:First number, y:i32:Second number"
).build();
Source

pub fn from_async_fn<F, Fut>( func_name: impl Into<String>, description: impl Into<String>, params: impl Into<String>, func: F, ) -> Self
where F: Fn(Value) -> Fut + Send + Sync + 'static, Fut: Future<Output = Result<ToolResult>> + Send + 'static,

Creates a ToolBuilder from an existing async function, automatically deriving the tool name.

This is the async version of from_fn, for functions that need to perform async operations.

§Arguments
  • func_name - The name to use for the tool (typically the function name)
  • description - A description of what the tool does
  • params - Parameter definitions in the format “name:type:description, …”
  • func - The async function to execute
§Example
use helios_engine::{ToolBuilder, ToolResult};

async fn fetch_temperature(city: &str) -> Result<f64, String> {
    // Simulate API call
    Ok(20.5)
}

let tool = ToolBuilder::from_async_fn(
    "fetch_temperature",
    "Get the temperature for a city",
    "city:string:The name of the city",
    |args| async move {
        let city = args.get("city").and_then(|v| v.as_str()).unwrap_or("");
        let temp = fetch_temperature(city).await.unwrap_or(0.0);
        Ok(ToolResult::success(format!("Temperature: {}°C", temp)))
    }
).build();
Source

pub fn description(self, description: impl Into<String>) -> Self

Sets the description of the tool.

§Arguments
  • description - A clear description of what the tool does
Examples found in repository?
examples/tool_builder_demo.rs (line 61)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn parameter( self, name: impl Into<String>, param_type: impl Into<String>, description: impl Into<String>, required: bool, ) -> Self

Adds a parameter to the tool.

§Arguments
  • name - The parameter name
  • param_type - The parameter type (e.g., “string”, “number”, “boolean”, “object”, “array”)
  • description - A description of the parameter
  • required - Whether the parameter is required
Source

pub fn optional_parameter( self, name: impl Into<String>, param_type: impl Into<String>, description: impl Into<String>, ) -> Self

Adds an optional parameter to the tool (convenience method).

§Arguments
  • name - The parameter name
  • param_type - The parameter type
  • description - A description of the parameter
Source

pub fn required_parameter( self, name: impl Into<String>, param_type: impl Into<String>, description: impl Into<String>, ) -> Self

Adds a required parameter to the tool (convenience method).

§Arguments
  • name - The parameter name
  • param_type - The parameter type
  • description - A description of the parameter
Source

pub fn parameters(self, params: impl Into<String>) -> Self

Adds multiple parameters at once using a compact format.

This method allows you to define all parameters in a single string, making it much easier and more concise than calling required_parameter multiple times.

§Format

The format is: "param_name:type:description, param_name2:type2:description2, ..."

Supported types:

  • i32, i64, u32, u64, isize, usize -> mapped to “integer”
  • f32, f64, number -> mapped to “number”
  • str, String, string -> mapped to “string”
  • bool, boolean -> mapped to “boolean”
  • object -> mapped to “object”
  • array -> mapped to “array”
§Arguments
  • params - A comma-separated string of parameters in the format “name:type:description”
§Example
use helios_engine::ToolBuilder;

let tool = ToolBuilder::new("calculate_volume")
    .description("Calculate the volume of a box")
    .parameters("width:i32:The width of the box, height:i32:The height of the box, depth:f64:The depth of the box")
    .sync_function(|args| {
        // function implementation
    })
    .build();
Examples found in repository?
examples/tool_builder_demo.rs (line 62)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn function<F, Fut>(self, f: F) -> Self
where F: Fn(Value) -> Fut + Send + Sync + 'static, Fut: Future<Output = Result<ToolResult>> + Send + 'static,

Sets the function to execute when the tool is called.

The function should be an async function that takes Value (JSON arguments) and returns Result<ToolResult>.

§Arguments
  • f - An async function that implements the tool’s logic
Source

pub fn sync_function<F>(self, f: F) -> Self
where F: Fn(Value) -> Result<ToolResult> + Send + Sync + 'static,

Sets the function using a synchronous closure.

This is a convenience method for simple synchronous operations.

§Arguments
  • f - A synchronous function that implements the tool’s logic
Source

pub fn ftool<F, T1, T2, R>(self, f: F) -> Self
where F: Fn(T1, T2) -> R + Send + Sync + 'static, T1: FromValue + Send + 'static, T2: FromValue + Send + 'static, R: ToString + Send + 'static,

Ultra-simple API: Pass a function directly with automatic type inference.

This method automatically infers parameter types from your function signature and extracts them from JSON. Works with any types that implement FromValue.

Supported types: i32, i64, u32, u64, f32, f64, bool, String

§Example
use helios_engine::ToolBuilder;

fn adder(x: i32, y: i32) -> i32 { x + y }
fn greeter(name: String, formal: bool) -> String {
    if formal {
        format!("Good day, {}", name)
    } else {
        format!("Hey {}!", name)
    }
}

let add_tool = ToolBuilder::new("add")
    .description("Add two numbers")
    .parameters("x:i32:First, y:i32:Second")
    .ftool(adder)
    .build();

let greet_tool = ToolBuilder::new("greet")
    .description("Greet someone")
    .parameters("name:string:Name, formal:bool:Formal")
    .ftool(greeter)
    .build();
Examples found in repository?
examples/tool_builder_demo.rs (line 63)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn ftool3<F, T1, T2, T3, R>(self, f: F) -> Self
where F: Fn(T1, T2, T3) -> R + Send + Sync + 'static, T1: FromValue + Send + 'static, T2: FromValue + Send + 'static, T3: FromValue + Send + 'static, R: ToString + Send + 'static,

Ultra-simple API: Pass a 3-parameter function directly with automatic type inference.

§Example
use helios_engine::ToolBuilder;

fn volume(width: f64, height: f64, depth: f64) -> f64 {
    width * height * depth
}

let tool = ToolBuilder::new("calculate_volume")
    .description("Calculate volume")
    .parameters("width:f64:Width, height:f64:Height, depth:f64:Depth")
    .ftool3(volume)
    .build();
Examples found in repository?
examples/tool_builder_demo.rs (line 86)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn ftool4<F, T1, T2, T3, T4, R>(self, f: F) -> Self
where F: Fn(T1, T2, T3, T4) -> R + Send + Sync + 'static, T1: FromValue + Send + 'static, T2: FromValue + Send + 'static, T3: FromValue + Send + 'static, T4: FromValue + Send + 'static, R: ToString + Send + 'static,

Ultra-simple API: Pass a 4-parameter function directly with automatic type inference.

Source

pub fn build(self) -> Box<dyn Tool>

Builds the tool, consuming the builder and returning a boxed Tool.

§Panics

Panics if the function has not been set.

Examples found in repository?
examples/tool_builder_demo.rs (line 64)
52async fn main() -> helios_engine::Result<()> {
53    let config = Config::from_file("config.toml")?;
54
55    println!("=== Tool Builder Demo ===\n");
56    println!("Creating tools with the ultra-simple ftool API!");
57    println!("The system automatically infers types from your function signature!\n");
58
59    // Example 1: Integer parameters (i32, i32) - types inferred automatically!
60    let add_tool = ToolBuilder::new("add")
61        .description("Add two integers")
62        .parameters("x:i32:First number, y:i32:Second number")
63        .ftool(adder) // Automatically knows these are i32!
64        .build();
65
66    // Example 2: Integer multiplication (i32, i32)
67    let multiply_tool = ToolBuilder::new("multiply")
68        .description("Multiply two integers")
69        .parameters("a:i32:First number, b:i32:Second number")
70        .ftool(multiplier)
71        .build();
72
73    // Example 3: Float parameters (f64, f64) - automatically inferred!
74    let area_tool = ToolBuilder::new("calculate_area")
75        .description("Calculate the area of a rectangle")
76        .parameters("length:f64:Length in meters, width:f64:Width in meters")
77        .ftool(calculate_area) // Same ftool method, but knows these are f64!
78        .build();
79
80    // Example 4: Three float parameters (f64, f64, f64)
81    let volume_tool = ToolBuilder::new("calculate_volume")
82        .description("Calculate the volume of a box")
83        .parameters(
84            "width:f64:Width in meters, height:f64:Height in meters, depth:f64:Depth in meters",
85        )
86        .ftool3(calculate_volume)
87        .build();
88
89    // Example 5: BMI calculator with floats
90    let bmi_tool = ToolBuilder::new("calculate_bmi")
91        .description("Calculate Body Mass Index")
92        .parameters("weight_kg:f64:Weight in kilograms, height_m:f64:Height in meters")
93        .ftool(calculate_bmi)
94        .build();
95
96    // Example 6: Mixed types - String and bool!
97    let greet_tool = ToolBuilder::new("greet")
98        .description("Greet someone by name")
99        .parameters("name:string:Person's name, formal:bool:Use formal greeting")
100        .ftool(greet) // Automatically knows: String, bool!
101        .build();
102
103    // Example 7: Mixed numeric types - f64 and i32
104    let discount_tool = ToolBuilder::new("calculate_discount")
105        .description("Calculate discount on a price")
106        .parameters("price:f64:Original price, percent:i32:Discount percentage")
107        .ftool(calculate_discount) // Automatically knows: f64, i32!
108        .build();
109
110    // Create an agent with all the tools
111    let mut agent = Agent::builder("ToolDemo")
112        .config(config)
113        .system_prompt(
114            "You are a helpful assistant with access to various calculation and utility tools. \
115             Use them to help answer questions accurately.",
116        )
117        .tool(add_tool)
118        .tool(multiply_tool)
119        .tool(area_tool)
120        .tool(volume_tool)
121        .tool(bmi_tool)
122        .tool(greet_tool)
123        .tool(discount_tool)
124        .build()
125        .await?;
126
127    println!("Created 7 tools with minimal code!\n");
128    println!("All types automatically inferred from function signatures!\n");
129    println!("===========================================\n");
130
131    // Test the tools
132    println!("Test 1: Integer addition");
133    let response = agent.chat("What is 42 plus 17?").await?;
134    println!("Agent: {}\n", response);
135
136    println!("Test 2: Integer multiplication");
137    let response = agent.chat("What is 12 times 8?").await?;
138    println!("Agent: {}\n", response);
139
140    println!("Test 3: Calculate area");
141    let response = agent
142        .chat("What is the area of a rectangle that is 5 meters long and 3 meters wide?")
143        .await?;
144    println!("Agent: {}\n", response);
145
146    println!("Test 4: Calculate volume");
147    let response = agent
148        .chat("What's the volume of a box that is 2m wide, 3m high, and 1.5m deep?")
149        .await?;
150    println!("Agent: {}\n", response);
151
152    println!("Test 5: Calculate BMI");
153    let response = agent
154        .chat("Calculate BMI for someone weighing 70 kg and 1.75 meters tall")
155        .await?;
156    println!("Agent: {}\n", response);
157
158    println!("Test 6: Greeting with String and bool");
159    let response = agent.chat("Greet Bob in a casual way").await?;
160    println!("Agent: {}\n", response);
161
162    println!("Test 7: Discount calculation with mixed types");
163    let response = agent
164        .chat("What's the discount on a $100 item with 20% off?")
165        .await?;
166    println!("Agent: {}\n", response);
167
168    println!("\n===========================================");
169    println!("✨ That's how easy it is to create tools!");
170    println!("   Just define your function and the system automatically:");
171    println!("   • Infers all parameter types from your function signature");
172    println!("   • Extracts values from JSON in the right order");
173    println!("   • Handles i32, i64, u32, u64, f32, f64, bool, String");
174    println!(
175        "   • Works with .ftool() for 2 params, .ftool3() for 3 params, .ftool4() for 4 params"
176    );
177
178    Ok(())
179}
Source

pub fn try_build(self) -> Result<Box<dyn Tool>>

Builds the tool, returning a Result instead of panicking.

Returns an error if the function has not been set.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more