#[tool]Expand description
The #[tool] attribute macro — turns an async fn into a registrable Gemini tool.
See the gemini_adk_macros_rs::tool documentation for details.
Turn a documented async fn into a registrable Gemini tool.
The function’s doc comment is what the model reads: its opening prose is
the tool’s description, and a # Arguments section describes each
parameter. The parameter types are the schema.
/// Get the current weather for a city.
///
/// # Arguments
///
/// * `city` - The city name, e.g. "Paris".
/// * `units` - "metric" or "imperial"; metric when omitted.
#[tool]
async fn get_weather(city: String, units: Option<String>) -> Result<Weather, reqwest::Error> {
fetch_weather(&city, units.as_deref()).await
}
agent.tool(get_weather());§Description
The doc comment’s prose up to its first # heading, with wrapped lines
joined. #[tool("...")] replaces it when the text for the model should
differ from the text for readers. A tool with neither is a compile error:
the model chooses tools by their descriptions.
§Arguments
Each item of a # Arguments (or # Args, # Parameters) section — in the
rustdoc form * `name` - text or - `name`: text — becomes that
parameter’s schema description. Naming a parameter the function does not
have is a compile error, so the documentation cannot drift from the
signature.
Every parameter type must be serde::Deserialize + schemars::JsonSchema
and owned (String, not &str): arguments are deserialized from the
model’s JSON. Option<T> parameters are optional. The schema is produced
by gemini_adk_rs::tool::wire_schema, so nested types are inlined and
optional fields declare a single type, as the API requires.
§Return type
- A type spelled
Result<T, E>(under any path:anyhow::Result<T>,io::Result<T>) is fallible.Tis anyserde::Serializetype;Eis any error — aToolErrorkeeps its variant, anything else becomesToolError::ExecutionFailedwith its message. - Any other type is the tool’s output, and the tool cannot fail.
- No return type sends
null.
A result that is not a JSON object reaches the model as {"output": ..}.
A Result behind an alias with another name is not recognized; spell the
return type as Result<..>.
§What it generates
A constructor fn get_weather() -> impl ToolFunction (with the original
visibility and doc comment) whose value you register:
agent.tool(get_weather()), or
dispatcher.register_function(Arc::new(get_weather())). The original body
runs in a hidden async fn, which keeps the function’s other attributes
(#[allow], #[tracing::instrument], …); #[cfg] applies to every
generated item.
§Path hygiene
Generated code reaches serde, schemars, serde_json, and async_trait
through the runtime crate’s __macros module, so none of them need to be
in your Cargo.toml. The runtime crate is located at expansion time:
gemini-adk-rs if it is a direct dependency (under whatever name), else
through the re-export in gemini-adk or gemini-adk-fluent-rs.