(request: ToolExecutionRequest)
| 332 | |
| 333 | #[tauri::command] |
| 334 | pub async fn execute_tool(request: ToolExecutionRequest) -> Result<ToolExecutionResponse, String> { |
| 335 | let start_time = std::time::Instant::now(); |
| 336 | |
| 337 | let tools = get_all_tools().await; |
| 338 | |
| 339 | for tool in tools { |
| 340 | if tool.name() == request.tool_name { |
| 341 | ensure_workspace_requirement( |
| 342 | &request.tool_name, |
| 343 | &request.input, |
| 344 | request.workspace_path.as_deref(), |
| 345 | )?; |
| 346 | |
| 347 | let context = build_tool_context(request.workspace_path.as_deref()).await; |
| 348 | |
| 349 | let validation_result = tool.validate_input(&request.input, Some(&context)).await; |
| 350 | if !validation_result.result { |
| 351 | return Ok(ToolExecutionResponse { |
| 352 | tool_name: request.tool_name, |
| 353 | success: false, |
| 354 | result: None, |
| 355 | error: None, |
| 356 | validation_error: validation_result.message, |
| 357 | duration_ms: elapsed_ms_u64(start_time), |
| 358 | }); |
| 359 | } |
| 360 | |
| 361 | match tool.call(&request.input, &context).await { |
| 362 | Ok(results) => { |
| 363 | let combined_result = if results.len() == 1 { |
| 364 | match &results[0] { |
| 365 | bitfun_core::agentic::tools::framework::ToolResult::Result { |
| 366 | data, |
| 367 | .. |
| 368 | } => Some(data.clone()), |
| 369 | bitfun_core::agentic::tools::framework::ToolResult::Progress { |
| 370 | content, |
| 371 | .. |
| 372 | } => Some(content.clone()), |
| 373 | bitfun_core::agentic::tools::framework::ToolResult::StreamChunk { |
| 374 | data, |
| 375 | .. |
| 376 | } => Some(data.clone()), |
| 377 | } |
| 378 | } else { |
| 379 | Some(serde_json::json!({ |
| 380 | "results": results.iter().map(|r| match r { |
| 381 | bitfun_core::agentic::tools::framework::ToolResult::Result { data, .. } => { |
| 382 | data.clone() |
| 383 | } |
| 384 | bitfun_core::agentic::tools::framework::ToolResult::Progress { content, .. } => content.clone(), |
| 385 | bitfun_core::agentic::tools::framework::ToolResult::StreamChunk { data, .. } => data.clone(), |
| 386 | }).collect::<Vec<_>>() |
| 387 | })) |
| 388 | }; |
| 389 | |
| 390 | return Ok(ToolExecutionResponse { |
| 391 | tool_name: request.tool_name, |
nothing calls this directly
no test coverage detected