Address exec-server sandbox review comments

- preserve sandbox child environment variables from shared launch requests
- dispatch codex-exec-server through codex-arg0 so helper arg0 is executable
- send sandbox preference to remote servers and report the server-selected sandbox

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
starr-openai
2026-04-08 10:53:18 -07:00
parent 5824352d53
commit a69385f63f
23 changed files with 140 additions and 110 deletions

View File

@@ -1,5 +1,6 @@
use codex_app_server_protocol::JSONRPCErrorError;
use crate::ExecServerRuntimeConfig;
use crate::protocol::ExecParams;
use crate::protocol::ExecResponse;
use crate::protocol::FsCopyParams;
@@ -34,9 +35,12 @@ pub(crate) struct ExecServerHandler {
}
impl ExecServerHandler {
pub(crate) fn new(notifications: RpcNotificationSender) -> Self {
pub(crate) fn new(
notifications: RpcNotificationSender,
runtime: ExecServerRuntimeConfig,
) -> Self {
Self {
process: ProcessHandler::new(notifications),
process: ProcessHandler::new(notifications, runtime),
file_system: FileSystemHandler::default(),
}
}

View File

@@ -6,6 +6,7 @@ use pretty_assertions::assert_eq;
use tokio::sync::mpsc;
use super::ExecServerHandler;
use crate::ExecServerRuntimeConfig;
use crate::ProcessId;
use crate::protocol::ExecParams;
use crate::protocol::InitializeResponse;
@@ -36,9 +37,10 @@ fn exec_params(process_id: &str) -> ExecParams {
async fn initialized_handler() -> Arc<ExecServerHandler> {
let (outgoing_tx, _outgoing_rx) = mpsc::channel(16);
let handler = Arc::new(ExecServerHandler::new(RpcNotificationSender::new(
outgoing_tx,
)));
let handler = Arc::new(ExecServerHandler::new(
RpcNotificationSender::new(outgoing_tx),
ExecServerRuntimeConfig::detect(),
));
assert_eq!(
handler.initialize().expect("initialize"),
InitializeResponse {}

View File

@@ -1,5 +1,6 @@
use codex_app_server_protocol::JSONRPCErrorError;
use crate::ExecServerRuntimeConfig;
use crate::local_process::LocalProcess;
use crate::protocol::ExecParams;
use crate::protocol::ExecResponse;
@@ -18,9 +19,12 @@ pub(crate) struct ProcessHandler {
}
impl ProcessHandler {
pub(crate) fn new(notifications: RpcNotificationSender) -> Self {
pub(crate) fn new(
notifications: RpcNotificationSender,
runtime: ExecServerRuntimeConfig,
) -> Self {
Self {
process: LocalProcess::new(notifications),
process: LocalProcess::new_with_runtime(notifications, runtime),
}
}

View File

@@ -4,6 +4,7 @@ use tokio::sync::mpsc;
use tracing::debug;
use tracing::warn;
use crate::ExecServerRuntimeConfig;
use crate::connection::CHANNEL_CAPACITY;
use crate::connection::JsonRpcConnection;
use crate::connection::JsonRpcConnectionEvent;
@@ -15,13 +16,16 @@ use crate::rpc::method_not_found;
use crate::server::ExecServerHandler;
use crate::server::registry::build_router;
pub(crate) async fn run_connection(connection: JsonRpcConnection) {
pub(crate) async fn run_connection(
connection: JsonRpcConnection,
runtime: ExecServerRuntimeConfig,
) {
let router = Arc::new(build_router());
let (json_outgoing_tx, mut incoming_rx, connection_tasks) = connection.into_parts();
let (outgoing_tx, mut outgoing_rx) =
mpsc::channel::<RpcServerOutboundMessage>(CHANNEL_CAPACITY);
let notifications = RpcNotificationSender::new(outgoing_tx.clone());
let handler = Arc::new(ExecServerHandler::new(notifications));
let handler = Arc::new(ExecServerHandler::new(notifications, runtime));
let outbound_task = tokio::spawn(async move {
while let Some(message) = outgoing_rx.recv().await {

View File

@@ -4,6 +4,7 @@ use tokio::net::TcpListener;
use tokio_tungstenite::accept_async;
use tracing::warn;
use crate::ExecServerRuntimeConfig;
use crate::connection::JsonRpcConnection;
use crate::server::processor::run_connection;
@@ -48,13 +49,15 @@ pub(crate) fn parse_listen_url(
pub(crate) async fn run_transport(
listen_url: &str,
runtime: ExecServerRuntimeConfig,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let bind_address = parse_listen_url(listen_url)?;
run_websocket_listener(bind_address).await
run_websocket_listener(bind_address, runtime).await
}
async fn run_websocket_listener(
bind_address: SocketAddr,
runtime: ExecServerRuntimeConfig,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let listener = TcpListener::bind(bind_address).await?;
let local_addr = listener.local_addr()?;
@@ -63,13 +66,17 @@ async fn run_websocket_listener(
loop {
let (stream, peer_addr) = listener.accept().await?;
let runtime = runtime.clone();
tokio::spawn(async move {
match accept_async(stream).await {
Ok(websocket) => {
run_connection(JsonRpcConnection::from_websocket(
websocket,
format!("exec-server websocket {peer_addr}"),
))
run_connection(
JsonRpcConnection::from_websocket(
websocket,
format!("exec-server websocket {peer_addr}"),
),
runtime,
)
.await;
}
Err(err) => {