derive_agent_tools 0.1.0

Derive macros for defining AI tools from structs.
Documentation

derive_agent_tools

Derive macros to define AI tools and their parameters directly from Rust structs.

  • AgentTool: derive on a struct to generate an AWS Bedrock ToolSpecification, a JSON schema helper, and an implementation to parse Bedrock tool inputs into your struct.
  • AgentToolParameter: derive on supporting types; currently provides a basic JSON schema helper. This will expand as more providers are supported.

Status: Bedrock-only today. Additional tool formats will be added over time.

Why

Writing Bedrock tool schemas by hand is repetitive and error‑prone. derive_agent_tools lets you define a tool once as a Rust type and get:

  • A validated JSON schema (properties + required)
  • A Bedrock ToolSpecification
  • A TryFrom<&aws_smithy_types::Document> impl to parse tool inputs into your struct

Install

Add to your Cargo.toml:

[dependencies]
derive_agent_tools = "0.1"
serde = { version = "1", features = ["derive"] }

Features

derive_agent_tools exposes two optional capabilities controlled by feature flags. Both of them are enabled by default.

  • serde-json – builds JSON Schema helpers and requires serde/serde_json at runtime.
  • bedrock – generates AWS Bedrock ToolSpecification builders and pulls in the AWS SDK dependencies.

If you want to opt out of the AWS SDK dependencies, disable default features and pick the subset you need:

[dependencies]
derive_agent_tools = { version = "0.1", default-features = false, features = ["serde-json"] }
serde = { version = "1", features = ["derive"] }

With this configuration the crate still derives tools and the JSON schema helpers compile, but Bedrock-specific functions such as AgentTool::tool_spec() are not generated.

Usage

use derive_agent_tools::AgentTool;
use serde::Deserialize;

#[derive(AgentTool, Deserialize)]
#[tool(description = "A tool to get the weather")]
struct WeatherTool {
    #[tool(required, description = "The latitude of the location")]
    latitude: f64,
    #[tool(required, description = "The longitude of the location")]
    longitude: f64,
}

// Register tool with Bedrock
#[cfg(feature = "bedrock")]
let spec = WeatherTool::tool_spec();

// Inspect schema if desired
#[cfg(feature = "serde-json")]
let schema = WeatherTool::tool_schema_json();

// If your Agent returns a ToolUse input Document, you can parse it:
// let args: WeatherTool = (&document).try_into()?;

Attributes

  • Struct-level #[tool(...)]:
    • name = "..." override the tool name (defaults to struct name)
    • description = "..." human-friendly description
  • Field-level #[tool(...)]:
    • required mark a field as required (otherwise it is optional in the schema)
    • description = "..." field description

Type mapping

Basic Rust types map to JSON Schema as follows:

  • bool -> boolean
  • integer types -> integer
  • f32, f64 -> number
  • String, &str -> string
  • Vec<T> -> array (best-effort items type)
  • Option<T> -> uses T's type but is not marked as required
  • Other types default to object

This mapping is intentionally minimal and conservative. It will be expanded over time.

Bedrock Support

tool_spec() builds an aws_sdk_bedrockruntime::types::ToolSpecification using a JSON schema generated from your struct and annotations. Only Bedrock is supported at present. The crate is structured to support additional providers in the future through feature flags and provider-specific builders.

Error Handling

  • Misuse of the macros (e.g., deriving on non-structs or tuple structs) produces compile‑time errors.
  • When the generated TryFrom<&Document> implementation fails to deserialize the payload, the error message is captured in a lightweight, per-type error struct.