#[tool]Expand description
Attribute macro for defining tools with automatic parameter extraction.
This macro generates a zero-sized struct with the function name and implements
the BaseTool trait directly, eliminating manual parameter extraction and JSON schema construction.
The function name is used as the tool name, so choose function names that accurately describe the tool’s purpose.
§Required Parameters
description: A detailed description of what the tool does (String)
§Example
ⓘ
use radkit::tools::{ToolResult, ToolContext};
use radkit_macros::tool;
use serde::{Deserialize};
use schemars::JsonSchema;
use serde_json::json;
#[derive(Deserialize, JsonSchema)]
struct AddArgs {
a: i64,
b: i64,
}
#[tool(description = "Add two numbers")]
async fn add(args: AddArgs) -> ToolResult {
ToolResult::success(json!({"sum": args.a + args.b}))
}
// With ToolContext
#[derive(Deserialize, JsonSchema)]
struct SaveArgs {
key: String,
value: String,
}
#[tool(description = "Save state")]
async fn save_state(args: SaveArgs, ctx: &ToolContext<'_>) -> ToolResult {
ctx.state().set_state(&args.key, json!(args.value));
ToolResult::success(json!({"saved": true}))
}§Generated Code
The macro transforms the async function into a zero-sized struct that implements
BaseTool. Parameters are automatically deserialized using serde and the JSON
schema is generated using schemars. The function name becomes both the struct
name and the tool name visible to the LLM.
§Usage
ⓘ
// Pass the tool struct directly to with_tool() - no function call!
let worker = LlmWorker::builder(llm)
.with_tool(add) // ← Not add()
.with_tool(save_state) // ← Not save_state()
.build();