adk_tool/builtin/
gemini_extra.rs1use adk_core::{Result, Tool, ToolContext};
2use async_trait::async_trait;
3use serde_json::{Value, json};
4use std::sync::Arc;
5
6#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct GoogleMapsContext {
9 latitude: f64,
10 longitude: f64,
11}
12
13impl GoogleMapsContext {
14 pub fn new(latitude: f64, longitude: f64) -> Self {
16 Self { latitude, longitude }
17 }
18
19 fn to_json(self) -> Value {
20 json!({
21 "retrievalConfig": {
22 "latLng": {
23 "latitude": self.latitude,
24 "longitude": self.longitude,
25 }
26 }
27 })
28 }
29}
30
31#[derive(Debug, Clone, Default)]
33pub struct GoogleMapsTool {
34 enable_widget: bool,
35 context: Option<GoogleMapsContext>,
36}
37
38impl GoogleMapsTool {
39 pub fn new() -> Self {
41 Self::default()
42 }
43
44 pub fn with_widget(mut self, enable_widget: bool) -> Self {
46 self.enable_widget = enable_widget;
47 self
48 }
49
50 pub fn with_context(mut self, context: GoogleMapsContext) -> Self {
52 self.context = Some(context);
53 self
54 }
55}
56
57#[async_trait]
58impl Tool for GoogleMapsTool {
59 fn name(&self) -> &str {
60 "google_maps"
61 }
62
63 fn description(&self) -> &str {
64 "Grounds responses with Google Maps data for places, routes, and local context."
65 }
66
67 fn is_builtin(&self) -> bool {
68 true
69 }
70
71 fn declaration(&self) -> Value {
72 json!({
73 "name": self.name(),
74 "description": self.description(),
75 "x-adk-gemini-tool": {
76 "google_maps": {
77 "enable_widget": self.enable_widget.then_some(true),
78 }
79 },
80 "x-adk-gemini-tool-config": self.context.map(GoogleMapsContext::to_json),
81 })
82 }
83
84 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
85 Err(adk_core::AdkError::tool("GoogleMaps is handled internally by Gemini"))
86 }
87}
88
89#[derive(Debug, Clone, Default)]
91pub struct GeminiCodeExecutionTool;
92
93impl GeminiCodeExecutionTool {
94 pub fn new() -> Self {
96 Self
97 }
98}
99
100#[async_trait]
101impl Tool for GeminiCodeExecutionTool {
102 fn name(&self) -> &str {
103 "gemini_code_execution"
104 }
105
106 fn description(&self) -> &str {
107 "Allows Gemini to write and execute Python code server-side."
108 }
109
110 fn is_builtin(&self) -> bool {
111 true
112 }
113
114 fn declaration(&self) -> Value {
115 json!({
116 "name": self.name(),
117 "description": self.description(),
118 "x-adk-gemini-tool": {
119 "code_execution": {}
120 }
121 })
122 }
123
124 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
125 Err(adk_core::AdkError::tool("Gemini code execution is handled internally by Gemini"))
126 }
127}
128
129#[derive(Debug, Clone)]
131pub struct GeminiFileSearchTool {
132 file_search_store_names: Vec<String>,
133}
134
135impl GeminiFileSearchTool {
136 pub fn new(file_search_store_names: impl IntoIterator<Item = impl Into<String>>) -> Self {
138 Self {
139 file_search_store_names: file_search_store_names.into_iter().map(Into::into).collect(),
140 }
141 }
142}
143
144#[async_trait]
145impl Tool for GeminiFileSearchTool {
146 fn name(&self) -> &str {
147 "gemini_file_search"
148 }
149
150 fn description(&self) -> &str {
151 "Searches Gemini File Search stores for relevant documents."
152 }
153
154 fn is_builtin(&self) -> bool {
155 true
156 }
157
158 fn declaration(&self) -> Value {
159 json!({
160 "name": self.name(),
161 "description": self.description(),
162 "x-adk-gemini-tool": {
163 "file_search": {
164 "file_search_store_names": self.file_search_store_names
165 }
166 }
167 })
168 }
169
170 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
171 Err(adk_core::AdkError::tool("Gemini file search is handled internally by Gemini"))
172 }
173}
174
175#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177pub enum GeminiComputerEnvironment {
178 Browser,
180}
181
182impl GeminiComputerEnvironment {
183 fn as_wire(self) -> &'static str {
184 match self {
185 Self::Browser => "ENVIRONMENT_BROWSER",
186 }
187 }
188}
189
190#[derive(Debug, Clone)]
192pub struct GeminiComputerUseTool {
193 environment: GeminiComputerEnvironment,
194 excluded_predefined_functions: Vec<String>,
195}
196
197impl Default for GeminiComputerUseTool {
198 fn default() -> Self {
199 Self {
200 environment: GeminiComputerEnvironment::Browser,
201 excluded_predefined_functions: Vec::new(),
202 }
203 }
204}
205
206impl GeminiComputerUseTool {
207 pub fn new(environment: GeminiComputerEnvironment) -> Self {
209 Self { environment, ..Default::default() }
210 }
211
212 pub fn with_excluded_functions(
214 mut self,
215 excluded_predefined_functions: impl IntoIterator<Item = impl Into<String>>,
216 ) -> Self {
217 self.excluded_predefined_functions =
218 excluded_predefined_functions.into_iter().map(Into::into).collect();
219 self
220 }
221}
222
223#[async_trait]
224impl Tool for GeminiComputerUseTool {
225 fn name(&self) -> &str {
226 "gemini_computer_use"
227 }
228
229 fn description(&self) -> &str {
230 "Enables Gemini computer use, which emits predefined UI action function calls."
231 }
232
233 fn is_builtin(&self) -> bool {
234 true
235 }
236
237 fn declaration(&self) -> Value {
238 json!({
239 "name": self.name(),
240 "description": self.description(),
241 "x-adk-gemini-tool": {
242 "computer_use": {
243 "environment": self.environment.as_wire(),
244 "excluded_predefined_functions": (!self.excluded_predefined_functions.is_empty())
245 .then_some(self.excluded_predefined_functions.clone()),
246 }
247 }
248 })
249 }
250
251 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
252 Err(adk_core::AdkError::tool("Gemini computer use actions must be executed client-side"))
253 }
254}