(
input: BashCommandInput,
sandbox_status: SandboxStatus,
cwd: std::path::PathBuf,
)
| 100 | } |
| 101 | |
| 102 | async fn execute_bash_async( |
| 103 | input: BashCommandInput, |
| 104 | sandbox_status: SandboxStatus, |
| 105 | cwd: std::path::PathBuf, |
| 106 | ) -> io::Result<BashCommandOutput> { |
| 107 | let mut command = prepare_tokio_command(&input.command, &cwd, &sandbox_status, true); |
| 108 | |
| 109 | let output_result = if let Some(timeout_ms) = input.timeout { |
| 110 | match timeout(Duration::from_millis(timeout_ms), command.output()).await { |
| 111 | Ok(result) => (result?, false), |
| 112 | Err(_) => { |
| 113 | return Ok(BashCommandOutput { |
| 114 | stdout: String::new(), |
| 115 | stderr: format!("Command exceeded timeout of {timeout_ms} ms"), |
| 116 | raw_output_path: None, |
| 117 | interrupted: true, |
| 118 | is_image: None, |
| 119 | background_task_id: None, |
| 120 | backgrounded_by_user: None, |
| 121 | assistant_auto_backgrounded: None, |
| 122 | dangerously_disable_sandbox: input.dangerously_disable_sandbox, |
| 123 | return_code_interpretation: Some(String::from("timeout")), |
| 124 | no_output_expected: Some(true), |
| 125 | structured_content: None, |
| 126 | persisted_output_path: None, |
| 127 | persisted_output_size: None, |
| 128 | sandbox_status: Some(sandbox_status), |
| 129 | }); |
| 130 | } |
| 131 | } |
| 132 | } else { |
| 133 | (command.output().await?, false) |
| 134 | }; |
| 135 | |
| 136 | let (output, interrupted) = output_result; |
| 137 | let stdout = String::from_utf8_lossy(&output.stdout).into_owned(); |
| 138 | let stderr = String::from_utf8_lossy(&output.stderr).into_owned(); |
| 139 | let no_output_expected = Some(stdout.trim().is_empty() && stderr.trim().is_empty()); |
| 140 | let return_code_interpretation = output.status.code().and_then(|code| { |
| 141 | if code == 0 { |
| 142 | None |
| 143 | } else { |
| 144 | Some(format!("exit_code:{code}")) |
| 145 | } |
| 146 | }); |
| 147 | |
| 148 | Ok(BashCommandOutput { |
| 149 | stdout, |
| 150 | stderr, |
| 151 | raw_output_path: None, |
| 152 | interrupted, |
| 153 | is_image: None, |
| 154 | background_task_id: None, |
| 155 | backgrounded_by_user: None, |
| 156 | assistant_auto_backgrounded: None, |
| 157 | dangerously_disable_sandbox: input.dangerously_disable_sandbox, |
| 158 | return_code_interpretation, |
| 159 | no_output_expected, |
no test coverage detected