mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
enable/disable remote control at runtime, not via features (#22578)
## Why reapplies https://github.com/openai/codex/pull/22386 which was previously reverted Also, introduce `remoteControl/enable` and `remoteControl/disable` app-server APIs to toggle on/off remote control at runtime for a given running app-server instance. ## What Changed - Adds experimental v2 RPCs: - `remoteControl/enable` - `remoteControl/disable` - Adds `RemoteControlRequestProcessor` and routes the new RPCs through it instead of `ConfigRequestProcessor`. - Adds named `RemoteControlHandle::enable`, `disable`, and `status` methods. - Makes `remoteControl/enable` return an error when sqlite state DB is unavailable, while keeping enrollment/websocket failures as async status updates. - Adds `AppServerRuntimeOptions.remote_control_enabled` and hidden `--remote-control` flags for `codex app-server` and `codex-app-server`. - Updates managed daemon startup to use `codex app-server --remote-control --listen unix://`. - Marks `Feature::RemoteControl` as removed and ignores `[features].remote_control`. - Updates app-server README entries for the new remote-control methods.
This commit is contained in:
committed by
GitHub
Unverified
parent
512f8f8012
commit
4e368aa2e9
@@ -6,7 +6,6 @@ use crate::error_code::internal_error;
|
||||
use crate::error_code::invalid_request;
|
||||
use crate::outgoing_message::ConnectionRequestId;
|
||||
use crate::outgoing_message::OutgoingMessageSender;
|
||||
use crate::transport::RemoteControlHandle;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_app_server_protocol::AppListUpdatedNotification;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
@@ -39,7 +38,6 @@ use codex_config::MatcherGroup as CoreMatcherGroup;
|
||||
use codex_config::ResidencyRequirement as CoreResidencyRequirement;
|
||||
use codex_config::SandboxModeRequirement as CoreSandboxModeRequirement;
|
||||
use codex_core::ThreadManager;
|
||||
use codex_features::Feature;
|
||||
use codex_features::canonical_feature_for_key;
|
||||
use codex_features::feature_for_key;
|
||||
use codex_login::AuthManager;
|
||||
@@ -67,7 +65,6 @@ pub(crate) struct ConfigRequestProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
analytics_events_client: AnalyticsEventsClient,
|
||||
remote_control_handle: Option<RemoteControlHandle>,
|
||||
}
|
||||
|
||||
impl ConfigRequestProcessor {
|
||||
@@ -77,7 +74,6 @@ impl ConfigRequestProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
analytics_events_client: AnalyticsEventsClient,
|
||||
remote_control_handle: Option<RemoteControlHandle>,
|
||||
) -> Self {
|
||||
Self {
|
||||
outgoing,
|
||||
@@ -85,7 +81,6 @@ impl ConfigRequestProcessor {
|
||||
auth_manager,
|
||||
thread_manager,
|
||||
analytics_events_client,
|
||||
remote_control_handle,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,21 +182,6 @@ impl ConfigRequestProcessor {
|
||||
pub(crate) async fn handle_config_mutation(&self) {
|
||||
self.thread_manager.plugins_manager().clear_cache();
|
||||
self.thread_manager.skills_manager().clear_cache();
|
||||
let Some(remote_control_handle) = &self.remote_control_handle else {
|
||||
return;
|
||||
};
|
||||
|
||||
match self.load_latest_config(/*fallback_cwd*/ None).await {
|
||||
Ok(config) => {
|
||||
remote_control_handle.set_enabled(config.features.enabled(Feature::RemoteControl));
|
||||
}
|
||||
Err(error) => {
|
||||
tracing::warn!(
|
||||
"failed to load config for remote control enablement refresh after config mutation: {}",
|
||||
error.message
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_config_mutation_result<T>(
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use crate::error_code::internal_error;
|
||||
use crate::error_code::invalid_request;
|
||||
use crate::transport::RemoteControlHandle;
|
||||
use crate::transport::RemoteControlUnavailable;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::RemoteControlDisableResponse;
|
||||
use codex_app_server_protocol::RemoteControlEnableResponse;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct RemoteControlRequestProcessor {
|
||||
remote_control_handle: Option<RemoteControlHandle>,
|
||||
}
|
||||
|
||||
impl RemoteControlRequestProcessor {
|
||||
pub(crate) fn new(remote_control_handle: Option<RemoteControlHandle>) -> Self {
|
||||
Self {
|
||||
remote_control_handle,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enable(&self) -> Result<RemoteControlEnableResponse, JSONRPCErrorError> {
|
||||
let handle = self.handle()?;
|
||||
handle
|
||||
.enable()
|
||||
.map(RemoteControlEnableResponse::from)
|
||||
.map_err(map_unavailable)
|
||||
}
|
||||
|
||||
pub(crate) fn disable(&self) -> Result<RemoteControlDisableResponse, JSONRPCErrorError> {
|
||||
let handle = self.handle()?;
|
||||
Ok(RemoteControlDisableResponse::from(handle.disable()))
|
||||
}
|
||||
|
||||
fn handle(&self) -> Result<&RemoteControlHandle, JSONRPCErrorError> {
|
||||
self.remote_control_handle
|
||||
.as_ref()
|
||||
.ok_or_else(|| internal_error("remote control is unavailable for this app-server"))
|
||||
}
|
||||
}
|
||||
|
||||
fn map_unavailable(err: RemoteControlUnavailable) -> JSONRPCErrorError {
|
||||
invalid_request(err.to_string())
|
||||
}
|
||||
Reference in New Issue
Block a user