1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
extern crate proc_macro;
use TokenStream;
use ;
//References:
//<https://doc.rust-lang.org/book/ch19-06-macros.html#how-to-write-a-custom-derive-macro>
//<https://doc.rust-lang.org/reference/procedural-macros.html>
/// A macro that allows you to implement the `rig::embedding::Embed` trait by deriving it.
/// Usage can be found below:
///
/// ```text
/// use rig::Embed;
/// use rig_derive::Embed;
///
/// #[derive(Embed)]
/// struct Foo {
/// id: String,
/// #[embed] // this helper shows which field to embed
/// description: String
///}
/// ```
/// A procedural macro that transforms a function into a portable
/// `rig_core::tool::PortableTool`, or into the classic contextual
/// `rig::tool::Tool` when the function accepts classic runtime context.
///
/// # Examples
///
/// Basic usage:
/// ```text
/// use rig_derive::rig_tool;
///
/// #[rig_tool]
/// fn add(a: i32, b: i32) -> Result<i32, rig::tool::ToolExecutionError> {
/// Ok(a + b)
/// }
/// ```
///
/// With description:
/// ```text
/// use rig_derive::rig_tool;
///
/// #[rig_tool(description = "Perform basic arithmetic operations")]
/// fn calculator(x: i32, y: i32, operation: String) -> Result<i32, rig::tool::ToolExecutionError> {
/// match operation.as_str() {
/// "add" => Ok(x + y),
/// "subtract" => Ok(x - y),
/// "multiply" => Ok(x * y),
/// "divide" => Ok(x / y),
/// _ => Err(rig::tool::ToolExecutionError::other("Unknown operation")),
/// }
/// }
/// ```
///
/// With a custom tool name:
/// ```text
/// use rig_derive::rig_tool;
///
/// // Explicit names must be string literals that start with an ASCII letter
/// // or `_`, may contain ASCII letters, digits, `_`, or `-`, and be at most
/// // 64 characters long.
/// #[rig_tool(name = "search-docs", description = "Search the documentation")]
/// fn search_docs_impl(query: String) -> Result<String, rig::tool::ToolExecutionError> {
/// Ok(format!("Searching docs for {query}"))
/// }
/// ```
///
/// With parameter descriptions:
/// ```text
/// use rig_derive::rig_tool;
///
/// #[rig_tool(
/// description = "A tool that performs string operations",
/// params(
/// text = "The input text to process",
/// operation = "The operation to perform (uppercase, lowercase, reverse)"
/// )
/// )]
/// fn string_processor(text: String, operation: String) -> Result<String, rig::tool::ToolExecutionError> {
/// match operation.as_str() {
/// "uppercase" => Ok(text.to_uppercase()),
/// "lowercase" => Ok(text.to_lowercase()),
/// "reverse" => Ok(text.chars().rev().collect()),
/// _ => Err(rig::tool::ToolExecutionError::other("Unknown operation")),
/// }
/// }
/// ```
///
/// # Required parameters
///
/// Required-ness is derived from the parameter types: every non-`Option`
/// parameter is required, and `Option<T>` parameters are optional (absent
/// fields deserialize to `None`). An explicit `required(...)` list overrides
/// this. A parameter *omitted* from an explicit list is deserialized with
/// `#[serde(default)]`, so its type must be `Option<T>` or implement
/// `Default` — the advertised schema and the deserializer always agree.
/// Listing an `Option<T>` parameter is a compile error (schemars and serde
/// would both silently ignore the directive). Names in `params(...)` and
/// `required(...)` must match actual parameters.
///
/// ```text
/// use rig_derive::rig_tool;
///
/// // `b` is advertised as optional and defaults to `0` when omitted.
/// #[rig_tool(required(a))]
/// fn add(a: i64, b: i64) -> Result<i64, rig::tool::ToolExecutionError> {
/// Ok(a + b)
/// }
/// ```
///
/// # Execution context
///
/// ```text
/// use rig::tool::ToolContext;
/// use rig_derive::rig_tool;
///
/// #[rig_tool]
/// fn current_user(
/// // The marker is required for imported names and type aliases. A fully
/// // qualified `&mut rig::tool::ToolContext` — including under a renamed
/// // dependency — is recognized directly.
/// #[rig(context)] context: &mut ToolContext,
/// greeting: String,
/// ) -> Result<String, rig::tool::ToolExecutionError> {
/// let user = context
/// .get::<String>()
/// .map(String::as_str)
/// .unwrap_or("guest");
/// Ok(format!("{greeting}, {user}!"))
/// }
/// ```