adk_tool/builtin/
gemini_extra.rs1use crate::builtin::bypass::BypassMultiToolsLimit;
2use adk_core::{Result, Tool, ToolContext};
3use async_trait::async_trait;
4use serde_json::{Value, json};
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
9pub struct GoogleMapsContext {
10 latitude: f64,
11 longitude: f64,
12}
13
14impl GoogleMapsContext {
15 pub fn new(latitude: f64, longitude: f64) -> Self {
17 Self { latitude, longitude }
18 }
19
20 fn to_json(self) -> Value {
21 json!({
22 "retrievalConfig": {
23 "latLng": {
24 "latitude": self.latitude,
25 "longitude": self.longitude,
26 }
27 }
28 })
29 }
30}
31
32#[derive(Debug, Clone, Default)]
34pub struct GoogleMapsTool {
35 enable_widget: bool,
36 context: Option<GoogleMapsContext>,
37}
38
39impl GoogleMapsTool {
40 pub fn new() -> Self {
42 Self::default()
43 }
44
45 pub fn with_widget(mut self, enable_widget: bool) -> Self {
47 self.enable_widget = enable_widget;
48 self
49 }
50
51 pub fn with_context(mut self, context: GoogleMapsContext) -> Self {
53 self.context = Some(context);
54 self
55 }
56}
57
58#[async_trait]
59impl Tool for GoogleMapsTool {
60 fn name(&self) -> &str {
61 "google_maps"
62 }
63
64 fn description(&self) -> &str {
65 "Grounds responses with Google Maps data for places, routes, and local context."
66 }
67
68 fn is_builtin(&self) -> bool {
69 true
70 }
71
72 fn declaration(&self) -> Value {
73 json!({
74 "name": self.name(),
75 "description": self.description(),
76 "x-adk-gemini-tool": {
77 "google_maps": {
78 "enable_widget": self.enable_widget.then_some(true),
79 }
80 },
81 "x-adk-gemini-tool-config": self.context.map(GoogleMapsContext::to_json),
82 })
83 }
84
85 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
86 Err(adk_core::AdkError::tool("GoogleMaps is handled internally by Gemini"))
87 }
88}
89
90#[derive(Debug, Clone, Default)]
92pub struct GeminiCodeExecutionTool;
93
94impl GeminiCodeExecutionTool {
95 pub fn new() -> Self {
97 Self
98 }
99}
100
101#[async_trait]
102impl Tool for GeminiCodeExecutionTool {
103 fn name(&self) -> &str {
104 "gemini_code_execution"
105 }
106
107 fn description(&self) -> &str {
108 "Allows Gemini to write and execute Python code server-side."
109 }
110
111 fn is_builtin(&self) -> bool {
112 true
113 }
114
115 fn declaration(&self) -> Value {
116 json!({
117 "name": self.name(),
118 "description": self.description(),
119 "x-adk-gemini-tool": {
120 "code_execution": {}
121 }
122 })
123 }
124
125 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
126 Err(adk_core::AdkError::tool("Gemini code execution is handled internally by Gemini"))
127 }
128}
129
130#[derive(Debug, Clone)]
132pub struct GeminiFileSearchTool {
133 file_search_store_names: Vec<String>,
134}
135
136impl GeminiFileSearchTool {
137 pub fn new(file_search_store_names: impl IntoIterator<Item = impl Into<String>>) -> Self {
139 Self {
140 file_search_store_names: file_search_store_names.into_iter().map(Into::into).collect(),
141 }
142 }
143}
144
145#[async_trait]
146impl Tool for GeminiFileSearchTool {
147 fn name(&self) -> &str {
148 "gemini_file_search"
149 }
150
151 fn description(&self) -> &str {
152 "Searches Gemini File Search stores for relevant documents."
153 }
154
155 fn is_builtin(&self) -> bool {
156 true
157 }
158
159 fn declaration(&self) -> Value {
160 json!({
161 "name": self.name(),
162 "description": self.description(),
163 "x-adk-gemini-tool": {
164 "file_search": {
165 "file_search_store_names": self.file_search_store_names
166 }
167 }
168 })
169 }
170
171 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
172 Err(adk_core::AdkError::tool("Gemini file search is handled internally by Gemini"))
173 }
174}
175
176impl BypassMultiToolsLimit for GeminiFileSearchTool {
196 fn bypass_name(&self) -> String {
197 self.name().to_string()
198 }
199
200 fn bypass_description(&self) -> String {
201 "Searches Gemini File Search stores for documents relevant to a query.".to_string()
202 }
203
204 fn bypass_parameters_schema(&self) -> Value {
205 json!({
206 "type": "object",
207 "properties": {
208 "query": {
209 "type": "string",
210 "description": "The query used to search the File Search stores."
211 }
212 },
213 "required": ["query"]
214 })
215 }
216
217 fn bypass_query_field(&self) -> String {
218 "query".to_string()
219 }
220}
221
222#[derive(Debug, Clone, Copy, PartialEq, Eq)]
224pub enum GeminiComputerEnvironment {
225 Browser,
227}
228
229impl GeminiComputerEnvironment {
230 fn as_wire(self) -> &'static str {
231 match self {
232 Self::Browser => "ENVIRONMENT_BROWSER",
233 }
234 }
235}
236
237#[derive(Debug, Clone)]
239pub struct GeminiComputerUseTool {
240 environment: GeminiComputerEnvironment,
241 excluded_predefined_functions: Vec<String>,
242}
243
244impl Default for GeminiComputerUseTool {
245 fn default() -> Self {
246 Self {
247 environment: GeminiComputerEnvironment::Browser,
248 excluded_predefined_functions: Vec::new(),
249 }
250 }
251}
252
253impl GeminiComputerUseTool {
254 pub fn new(environment: GeminiComputerEnvironment) -> Self {
256 Self { environment, ..Default::default() }
257 }
258
259 pub fn with_excluded_functions(
261 mut self,
262 excluded_predefined_functions: impl IntoIterator<Item = impl Into<String>>,
263 ) -> Self {
264 self.excluded_predefined_functions =
265 excluded_predefined_functions.into_iter().map(Into::into).collect();
266 self
267 }
268}
269
270#[async_trait]
271impl Tool for GeminiComputerUseTool {
272 fn name(&self) -> &str {
273 "gemini_computer_use"
274 }
275
276 fn description(&self) -> &str {
277 "Enables Gemini computer use, which emits predefined UI action function calls."
278 }
279
280 fn is_builtin(&self) -> bool {
281 true
282 }
283
284 fn declaration(&self) -> Value {
285 json!({
286 "name": self.name(),
287 "description": self.description(),
288 "x-adk-gemini-tool": {
289 "computer_use": {
290 "environment": self.environment.as_wire(),
291 "excluded_predefined_functions": (!self.excluded_predefined_functions.is_empty())
292 .then_some(self.excluded_predefined_functions.clone()),
293 }
294 }
295 })
296 }
297
298 async fn execute(&self, _ctx: Arc<dyn ToolContext>, _args: Value) -> Result<Value> {
299 Err(adk_core::AdkError::tool("Gemini computer use actions must be executed client-side"))
300 }
301}