mirror of
https://github.com/openai/codex.git
synced 2026-11-13 22:47:20 +00:00
Route local-only app-server gating through processors (#23551)
## Summary - move local-only app-server gating out of `MessageProcessor` - let `fs/*`, `command/exec`, and `process/spawn` resolve local availability inside their owning processors - keep `fs/*` mounted for the future environment-param path while preserving current no-local error behavior ## Validation - not run locally per Codex repo guidance
This commit is contained in:
1 parent
954a9c8579
commit
1509ae6d8d
4 files changed
+73
-64
No files matched your search
@@ -6,6 +6,7 @@ pub(crate) struct CommandExecRequestProcessor {
|
||||
config: Arc<Config>,
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
config_manager: ConfigManager,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
command_exec_manager: CommandExecManager,
|
||||
}
|
||||
|
||||
@@ -15,12 +16,14 @@ impl CommandExecRequestProcessor {
|
||||
config: Arc<Config>,
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
config_manager: ConfigManager,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
) -> Self {
|
||||
Self {
|
||||
arg0_paths,
|
||||
config,
|
||||
outgoing,
|
||||
config_manager,
|
||||
environment_manager,
|
||||
command_exec_manager: CommandExecManager::default(),
|
||||
}
|
||||
}
|
||||
@@ -30,6 +33,7 @@ impl CommandExecRequestProcessor {
|
||||
request_id: &ConnectionRequestId,
|
||||
params: CommandExecParams,
|
||||
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
|
||||
self.require_local_environment()?;
|
||||
self.exec_one_off_command(request_id, params)
|
||||
.await
|
||||
.map(|()| None)
|
||||
@@ -74,6 +78,14 @@ impl CommandExecRequestProcessor {
|
||||
.await;
|
||||
}
|
||||
|
||||
fn require_local_environment(&self) -> Result<(), JSONRPCErrorError> {
|
||||
self.environment_manager
|
||||
.try_local_environment()
|
||||
.is_some()
|
||||
.then_some(())
|
||||
.ok_or_else(|| internal_error("local environment is not configured"))
|
||||
}
|
||||
|
||||
async fn exec_one_off_command(
|
||||
&self,
|
||||
request_id: &ConnectionRequestId,
|
||||
|
||||
@@ -26,6 +26,7 @@ use codex_app_server_protocol::FsWriteFileResponse;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_exec_server::CopyOptions;
|
||||
use codex_exec_server::CreateDirectoryOptions;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_exec_server::ExecutorFileSystem;
|
||||
use codex_exec_server::RemoveOptions;
|
||||
use std::io;
|
||||
@@ -33,21 +34,28 @@ use std::sync::Arc;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct FsRequestProcessor {
|
||||
file_system: Arc<dyn ExecutorFileSystem>,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
fs_watch_manager: FsWatchManager,
|
||||
}
|
||||
|
||||
impl FsRequestProcessor {
|
||||
pub(crate) fn new(
|
||||
file_system: Arc<dyn ExecutorFileSystem>,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
fs_watch_manager: FsWatchManager,
|
||||
) -> Self {
|
||||
Self {
|
||||
file_system,
|
||||
environment_manager,
|
||||
fs_watch_manager,
|
||||
}
|
||||
}
|
||||
|
||||
fn file_system(&self) -> Result<Arc<dyn ExecutorFileSystem>, JSONRPCErrorError> {
|
||||
self.environment_manager
|
||||
.try_local_environment()
|
||||
.map(|environment| environment.get_filesystem())
|
||||
.ok_or_else(|| internal_error("local filesystem is not configured"))
|
||||
}
|
||||
|
||||
pub(crate) async fn connection_closed(&self, connection_id: ConnectionId) {
|
||||
self.fs_watch_manager.connection_closed(connection_id).await;
|
||||
}
|
||||
@@ -57,7 +65,7 @@ impl FsRequestProcessor {
|
||||
params: FsReadFileParams,
|
||||
) -> Result<FsReadFileResponse, JSONRPCErrorError> {
|
||||
let bytes = self
|
||||
.file_system
|
||||
.file_system()?
|
||||
.read_file(¶ms.path, /*sandbox*/ None)
|
||||
.await
|
||||
.map_err(map_fs_error)?;
|
||||
@@ -75,7 +83,7 @@ impl FsRequestProcessor {
|
||||
"fs/writeFile requires valid base64 dataBase64: {err}"
|
||||
))
|
||||
})?;
|
||||
self.file_system
|
||||
self.file_system()?
|
||||
.write_file(¶ms.path, bytes, /*sandbox*/ None)
|
||||
.await
|
||||
.map_err(map_fs_error)?;
|
||||
@@ -86,7 +94,7 @@ impl FsRequestProcessor {
|
||||
&self,
|
||||
params: FsCreateDirectoryParams,
|
||||
) -> Result<FsCreateDirectoryResponse, JSONRPCErrorError> {
|
||||
self.file_system
|
||||
self.file_system()?
|
||||
.create_directory(
|
||||
¶ms.path,
|
||||
CreateDirectoryOptions {
|
||||
@@ -104,7 +112,7 @@ impl FsRequestProcessor {
|
||||
params: FsGetMetadataParams,
|
||||
) -> Result<FsGetMetadataResponse, JSONRPCErrorError> {
|
||||
let metadata = self
|
||||
.file_system
|
||||
.file_system()?
|
||||
.get_metadata(¶ms.path, /*sandbox*/ None)
|
||||
.await
|
||||
.map_err(map_fs_error)?;
|
||||
@@ -122,7 +130,7 @@ impl FsRequestProcessor {
|
||||
params: FsReadDirectoryParams,
|
||||
) -> Result<FsReadDirectoryResponse, JSONRPCErrorError> {
|
||||
let entries = self
|
||||
.file_system
|
||||
.file_system()?
|
||||
.read_directory(¶ms.path, /*sandbox*/ None)
|
||||
.await
|
||||
.map_err(map_fs_error)?;
|
||||
@@ -142,7 +150,7 @@ impl FsRequestProcessor {
|
||||
&self,
|
||||
params: FsRemoveParams,
|
||||
) -> Result<FsRemoveResponse, JSONRPCErrorError> {
|
||||
self.file_system
|
||||
self.file_system()?
|
||||
.remove(
|
||||
¶ms.path,
|
||||
RemoveOptions {
|
||||
@@ -160,7 +168,7 @@ impl FsRequestProcessor {
|
||||
&self,
|
||||
params: FsCopyParams,
|
||||
) -> Result<FsCopyResponse, JSONRPCErrorError> {
|
||||
self.file_system
|
||||
self.file_system()?
|
||||
.copy(
|
||||
¶ms.source_path,
|
||||
¶ms.destination_path,
|
||||
@@ -179,6 +187,7 @@ impl FsRequestProcessor {
|
||||
connection_id: ConnectionId,
|
||||
params: FsWatchParams,
|
||||
) -> Result<FsWatchResponse, JSONRPCErrorError> {
|
||||
self.file_system()?;
|
||||
self.fs_watch_manager.watch(connection_id, params).await
|
||||
}
|
||||
|
||||
@@ -187,6 +196,7 @@ impl FsRequestProcessor {
|
||||
connection_id: ConnectionId,
|
||||
params: FsUnwatchParams,
|
||||
) -> Result<FsUnwatchResponse, JSONRPCErrorError> {
|
||||
self.file_system()?;
|
||||
self.fs_watch_manager.unwatch(connection_id, params).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ use codex_app_server_protocol::ServerNotification;
|
||||
use codex_core::exec::ExecExpiration;
|
||||
use codex_core::exec::ExecExpirationOutcome;
|
||||
use codex_core::exec::IO_DRAIN_TIMEOUT_MS;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_protocol::exec_output::bytes_to_string_smart;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use codex_utils_pty::DEFAULT_OUTPUT_BYTES_CAP;
|
||||
@@ -48,13 +49,18 @@ const OUTPUT_CHUNK_SIZE_HINT: usize = 64 * 1024;
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ProcessExecRequestProcessor {
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
process_exec_manager: ProcessExecManager,
|
||||
}
|
||||
|
||||
impl ProcessExecRequestProcessor {
|
||||
pub(crate) fn new(outgoing: Arc<OutgoingMessageSender>) -> Self {
|
||||
pub(crate) fn new(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
environment_manager: Arc<EnvironmentManager>,
|
||||
) -> Self {
|
||||
Self {
|
||||
outgoing,
|
||||
environment_manager,
|
||||
process_exec_manager: ProcessExecManager::default(),
|
||||
}
|
||||
}
|
||||
@@ -64,6 +70,7 @@ impl ProcessExecRequestProcessor {
|
||||
request_id: ConnectionRequestId,
|
||||
params: ProcessSpawnParams,
|
||||
) -> Result<(), JSONRPCErrorError> {
|
||||
self.require_local_environment()?;
|
||||
let ProcessSpawnParams {
|
||||
command,
|
||||
process_handle,
|
||||
@@ -173,6 +180,14 @@ impl ProcessExecRequestProcessor {
|
||||
.connection_closed(connection_id)
|
||||
.await;
|
||||
}
|
||||
|
||||
fn require_local_environment(&self) -> Result<(), JSONRPCErrorError> {
|
||||
self.environment_manager
|
||||
.try_local_environment()
|
||||
.is_some()
|
||||
.then_some(())
|
||||
.ok_or_else(|| internal_error("local environment is not configured"))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
||||
Reference in new issue
Block a user