watsonx_rs/orchestrate/
tool.rs1use crate::error::{Error, Result};
4use super::types::{Tool, ToolExecutionRequest, ToolExecutionResult, ToolUpdateRequest, ToolTestRequest, ToolTestResult, ToolExecutionHistory, ToolVersion};
5use super::OrchestrateClient;
6
7impl OrchestrateClient {
8 pub async fn list_tools(&self) -> Result<Vec<Tool>> {
10 let api_key = self.access_token.as_ref().ok_or_else(|| {
11 Error::Authentication("Not authenticated. Set access token (API key) first.".to_string())
12 })?;
13
14 let base_url = self.config.get_base_url();
15 let url = format!("{}/tools", base_url);
16
17 let response = self
18 .client
19 .get(&url)
20 .header("Authorization", format!("Bearer {}", api_key))
21 .header("Content-Type", "application/json")
22 .send()
23 .await
24 .map_err(|e| Error::Network(e.to_string()))?;
25
26 if !response.status().is_success() {
27 let status = response.status();
28 let error_text = response
29 .text()
30 .await
31 .unwrap_or_else(|_| "Unknown error".to_string());
32 return Err(Error::Api(format!(
33 "Failed to list tools: {} - {}",
34 status, error_text
35 )));
36 }
37
38 let text = response
39 .text()
40 .await
41 .map_err(|e| Error::Serialization(e.to_string()))?;
42
43 if let Ok(tools) = serde_json::from_str::<Vec<Tool>>(&text) {
44 return Ok(tools);
45 }
46
47 if let Ok(obj) = serde_json::from_str::<serde_json::Value>(&text) {
48 if let Some(tools_array) = obj.get("tools").and_then(|t| t.as_array()) {
49 let tools: Result<Vec<Tool>> = tools_array
50 .iter()
51 .map(|tool| {
52 serde_json::from_value::<Tool>(tool.clone())
53 .map_err(|e| Error::Serialization(e.to_string()))
54 })
55 .collect();
56 return tools;
57 }
58 }
59
60 Ok(Vec::new())
61 }
62
63 pub async fn get_tool(&self, tool_id: &str) -> Result<Tool> {
65 let api_key = self.access_token.as_ref().ok_or_else(|| {
66 Error::Authentication("Not authenticated. Set access token (API key) first.".to_string())
67 })?;
68
69 let base_url = self.config.get_base_url();
70 let url = format!("{}/tools/{}", base_url, tool_id);
71
72 let response = self
73 .client
74 .get(&url)
75 .header("Authorization", format!("Bearer {}", api_key))
76 .header("Content-Type", "application/json")
77 .send()
78 .await
79 .map_err(|e| Error::Network(e.to_string()))?;
80
81 if !response.status().is_success() {
82 let status = response.status();
83 let error_text = response
84 .text()
85 .await
86 .unwrap_or_else(|_| "Unknown error".to_string());
87 return Err(Error::Api(format!(
88 "Failed to get tool {}: {} - {}",
89 tool_id, status, error_text
90 )));
91 }
92
93 let tool: Tool = response
94 .json()
95 .await
96 .map_err(|e| Error::Serialization(e.to_string()))?;
97
98 Ok(tool)
99 }
100
101 pub async fn execute_tool(&self, request: ToolExecutionRequest) -> Result<ToolExecutionResult> {
103 let api_key = self.access_token.as_ref().ok_or_else(|| {
104 Error::Authentication("Not authenticated. Set access token (API key) first.".to_string())
105 })?;
106
107 let base_url = self.config.get_base_url();
108 let url = format!("{}/tools/{}/execute", base_url, request.tool_id);
109
110 let response = self
111 .client
112 .post(&url)
113 .header("Authorization", format!("Bearer {}", api_key))
114 .header("Content-Type", "application/json")
115 .json(&request)
116 .send()
117 .await
118 .map_err(|e| Error::Network(e.to_string()))?;
119
120 if !response.status().is_success() {
121 let status = response.status();
122 let error_text = response
123 .text()
124 .await
125 .unwrap_or_else(|_| "Unknown error".to_string());
126 return Err(Error::Api(format!(
127 "Failed to execute tool: {} - {}",
128 status, error_text
129 )));
130 }
131
132 let result: ToolExecutionResult = response
133 .json()
134 .await
135 .map_err(|e| Error::Serialization(e.to_string()))?;
136
137 Ok(result)
138 }
139
140 pub async fn update_tool(&self, tool_id: &str, request: ToolUpdateRequest) -> Result<Tool> {
142 let token = self.access_token.as_ref().ok_or_else(|| {
143 Error::Authentication("Not authenticated. Set access token (Bearer token) first.".to_string())
144 })?;
145
146 let base_url = self.config.get_base_url();
147 let url = format!("{}/orchestrate/tools/{}", base_url, tool_id);
148
149 let response = self
150 .client
151 .patch(&url)
152 .header("Authorization", format!("Bearer {}", token))
153 .header("Content-Type", "application/json")
154 .header("X-Instance-ID", &self.config.instance_id)
155 .json(&request)
156 .send()
157 .await
158 .map_err(|e| Error::Network(e.to_string()))?;
159
160 if !response.status().is_success() {
161 let status = response.status();
162 let error_text = response
163 .text()
164 .await
165 .unwrap_or_else(|_| "Unknown error".to_string());
166 return Err(Error::Api(format!(
167 "Failed to update tool: {} - {}",
168 status, error_text
169 )));
170 }
171
172 let tool: Tool = response
173 .json()
174 .await
175 .map_err(|e| Error::Serialization(e.to_string()))?;
176
177 Ok(tool)
178 }
179
180 pub async fn delete_tool(&self, tool_id: &str) -> Result<()> {
182 let token = self.access_token.as_ref().ok_or_else(|| {
183 Error::Authentication("Not authenticated. Set access token (Bearer token) first.".to_string())
184 })?;
185
186 let base_url = self.config.get_base_url();
187 let url = format!("{}/orchestrate/tools/{}", base_url, tool_id);
188
189 let response = self
190 .client
191 .delete(&url)
192 .header("Authorization", format!("Bearer {}", token))
193 .header("X-Instance-ID", &self.config.instance_id)
194 .send()
195 .await
196 .map_err(|e| Error::Network(e.to_string()))?;
197
198 if !response.status().is_success() {
199 let status = response.status();
200 let error_text = response
201 .text()
202 .await
203 .unwrap_or_else(|_| "Unknown error".to_string());
204 return Err(Error::Api(format!(
205 "Failed to delete tool: {} - {}",
206 status, error_text
207 )));
208 }
209
210 Ok(())
211 }
212
213 pub async fn test_tool(&self, request: ToolTestRequest) -> Result<ToolTestResult> {
215 let token = self.access_token.as_ref().ok_or_else(|| {
216 Error::Authentication("Not authenticated. Set access token (Bearer token) first.".to_string())
217 })?;
218
219 let base_url = self.config.get_base_url();
220 let url = format!("{}/orchestrate/tools/{}/test", base_url, request.tool_id);
221
222 let response = self
223 .client
224 .post(&url)
225 .header("Authorization", format!("Bearer {}", token))
226 .header("Content-Type", "application/json")
227 .header("X-Instance-ID", &self.config.instance_id)
228 .json(&request)
229 .send()
230 .await
231 .map_err(|e| Error::Network(e.to_string()))?;
232
233 if !response.status().is_success() {
234 let status = response.status();
235 let error_text = response
236 .text()
237 .await
238 .unwrap_or_else(|_| "Unknown error".to_string());
239 return Err(Error::Api(format!(
240 "Failed to test tool: {} - {}",
241 status, error_text
242 )));
243 }
244
245 let result: ToolTestResult = response
246 .json()
247 .await
248 .map_err(|e| Error::Serialization(e.to_string()))?;
249
250 Ok(result)
251 }
252
253 pub async fn get_tool_execution_history(&self, tool_id: &str, limit: Option<u32>) -> Result<Vec<ToolExecutionHistory>> {
255 let token = self.access_token.as_ref().ok_or_else(|| {
256 Error::Authentication("Not authenticated. Set access token (Bearer token) first.".to_string())
257 })?;
258
259 let base_url = self.config.get_base_url();
260 let mut url = format!("{}/orchestrate/tools/{}/execution-history", base_url, tool_id);
261
262 if let Some(l) = limit {
263 url.push_str(&format!("?limit={}", l));
264 }
265
266 let response = self
267 .client
268 .get(&url)
269 .header("Authorization", format!("Bearer {}", token))
270 .header("Content-Type", "application/json")
271 .header("X-Instance-ID", &self.config.instance_id)
272 .send()
273 .await
274 .map_err(|e| Error::Network(e.to_string()))?;
275
276 if !response.status().is_success() {
277 let status = response.status();
278 let error_text = response
279 .text()
280 .await
281 .unwrap_or_else(|_| "Unknown error".to_string());
282 return Err(Error::Api(format!(
283 "Failed to get tool execution history: {} - {}",
284 status, error_text
285 )));
286 }
287
288 let text = response
289 .text()
290 .await
291 .map_err(|e| Error::Network(e.to_string()))?;
292
293 if let Ok(history) = serde_json::from_str::<Vec<ToolExecutionHistory>>(&text) {
294 return Ok(history);
295 }
296
297 if let Ok(obj) = serde_json::from_str::<serde_json::Value>(&text) {
298 if let Some(history_array) = obj.get("history").and_then(|h| h.as_array()) {
299 let history: Result<Vec<ToolExecutionHistory>> = history_array
300 .iter()
301 .map(|item| {
302 serde_json::from_value::<ToolExecutionHistory>(item.clone())
303 .map_err(|e| Error::Serialization(e.to_string()))
304 })
305 .collect();
306 return history;
307 }
308 }
309
310 Ok(Vec::new())
311 }
312
313 pub async fn get_tool_versions(&self, tool_id: &str) -> Result<Vec<ToolVersion>> {
315 let token = self.access_token.as_ref().ok_or_else(|| {
316 Error::Authentication("Not authenticated. Set access token (Bearer token) first.".to_string())
317 })?;
318
319 let base_url = self.config.get_base_url();
320 let url = format!("{}/orchestrate/tools/{}/versions", base_url, tool_id);
321
322 let response = self
323 .client
324 .get(&url)
325 .header("Authorization", format!("Bearer {}", token))
326 .header("Content-Type", "application/json")
327 .header("X-Instance-ID", &self.config.instance_id)
328 .send()
329 .await
330 .map_err(|e| Error::Network(e.to_string()))?;
331
332 if !response.status().is_success() {
333 let status = response.status();
334 let error_text = response
335 .text()
336 .await
337 .unwrap_or_else(|_| "Unknown error".to_string());
338 return Err(Error::Api(format!(
339 "Failed to get tool versions: {} - {}",
340 status, error_text
341 )));
342 }
343
344 let text = response
345 .text()
346 .await
347 .map_err(|e| Error::Network(e.to_string()))?;
348
349 if let Ok(versions) = serde_json::from_str::<Vec<ToolVersion>>(&text) {
350 return Ok(versions);
351 }
352
353 if let Ok(obj) = serde_json::from_str::<serde_json::Value>(&text) {
354 if let Some(versions_array) = obj.get("versions").and_then(|v| v.as_array()) {
355 let versions: Result<Vec<ToolVersion>> = versions_array
356 .iter()
357 .map(|item| {
358 serde_json::from_value::<ToolVersion>(item.clone())
359 .map_err(|e| Error::Serialization(e.to_string()))
360 })
361 .collect();
362 return versions;
363 }
364 }
365
366 Ok(Vec::new())
367 }
368}