Skip to main content

serdes_ai_macros/
lib.rs

1//! # serdes-ai-macros
2//!
3//! Procedural macros for serdes-ai.
4//!
5//! This crate provides derive macros and attribute macros to reduce boilerplate
6//! when defining tools, agents, and output schemas.
7//!
8//! ## Tool Macro
9//!
10//! ```ignore
11//! #[derive(Tool)]
12//! #[tool(name = "get_weather", description = "Get current weather")]
13//! struct GetWeather {
14//!     city: String,
15//!     units: Option<String>,
16//! }
17//! ```
18//!
19//! ## Output Schema Macro
20//!
21//! ```ignore
22//! #[derive(OutputSchema)]
23//! #[output(description = "Weather response")]
24//! struct WeatherResponse {
25//!     /// Temperature in requested units
26//!     temperature: f64,
27//!     /// Weather description
28//!     description: String,
29//! }
30//! ```
31//!
32//! ## Agent Macro
33//!
34//! ```ignore
35//! #[derive(Agent)]
36//! #[agent(model = "openai:gpt-4", system_prompt = "You are helpful.")]
37//! struct MyAgent;
38//! ```
39
40extern crate proc_macro;
41
42mod agent;
43mod output;
44mod tool;
45
46use proc_macro::TokenStream;
47
48/// Derive macro for implementing the `Tool` trait.
49///
50/// Generates a `Tool` implementation that provides tool definition
51/// with JSON schema derived from struct fields.
52///
53/// # Attributes
54///
55/// - `#[tool(name = "...")]` - Override tool name (default: snake_case struct name)
56/// - `#[tool(description = "...")]` - Tool description for the model
57/// - `#[tool(strict)]` - Enable strict mode for tool calls
58///
59/// # Example
60///
61/// ```ignore
62/// #[derive(Tool)]
63/// #[tool(name = "search", description = "Search the web")]
64/// struct SearchWeb {
65///     query: String,
66///     limit: Option<u32>,
67/// }
68/// ```
69#[proc_macro_derive(Tool, attributes(tool))]
70pub fn derive_tool(input: TokenStream) -> TokenStream {
71    tool::derive_tool_impl(input)
72}
73
74/// Attribute macro for creating tools from functions.
75///
76/// Transforms a function into a tool by generating argument struct
77/// and tool wrapper.
78///
79/// # Example
80///
81/// ```ignore
82/// #[tool]
83/// async fn get_weather(ctx: RunContext, city: String) -> Result<String, ToolError> {
84///     // Implementation
85///     Ok(format!("Weather in {}", city))
86/// }
87/// ```
88#[proc_macro_attribute]
89pub fn tool(attr: TokenStream, item: TokenStream) -> TokenStream {
90    tool::tool_attribute_impl(attr, item)
91}
92
93/// Derive macro for implementing the `OutputSchema` trait.
94///
95/// Generates JSON Schema for structured output validation.
96///
97/// # Attributes
98///
99/// - `#[output(description = "...")]` - Schema description
100/// - `#[output(strict = false)]` - Disable strict mode
101///
102/// # Example
103///
104/// ```ignore
105/// #[derive(OutputSchema, Deserialize)]
106/// #[output(description = "A person's information")]
107/// struct Person {
108///     /// Person's full name
109///     name: String,
110///     /// Age in years
111///     age: u32,
112///     /// Optional email address
113///     email: Option<String>,
114/// }
115/// ```
116#[proc_macro_derive(OutputSchema, attributes(output))]
117pub fn derive_output_schema(input: TokenStream) -> TokenStream {
118    output::derive_output_schema_impl(input)
119}
120
121/// Attribute macro for defining agents.
122///
123/// Adds agent configuration methods to a struct.
124///
125/// # Attributes
126///
127/// - `model = "..."`- Model identifier
128/// - `system_prompt = "..."` - System prompt
129///
130/// # Example
131///
132/// ```ignore
133/// #[agent(model = "openai:gpt-4o", system_prompt = "You are helpful.")]
134/// struct AssistantAgent;
135/// ```
136#[proc_macro_attribute]
137pub fn agent(attr: TokenStream, item: TokenStream) -> TokenStream {
138    agent::agent_attribute_impl(attr, item)
139}
140
141/// Derive macro for implementing agent configuration.
142///
143/// # Example
144///
145/// ```ignore
146/// #[derive(Agent)]
147/// #[agent(model = "openai:gpt-4", result = String)]
148/// struct MyAgent {
149///     context: String,
150/// }
151/// ```
152#[proc_macro_derive(Agent, attributes(agent))]
153pub fn derive_agent(input: TokenStream) -> TokenStream {
154    agent::derive_agent_impl(input)
155}