Skip to main content

Tool

Derive Macro Tool 

Source
#[derive(Tool)]
{
    // Attributes available to this derive:
    #[tool]
}
Expand description

Derives the ToolMeta half of the tool contract from struct attributes.

ToolMeta is a tool’s static identity: the name a model calls it by, a human-readable description, and its side-effect class. This derive writes that impl and nothing else. The behavior half, ToolHandler (the typed input, output, and async call), is always written by hand; the derive never sees or reasons about it.

§Usage

use salvor_tools::Tool;

#[derive(Tool)]
#[tool(effect = "write", description = "Create a Jira ticket")]
struct CreateTicket;

That expands to an impl salvor_tools::ToolMeta for CreateTicket with NAME = "create_ticket", DESCRIPTION = "Create a Jira ticket", and EFFECT = Effect::Write.

§The #[tool(...)] attribute

The derive reads a single #[tool(...)] attribute whose keys are:

  • description = "..." (required): the DESCRIPTION constant.
  • effect = "read" | "idempotent" | "write" (required): the EFFECT constant. Any other string is a compile error that names the three valid values.
  • name = "..." (optional): overrides NAME. When omitted, the name is derived from the struct identifier (see below).

Keys may be split across more than one #[tool(...)] attribute or combined in one. Repeating a key, using an unknown key, or giving a key a value that is not a string literal is a compile error.

§The default name

With no name = "...", the derive lowercases the struct identifier into snake_case by inserting an underscore at each word boundary:

  • before an uppercase letter that follows a lowercase letter or a digit (CreateTicket becomes create_ticket), and
  • before an uppercase letter that both follows another uppercase letter and is followed by a lowercase letter, which is the end of an acronym run (HTTPFetch becomes http_fetch).

A single-word identifier is simply lowercased (Ticket becomes ticket). Override the result with name = "..." when this rule does not produce the name you want.

§Hygiene

The generated code names every path from the crate root: the trait as ::salvor_tools::ToolMeta and the effect as ::salvor_tools::Effect. A use in the calling module that shadows either name (the tool author’s own Effect type, say) cannot change what the generated impl refers to.

§What it rejects

The derive applies only to a struct. Placing it on an enum or a union is a compile error, because a tool’s identity is one name, not a choice among several.