1#![cfg_attr(test, allow(dead_code, unused_imports))]
19
20use proc_macro::TokenStream;
21use proc_macro_crate::{FoundCrate, crate_name};
22use proc_macro2::Span;
23
24use crate::transaction::golem_operation_impl;
25
26mod agentic;
27mod rpc_client_common;
28mod tool;
29mod transaction;
30
31#[cfg(test)]
32test_r::enable!();
33
34#[cfg(not(test))]
35#[proc_macro_derive(MultimodalSchema)]
36pub fn derive_multimodal(input: TokenStream) -> TokenStream {
37 agentic::derive_multimodal(input)
38}
39
40#[cfg(not(test))]
41#[proc_macro_derive(ConfigSchema, attributes(config_schema))]
42pub fn derive_config_schema(input: TokenStream) -> TokenStream {
43 let golem_rust_crate_ident = get_golem_rust_crate_ident();
44
45 agentic::derive_config_schema(input, &golem_rust_crate_ident)
46}
47
48#[cfg(not(test))]
49#[proc_macro_derive(AllowedLanguages, attributes(code))]
50pub fn derive_allowed_languages(input: TokenStream) -> TokenStream {
51 let golem_rust_crate_ident = get_golem_rust_crate_ident();
52
53 agentic::derive_allowed_languages(input, &golem_rust_crate_ident)
54}
55
56#[cfg(not(test))]
57#[proc_macro_derive(AllowedMimeTypes, attributes(mime_type))]
58pub fn derive_allowed_mimetypes(input: TokenStream) -> TokenStream {
59 let golem_rust_crate_ident = get_golem_rust_crate_ident();
60
61 agentic::derive_allowed_mime_types(input, &golem_rust_crate_ident)
62}
63
64#[cfg(not(test))]
65#[proc_macro_attribute]
66pub fn description(_attr: TokenStream, item: TokenStream) -> TokenStream {
67 item
68}
69
70#[cfg(not(test))]
71#[proc_macro_attribute]
72pub fn prompt(_attr: TokenStream, item: TokenStream) -> TokenStream {
73 item
74}
75
76#[cfg(not(test))]
77#[proc_macro_attribute]
78pub fn endpoint(_attr: TokenStream, item: TokenStream) -> TokenStream {
79 item
80}
81
82#[cfg(not(test))]
83#[proc_macro_attribute]
84pub fn read_only(_attr: TokenStream, item: TokenStream) -> TokenStream {
85 item
86}
87
88#[cfg(not(test))]
90#[proc_macro_attribute]
91pub fn golem_operation(attr: TokenStream, item: TokenStream) -> TokenStream {
92 golem_operation_impl(attr, item)
93}
94
95#[cfg(not(test))]
96#[proc_macro_attribute]
97pub fn agent_definition(attr: TokenStream, item: TokenStream) -> TokenStream {
98 agentic::agent_definition_impl(attr, item)
99}
100
101#[cfg(not(test))]
102#[proc_macro_attribute]
103pub fn agent_implementation(attr: TokenStream, item: TokenStream) -> TokenStream {
104 agentic::agent_implementation_impl(attr, item)
105}
106
107#[cfg(not(test))]
109#[proc_macro_attribute]
110pub fn http_router(attr: TokenStream, item: TokenStream) -> TokenStream {
111 agentic::http_router::expand(attr.into(), item.into())
112 .unwrap_or_else(|error| error.to_compile_error())
113 .into()
114}
115
116#[cfg(not(test))]
117#[proc_macro_attribute]
118pub fn agent_client(attr: TokenStream, item: TokenStream) -> TokenStream {
119 agentic::agent_client_impl(attr, item, &get_golem_rust_crate_ident())
120}
121
122#[cfg(not(test))]
123#[proc_macro_attribute]
124pub fn tool_definition(attr: TokenStream, item: TokenStream) -> TokenStream {
125 tool::tool_definition_impl(attr, item, &get_golem_rust_crate_ident())
126}
127
128#[cfg(not(test))]
129#[proc_macro_attribute]
130pub fn tool_implementation(attr: TokenStream, item: TokenStream) -> TokenStream {
131 tool::tool_implementation_impl(attr, item, &get_golem_rust_crate_ident())
132}
133
134#[doc(hidden)]
135#[cfg(not(test))]
136#[proc_macro_attribute]
137pub fn native_tool_definition(attr: TokenStream, item: TokenStream) -> TokenStream {
138 tool::native::native_tool_definition_impl(attr, item, &get_native_tool_crate_ident())
139}
140
141#[doc(hidden)]
142#[cfg(not(test))]
143#[proc_macro_attribute]
144pub fn native_tool_implementation(attr: TokenStream, item: TokenStream) -> TokenStream {
145 tool::native::native_tool_implementation_impl(attr, item, &get_native_tool_crate_ident())
146}
147
148fn get_native_tool_crate_ident() -> syn::Ident {
149 match crate_name("golem-native-tool") {
150 Ok(FoundCrate::Itself) => syn::Ident::new("crate", Span::call_site()),
151 Ok(FoundCrate::Name(name)) => syn::Ident::new(&name, Span::call_site()),
152 Err(_) => syn::Ident::new("golem_native_tool", Span::call_site()),
153 }
154}
155
156#[cfg(not(test))]
157#[proc_macro_attribute]
158pub fn tool_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
159 tool::tool_middleware_impl(attr, item, &get_golem_rust_crate_ident())
160}
161
162#[cfg(not(test))]
163#[proc_macro_attribute]
164pub fn universal_tool_middleware(attr: TokenStream, item: TokenStream) -> TokenStream {
165 tool::universal_tool_middleware_impl(attr, item, &get_golem_rust_crate_ident())
166}
167
168#[cfg(not(test))]
169#[proc_macro_derive(ToolError, attributes(tool_error, example))]
170pub fn derive_tool_error(input: TokenStream) -> TokenStream {
171 let guest = crate_name("golem-rust").is_ok() || crate_name("golem-native-tool").is_err();
172 tool::derive_tool_error_impl(input, &get_tool_schema_crate_ident(), guest)
173}
174
175fn get_tool_schema_crate_ident() -> syn::Ident {
176 if crate_name("golem-rust").is_ok() {
177 get_golem_rust_crate_ident()
178 } else {
179 match crate_name("golem-native-tool") {
180 Ok(FoundCrate::Itself) => syn::Ident::new("crate", Span::call_site()),
181 Ok(FoundCrate::Name(name)) => syn::Ident::new(&name, Span::call_site()),
182 Err(_) => syn::Ident::new("golem_rust", Span::call_site()),
183 }
184 }
185}
186
187#[doc(hidden)]
188#[cfg(not(test))]
189#[proc_macro]
190pub fn __golem_emit_tool_middleware_leaf(input: TokenStream) -> TokenStream {
191 match tool::middleware_surface::emit_tool_middleware_leaf(input.into()) {
192 Ok(tokens) => tokens.into(),
193 Err(error) => error.to_compile_error().into(),
194 }
195}
196
197fn misplaced_tool_helper_attr(name: &str) -> TokenStream {
204 syn::Error::new(
205 Span::call_site(),
206 format!("#[{name}] may only be used on methods inside a #[tool_definition] trait"),
207 )
208 .to_compile_error()
209 .into()
210}
211
212#[cfg(not(test))]
213#[proc_macro_attribute]
214pub fn arg(_attr: TokenStream, _item: TokenStream) -> TokenStream {
215 misplaced_tool_helper_attr("arg")
216}
217
218#[cfg(not(test))]
219#[proc_macro_attribute]
220pub fn command(_attr: TokenStream, _item: TokenStream) -> TokenStream {
221 misplaced_tool_helper_attr("command")
222}
223
224#[cfg(not(test))]
225#[proc_macro_attribute]
226pub fn constraint(_attr: TokenStream, _item: TokenStream) -> TokenStream {
227 misplaced_tool_helper_attr("constraint")
228}
229
230#[cfg(not(test))]
231#[proc_macro_attribute]
232pub fn result(_attr: TokenStream, _item: TokenStream) -> TokenStream {
233 misplaced_tool_helper_attr("result")
234}
235
236fn get_golem_rust_crate_ident() -> syn::Ident {
240 match crate_name("golem-rust") {
241 Ok(FoundCrate::Itself) => syn::Ident::new("crate", Span::call_site()),
242 Ok(FoundCrate::Name(name)) => syn::Ident::new(&name, Span::call_site()),
243 Err(_) => syn::Ident::new("golem_rust", Span::call_site()),
244 }
245}