(
&self,
_id: &str,
params: Value,
cancel: CancellationToken,
_on_update: Option<AgentToolUpdate>,
)
| 62 | } |
| 63 | |
| 64 | async fn execute( |
| 65 | &self, |
| 66 | _id: &str, |
| 67 | params: Value, |
| 68 | cancel: CancellationToken, |
| 69 | _on_update: Option<AgentToolUpdate>, |
| 70 | ) -> Result<AgentToolResult, AgentToolError> { |
| 71 | let command = params |
| 72 | .get("command") |
| 73 | .and_then(|v| v.as_str()) |
| 74 | .ok_or_else(|| AgentToolError::from("missing `command`"))?; |
| 75 | let timeout_secs = params.get("timeout").and_then(|v| v.as_u64()); |
| 76 | |
| 77 | let outcome = run_with_kill_on_timeout_or_cancel(command, timeout_secs, &cancel).await?; |
| 78 | |
| 79 | let exit = outcome.rendered_exit(); |
| 80 | let (stdout_trim, st) = |
| 81 | truncate_tail(&outcome.stdout, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES); |
| 82 | let mut stderr_full = outcome.stderr; |
| 83 | if let Some(suffix) = &outcome.stderr_suffix { |
| 84 | if !stderr_full.is_empty() && !stderr_full.ends_with('\n') { |
| 85 | stderr_full.push('\n'); |
| 86 | } |
| 87 | stderr_full.push_str(suffix); |
| 88 | } |
| 89 | let (stderr_trim, _) = truncate_tail(&stderr_full, DEFAULT_MAX_LINES, DEFAULT_MAX_BYTES); |
| 90 | let mut text = format!("$ {command}\n"); |
| 91 | if let Some(note) = st.note() { |
| 92 | text.push_str(¬e); |
| 93 | text.push('\n'); |
| 94 | } |
| 95 | if !stdout_trim.is_empty() { |
| 96 | text.push_str(&stdout_trim); |
| 97 | if !stdout_trim.ends_with('\n') { |
| 98 | text.push('\n'); |
| 99 | } |
| 100 | } |
| 101 | if !stderr_trim.is_empty() { |
| 102 | text.push_str("[stderr]\n"); |
| 103 | text.push_str(&stderr_trim); |
| 104 | if !stderr_trim.ends_with('\n') { |
| 105 | text.push('\n'); |
| 106 | } |
| 107 | } |
| 108 | text.push_str(&format!("[exit {exit}]")); |
| 109 | |
| 110 | let is_error = exit != 0; |
| 111 | Ok(AgentToolResult { |
| 112 | content: vec![UserContentBlock::text(text)], |
| 113 | details: json!({ |
| 114 | "command": command, |
| 115 | "exitCode": exit, |
| 116 | "isError": is_error, |
| 117 | }), |
| 118 | terminate: None, |
| 119 | }) |
| 120 | } |
| 121 | } |
no test coverage detected