| 472 | } |
| 473 | |
| 474 | pub async fn execute_with_context( |
| 475 | &self, |
| 476 | name: &str, |
| 477 | args: &serde_json::Value, |
| 478 | ctx: &ToolContext, |
| 479 | ) -> Result<ToolResult> { |
| 480 | Self::check_workspace_boundary(name, args, ctx)?; |
| 481 | log_tool_invocation(name, args); |
| 482 | self.capture_snapshot(name, args); |
| 483 | let mut result = self.registry.execute_with_context(name, args, ctx).await; |
| 484 | if let Ok(ref mut r) = result { |
| 485 | self.attach_diff_metadata(name, args, r); |
| 486 | } |
| 487 | match &result { |
| 488 | Ok(r) => tracing::info!("Tool {} completed with exit_code={}", name, r.exit_code), |
| 489 | Err(e) => tracing::error!("Tool {} failed: {}", name, e), |
| 490 | } |
| 491 | result |
| 492 | } |
| 493 | |
| 494 | fn attach_diff_metadata(&self, name: &str, args: &serde_json::Value, result: &mut ToolResult) { |
| 495 | if !file_history::is_file_modifying_tool(name) { |