Skip to main content

Crate tokitai_macros

Crate tokitai_macros 

Source
Expand description

§Tokitai Macros

Procedural macros for Tokitai - Zero-dependency macro for AI tool integration

This crate provides the #[tool] procedural macro that enables compile-time tool definitions for AI/LLM tool calling systems. It generates all the boilerplate code needed to expose your Rust functions as AI-callable tools.

§🎯 Key Features

  • Zero Runtime Dependencies - The macro itself has no runtime overhead
  • Compile-time Generation - Tool definitions are generated at compile time
  • Type Safety - Parameter validation happens at compile time
  • Automatic Discovery - Mark an impl block and all pub methods become tools
  • Customizable - Override tool names and descriptions via attributes
  • Vendor Neutral - Works with any AI/LLM provider (Ollama, OpenAI, Anthropic, etc.)

§Quick Start

Add to your Cargo.toml:

[dependencies]
tokitai = "0.3.3"

Then use the #[tool] macro:

ⓘ
use tokitai::tool;

pub struct Calculator;

#[tool]
impl Calculator {
    /// Add two numbers together
    pub async fn add(&self, a: i32, b: i32) -> i32 {
        a + b
    }

    /// Multiply two numbers
    pub async fn multiply(&self, a: i32, b: i32) -> i32 {
        a * b
    }
}

// Usage
let calc = Calculator;

// Get tool definitions (compile-time generated)
let tools = Calculator::tool_definitions();
println!("Number of tools: {}", tools.len());

// Call a tool
let result = calc.call_tool("add", &serde_json::json!({"a": 10, "b": 20})).unwrap();
println!("Result: {}", result);  // 30

§How It Works

The #[tool] macro automatically:

  1. Extracts doc comments as tool descriptions
  2. Generates JSON Schema for parameters from Rust types
  3. Creates TOOL_DEFINITIONS constant with all tool metadata
  4. Implements call_tool dispatcher for runtime invocation
  5. Generates parameter parsing and validation code

§Customization

You can customize tool names and descriptions using the attribute syntax:

ⓘ
#[tool]
impl MyTools {
    #[tool(name = "fetch_url", desc = "Fetch content from a URL")]
    pub async fn fetch(&self, url: String) -> String {
        // implementation
    }
}

§Generated Code

For each #[tool] impl block, the macro generates:

ⓘ
// 1. Tool definitions constant
impl Calculator {
    pub const TOOL_DEFINITIONS: &'static [ToolDefinition] = &[
        ToolDefinition {
            name: "add",
            description: "Add two numbers together",
            input_schema: "{\"type\":\"object\",\"properties\":{\"a\":{\"type\":\"integer\"},\"b\":{\"type\":\"integer\"}},\"required\":[\"a\",\"b\"]}",
        },
        // ... more tools
    ];
}

// 2. ToolProvider trait implementation
impl ToolProvider for Calculator {
    fn tool_definitions() -> &'static [ToolDefinition] {
        Self::tool_definitions()
    }
}

// 3. call_tool dispatcher
impl Calculator {
    pub fn call_tool(&self, name: &str, args: &Value) -> Result<Value, ToolError> {
        match name {
            "add" => self.__call_add(args).await,
            "multiply" => self.__call_multiply(args).await,
            _ => Err(ToolError::not_found(format!("Unknown tool: {}", name))),
        }
    }
}

§Type Mapping

Rust types are automatically mapped to JSON Schema types with full recursive support:

§Basic Types

Rust TypeJSON Schema Type
String, strstring
i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, usize, isizeinteger
f32, f64number
boolboolean

§Compound Types

Rust TypeJSON Schema Type
Vec<T>array with items schema
[T; N]array with items schema
&[T]array with items schema
HashMap<K, V>object with additionalProperties
Option<T>anyOf with inner type and null
(T, U, ...)array (tuple representation)

§Third-party Types

Rust TypeJSON Schema Type
chrono::DateTime<Utc>string with format: date-time
chrono::NaiveDateTimestring with format: date-time
uuid::Uuidstring with format: uuid
url::Urlstring with format: uri
PathBuf, Pathstring with format: file-path

§Custom Types

Custom structs are represented as object types. For full field-level schema generation, ensure your struct derives serde::Deserialize and the macro will handle it at runtime.

§Requirements

  • Rust Version: 1.70+
  • Edition: 2021

§License

Licensed under either of:

at your option.

§Contributing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

§See Also

Macros§

config
tokitai! Configuration Macro

Attribute Macros§

param_tool
Parameter-level tool attributes (helper macro for #[tool])
tool
#[tool] Attribute Macro
tool_default
Parameter default attribute (used internally by #[tool] macro)
tool_desc
Parameter description attribute (used internally by #[tool] macro)
tool_example
Parameter example attribute (used internally by #[tool] macro)
tool_max
Parameter max attribute (used internally by #[tool] macro)
tool_max_items
Parameter max_items attribute (used internally by #[tool] macro)
tool_max_length
Parameter max_length attribute (used internally by #[tool] macro)
tool_min
Parameter min attribute (used internally by #[tool] macro)
tool_min_items
Parameter min_items attribute (used internally by #[tool] macro)
tool_min_length
Parameter min_length attribute (used internally by #[tool] macro)
tool_multiple_of
Parameter multiple_of attribute (used internally by #[tool] macro)
tool_pattern
Parameter pattern attribute (used internally by #[tool] macro)
tool_required
Parameter required attribute (used internally by #[tool] macro)
tool_transform
Parameter transformation attribute (used internally by #[tool] macro)
tool_type
#[tool_type] Attribute Macro
tool_validate
Parameter validation attribute (used internally by #[tool] macro)