pub struct ToolBuilder { /* private fields */ }Expand description
Fluent builder for defining tools with both schemas and handlers.
ToolBuilder combines tool definitions (sent to the API) with tool handlers
(for local execution), similar to the TypeScript/Go SDK patterns.
§Example
use modelrelay::{ToolBuilder, ToolCall};
use schemars::JsonSchema;
use serde::Deserialize;
use serde_json::json;
#[derive(JsonSchema, Deserialize)]
struct WeatherArgs {
/// City name
location: String,
/// Temperature unit (optional)
unit: Option<String>,
}
let tools = ToolBuilder::new()
.add_sync::<WeatherArgs, _>("get_weather", "Get weather for a location", |args, _call| {
Ok(json!({ "temp": 72, "location": args.location }))
})
.add_async::<SearchArgs, _>("search", "Search the web", |args, _call| {
Box::pin(async move {
Ok(json!({ "results": ["result1", "result2"] }))
})
});
// Extract definitions for API request
let (definitions, registry) = tools.build();Implementations§
Source§impl ToolBuilder
impl ToolBuilder
Sourcepub fn add_sync<T, F>(
self,
name: impl Into<String>,
description: impl Into<String>,
handler: F,
) -> Selfwhere
T: JsonSchema + DeserializeOwned + Send + 'static,
F: Fn(T, ToolCall) -> Result<Value, String> + Send + Sync + 'static,
pub fn add_sync<T, F>(
self,
name: impl Into<String>,
description: impl Into<String>,
handler: F,
) -> Selfwhere
T: JsonSchema + DeserializeOwned + Send + 'static,
F: Fn(T, ToolCall) -> Result<Value, String> + Send + Sync + 'static,
Adds a synchronous tool handler with type-safe arguments.
The argument type must implement JsonSchema (for generating the schema)
and DeserializeOwned (for parsing incoming arguments).
§Example
use schemars::JsonSchema;
use serde::Deserialize;
use modelrelay::ToolBuilder;
#[derive(JsonSchema, Deserialize)]
struct Args { path: String }
let tools = ToolBuilder::new()
.add_sync::<Args, _>("read_file", "Read a file", |args, _call| {
Ok(serde_json::json!({ "content": "file contents" }))
});Sourcepub fn add_async<T, F>(
self,
name: impl Into<String>,
description: impl Into<String>,
handler: F,
) -> Self
pub fn add_async<T, F>( self, name: impl Into<String>, description: impl Into<String>, handler: F, ) -> Self
Adds an asynchronous tool handler with type-safe arguments.
The handler returns a boxed future for async execution.
§Example
use schemars::JsonSchema;
use serde::Deserialize;
use modelrelay::ToolBuilder;
#[derive(JsonSchema, Deserialize)]
struct Args { query: String }
let tools = ToolBuilder::new()
.add_async::<Args>("search", "Search the web", |args, _call| {
Box::pin(async move {
Ok(serde_json::json!({ "results": ["result"] }))
})
});Sourcepub fn add_raw(
self,
name: impl Into<String>,
description: impl Into<String>,
parameters: Option<Value>,
handler: ToolHandler,
) -> Self
pub fn add_raw( self, name: impl Into<String>, description: impl Into<String>, parameters: Option<Value>, handler: ToolHandler, ) -> Self
Adds a raw tool handler without type-safe argument parsing.
Use this when you want to handle argument parsing yourself or need more control over the handler behavior.
Sourcepub fn definitions(&self) -> Vec<Tool>
pub fn definitions(&self) -> Vec<Tool>
Returns just the tool definitions (for API requests).
Sourcepub fn registry(&self) -> &ToolRegistry
pub fn registry(&self) -> &ToolRegistry
Returns just the tool registry (for execution).
Sourcepub fn build(self) -> (Vec<Tool>, ToolRegistry)
pub fn build(self) -> (Vec<Tool>, ToolRegistry)
Consumes the builder and returns both definitions and registry.
This is typically called when passing tools to an agent loop.