Refactor user shell task to call execute_exec_env

This commit is contained in:
zhao-oai
2025-11-03 09:54:30 -08:00
parent b81cb7ceb3
commit 0efd420071

View File

@@ -1,28 +1,28 @@
use std::sync::Arc;
use async_trait::async_trait;
use codex_protocol::models::ShellToolCallParams;
use codex_protocol::user_input::UserInput;
use tokio::sync::Mutex;
use tokio_util::sync::CancellationToken;
use tracing::error;
use uuid::Uuid;
use crate::codex::TurnContext;
use crate::exec::SandboxType;
use crate::exec::StdoutStream;
use crate::exec::execute_exec_env;
use crate::exec_env::create_env;
use crate::protocol::EventMsg;
use crate::protocol::TaskStartedEvent;
use crate::sandboxing::SandboxManager;
use crate::state::TaskKind;
use crate::tools::context::ToolPayload;
use crate::tools::parallel::ToolCallRuntime;
use crate::tools::router::ToolCall;
use crate::tools::router::ToolRouter;
use crate::turn_diff_tracker::TurnDiffTracker;
use crate::tools::events::ToolEmitter;
use crate::tools::events::ToolEventCtx;
use crate::tools::runtimes::build_command_spec;
use crate::tools::sandboxing::ToolError;
use super::SessionTask;
use super::SessionTaskContext;
const USER_SHELL_TOOL_NAME: &str = "local_shell";
#[derive(Clone)]
pub(crate) struct UserShellCommandTask {
command: String,
@@ -78,37 +78,75 @@ impl SessionTask for UserShellCommandTask {
}
};
let params = ShellToolCallParams {
command: shell_invocation,
workdir: None,
timeout_ms: None,
with_escalated_permissions: None,
justification: None,
if cancellation_token.is_cancelled() {
return None;
}
let call_id = Uuid::new_v4().to_string();
let emitter = ToolEmitter::shell(shell_invocation.clone(), turn_context.cwd.clone(), true);
let event_ctx = ToolEventCtx::new(session.as_ref(), turn_context.as_ref(), &call_id, None);
emitter.begin(event_ctx).await;
let env = create_env(&turn_context.shell_environment_policy);
let spec = match build_command_spec(
&shell_invocation,
&turn_context.cwd,
&env,
None,
None,
None,
) {
Ok(spec) => spec,
Err(err) => {
let event_ctx =
ToolEventCtx::new(session.as_ref(), turn_context.as_ref(), &call_id, None);
if let Err(finish_err) = emitter.finish(event_ctx, Err(err)).await {
error!(?finish_err, "user shell command failed: {finish_err:?}");
}
return None;
}
};
let tool_call = ToolCall {
tool_name: USER_SHELL_TOOL_NAME.to_string(),
call_id: Uuid::new_v4().to_string(),
payload: ToolPayload::LocalShell {
params,
is_user_shell_command: true,
},
let manager = SandboxManager::new();
let exec_env = match manager.transform(
&spec,
&turn_context.sandbox_policy,
SandboxType::None,
&turn_context.cwd,
turn_context.codex_linux_sandbox_exe.as_ref(),
) {
Ok(env) => env,
Err(err) => {
let event_ctx =
ToolEventCtx::new(session.as_ref(), turn_context.as_ref(), &call_id, None);
let tool_error = ToolError::Codex(err.into());
if let Err(finish_err) = emitter.finish(event_ctx, Err(tool_error)).await {
error!(?finish_err, "user shell command failed: {finish_err:?}");
}
return None;
}
};
let router = Arc::new(ToolRouter::from_config(&turn_context.tools_config, None));
let tracker = Arc::new(Mutex::new(TurnDiffTracker::new()));
let runtime = ToolCallRuntime::new(
Arc::clone(&router),
Arc::clone(&session),
Arc::clone(&turn_context),
Arc::clone(&tracker),
);
let stdout_stream = StdoutStream {
sub_id: turn_context.sub_id.clone(),
call_id: call_id.clone(),
tx_event: session.get_tx_event(),
};
if let Err(err) = runtime
.handle_tool_call(tool_call, cancellation_token)
.await
{
error!("user shell command failed: {err:?}");
let exec_result = tokio::select! {
_ = cancellation_token.cancelled() => None,
res = execute_exec_env(exec_env, &turn_context.sandbox_policy, Some(stdout_stream)) => Some(res),
};
if let Some(result) = exec_result {
let event_ctx =
ToolEventCtx::new(session.as_ref(), turn_context.as_ref(), &call_id, None);
if let Err(err) = emitter
.finish(event_ctx, result.map_err(ToolError::Codex))
.await
{
error!(?err, "user shell command failed: {err:?}");
}
}
None
}