feat: add codex_linux_sandbox_exe: Option<PathBuf> field to Config (#1089)

https://github.com/openai/codex/pull/1086 is a work-in-progress to make
Linux sandboxing work more like Seatbelt where, for the command we want
to sandbox, we build up the command and then hand it, and some sandbox
configuration flags, to another command to set up the sandbox and then
run it.

In the case of Seatbelt, macOS provides this helper binary and provides
it at `/usr/bin/sandbox-exec`. For Linux, we have to build our own and
pass it through (which is what #1086 does), so this makes the new
`codex_linux_sandbox_exe` available on `Config` so that it will later be
available in `exec.rs` when we need it in #1086.
This commit is contained in:
Michael Bolin
2025-05-22 21:52:28 -07:00
committed by GitHub
parent 63deb7c369
commit d1de7bb383
10 changed files with 75 additions and 13 deletions

View File

@@ -144,7 +144,10 @@ pub(crate) fn create_tool_for_codex_tool_call_param() -> Tool {
impl CodexToolCallParam {
/// Returns the initial user prompt to start the Codex conversation and the
/// Config.
pub fn into_config(self) -> std::io::Result<(String, codex_core::config::Config)> {
pub fn into_config(
self,
codex_linux_sandbox_exe: Option<PathBuf>,
) -> std::io::Result<(String, codex_core::config::Config)> {
let Self {
prompt,
model,
@@ -167,6 +170,7 @@ impl CodexToolCallParam {
sandbox_policy,
disable_response_storage,
model_provider: None,
codex_linux_sandbox_exe,
};
let cfg = codex_core::config::Config::load_with_overrides(overrides)?;

View File

@@ -2,6 +2,7 @@
#![deny(clippy::print_stdout, clippy::print_stderr)]
use std::io::Result as IoResult;
use std::path::PathBuf;
use mcp_types::JSONRPCMessage;
use tokio::io::AsyncBufReadExt;
@@ -24,7 +25,7 @@ use crate::message_processor::MessageProcessor;
/// plenty for an interactive CLI.
const CHANNEL_CAPACITY: usize = 128;
pub async fn run_main() -> IoResult<()> {
pub async fn run_main(codex_linux_sandbox_exe: Option<PathBuf>) -> IoResult<()> {
// Install a simple subscriber so `tracing` output is visible. Users can
// control the log level with `RUST_LOG`.
tracing_subscriber::fmt()
@@ -61,7 +62,7 @@ pub async fn run_main() -> IoResult<()> {
// Task: process incoming messages.
let processor_handle = tokio::spawn({
let mut processor = MessageProcessor::new(outgoing_tx.clone());
let mut processor = MessageProcessor::new(outgoing_tx.clone(), codex_linux_sandbox_exe);
async move {
while let Some(msg) = incoming_rx.recv().await {
match msg {

View File

@@ -1,7 +1,15 @@
use std::path::PathBuf;
use codex_mcp_server::run_main;
#[tokio::main]
async fn main() -> std::io::Result<()> {
run_main().await?;
let codex_linux_sandbox_exe: Option<PathBuf> = if cfg!(target_os = "linux") {
std::env::current_exe().ok()
} else {
None
};
run_main(codex_linux_sandbox_exe).await?;
Ok(())
}

View File

@@ -1,3 +1,5 @@
use std::path::PathBuf;
use crate::codex_tool_config::CodexToolCallParam;
use crate::codex_tool_config::create_tool_for_codex_tool_call_param;
@@ -28,15 +30,20 @@ use tokio::task;
pub(crate) struct MessageProcessor {
outgoing: mpsc::Sender<JSONRPCMessage>,
initialized: bool,
codex_linux_sandbox_exe: Option<PathBuf>,
}
impl MessageProcessor {
/// Create a new `MessageProcessor`, retaining a handle to the outgoing
/// `Sender` so handlers can enqueue messages to be written to stdout.
pub(crate) fn new(outgoing: mpsc::Sender<JSONRPCMessage>) -> Self {
pub(crate) fn new(
outgoing: mpsc::Sender<JSONRPCMessage>,
codex_linux_sandbox_exe: Option<PathBuf>,
) -> Self {
Self {
outgoing,
initialized: false,
codex_linux_sandbox_exe,
}
}
@@ -339,7 +346,7 @@ impl MessageProcessor {
let (initial_prompt, config): (String, CodexConfig) = match arguments {
Some(json_val) => match serde_json::from_value::<CodexToolCallParam>(json_val) {
Ok(tool_cfg) => match tool_cfg.into_config() {
Ok(tool_cfg) => match tool_cfg.into_config(self.codex_linux_sandbox_exe.clone()) {
Ok(cfg) => cfg,
Err(e) => {
let result = CallToolResult {