Skip to main content

RustTool

Trait RustTool 

Source
pub trait RustTool: Send + Sync {
    type Params: DeserializeOwned + JsonSchema + Send;

    const NAME: &'static str;
    const DESCRIPTION: &'static str;

    // Required method
    fn call(
        &self,
        params: Self::Params,
        ctx: &ToolContext,
    ) -> impl Future<Output = Result<ToolOutput, ToolError>> + Send;

    // Provided method
    fn description(&self) -> Cow<'static, str> { ... }
}
Expand description

A custom tool implemented entirely in Rust with strongly-typed parameters.

Define your parameters as a struct deriving serde::Deserialize and JsonSchema, then implement this trait to provide the tool’s logic. The JSON Schema sent to the model is derived automatically from the params struct — doc comments on fields become parameter descriptions.

Tools are async: for I/O-bound work (HTTP, filesystem, subprocess) the runtime stays unblocked. Sync tools just don’t .await anything — the compiler optimizes the state machine to an immediate return.

§Example

use llm_tool::{JsonSchema, RustTool, ToolContext, ToolError, ToolOutput};
use serde::Deserialize;

#[derive(Deserialize, JsonSchema)]
struct FlashParams {
    /// Target device identifier.
    device_id: String,
    /// Path to the firmware image.
    image_path: String,
}

struct FlashDevice;

impl RustTool for FlashDevice {
    type Params = FlashParams;
    const NAME: &'static str = "flash_device";
    const DESCRIPTION: &'static str = "Flashes firmware to a connected device.";

    async fn call(
        &self,
        params: Self::Params,
        _ctx: &ToolContext,
    ) -> Result<ToolOutput, ToolError> {
        Ok(format!("Flashed {} to {}", params.image_path, params.device_id).into())
    }
}

Required Associated Constants§

Source

const NAME: &'static str

Unique tool name (e.g. "flash_device").

Source

const DESCRIPTION: &'static str

Human-readable description shown to the model.

Required Associated Types§

Source

type Params: DeserializeOwned + JsonSchema + Send

The strongly-typed parameters struct.

Derive serde::Deserialize and JsonSchema on your params struct. JsonSchema auto-generates the parameter schema sent to the model; Deserialize parses the model’s JSON arguments into your struct.

Required Methods§

Source

fn call( &self, params: Self::Params, ctx: &ToolContext, ) -> impl Future<Output = Result<ToolOutput, ToolError>> + Send

Execute the tool with typed parameters and an execution context.

Async to support I/O-bound tools (HTTP, filesystem, subprocess). Sync tools just compute and return — the async wrapper is zero-cost.

The ctx parameter provides access to conversation metadata and a shared key-value state store. Tools that don’t need context can simply ignore it with _ctx.

§Errors

Returns Err(ToolError) if the tool execution fails.

Provided Methods§

Source

fn description(&self) -> Cow<'static, str>

Return the tool description used in ToolDefinition.

The default returns Self::DESCRIPTION (the static string from a doc comment or template body). When using #[llm_tool(template = "...", context = ...)], the generated implementation overrides this to render the template with runtime variables on each call. Templates are parsed once via LazyLock.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§