|
| 1 | +use std::future::Future; |
1 | 2 | use std::path::PathBuf; |
2 | 3 | use std::sync::Arc; |
3 | 4 | use std::sync::RwLock; |
@@ -74,13 +75,18 @@ impl Executor { |
74 | 75 | /// Runs a prepared execution request end-to-end: prepares parameters, decides on |
75 | 76 | /// sandbox placement (prompting the user when necessary), launches the command, |
76 | 77 | /// and lets the backend post-process the final output. |
77 | | - pub(crate) async fn run( |
| 78 | + pub(crate) async fn run<F, Fut>( |
78 | 79 | &self, |
79 | 80 | mut request: ExecutionRequest, |
80 | 81 | session: &Session, |
81 | 82 | approval_policy: AskForApproval, |
82 | 83 | context: &ExecCommandContext, |
83 | | - ) -> Result<ExecToolCallOutput, ExecError> { |
| 84 | + on_exec_begin: F, |
| 85 | + ) -> Result<ExecToolCallOutput, ExecError> |
| 86 | + where |
| 87 | + F: FnOnce() -> Fut, |
| 88 | + Fut: Future<Output = ()>, |
| 89 | + { |
84 | 90 | if matches!(request.mode, ExecutionMode::Shell) { |
85 | 91 | request.params = |
86 | 92 | maybe_translate_shell_command(request.params, session, request.use_shell_profile); |
@@ -119,7 +125,7 @@ impl Executor { |
119 | 125 | if sandbox_decision.record_session_approval { |
120 | 126 | self.approval_cache.insert(request.approval_command.clone()); |
121 | 127 | } |
122 | | - |
| 128 | + on_exec_begin().await; |
123 | 129 | // Step 4: Launch the command within the chosen sandbox. |
124 | 130 | let first_attempt = self |
125 | 131 | .spawn( |
@@ -210,7 +216,7 @@ impl Executor { |
210 | 216 | Ok(retry_output) |
211 | 217 | } |
212 | 218 | ReviewDecision::Denied | ReviewDecision::Abort => { |
213 | | - Err(ExecError::rejection("exec command rejected by user")) |
| 219 | + Err(ExecError::denied("exec command rejected by user")) |
214 | 220 | } |
215 | 221 | } |
216 | 222 | } |
@@ -301,7 +307,8 @@ pub(crate) fn normalize_exec_result( |
301 | 307 | } |
302 | 308 | Err(err) => { |
303 | 309 | let message = match err { |
304 | | - ExecError::Function(FunctionCallError::RespondToModel(msg)) => msg.clone(), |
| 310 | + ExecError::Function(FunctionCallError::RespondToModel(msg)) |
| 311 | + | ExecError::Function(FunctionCallError::Denied(msg)) => msg.clone(), |
305 | 312 | ExecError::Codex(e) => get_error_message_ui(e), |
306 | 313 | err => err.to_string(), |
307 | 314 | }; |
|
0 commit comments