[codex] attribute app-server ChatGPT HTTP state [ci changed_files]

This commit is contained in:
Cooper Gamble
2026-06-03 09:54:52 +00:00
parent 0fc80189bf
commit fb9d91415a
5 changed files with 86 additions and 24 deletions
+15 -5
View File
@@ -910,7 +910,11 @@ impl MessageProcessor {
}
ClientRequest::ExperimentalFeatureEnablementSet { params, .. } => {
self.config_processor
.experimental_feature_enablement_set(request_id.clone(), params)
.experimental_feature_enablement_set(
request_id.clone(),
params,
app_server_client_name.as_deref(),
)
.await
}
ClientRequest::RemoteControlEnable { .. } => self
@@ -1133,13 +1137,17 @@ impl MessageProcessor {
self.thread_processor.conversation_summary(params).await
}
ClientRequest::SkillsList { params, .. } => {
self.catalog_processor.skills_list(params).await
self.catalog_processor
.skills_list(params, app_server_client_name.as_deref())
.await
}
ClientRequest::SkillsExtraRootsSet { params, .. } => {
self.catalog_processor.skills_extra_roots_set(params).await
}
ClientRequest::HooksList { params, .. } => {
self.catalog_processor.hooks_list(params).await
self.catalog_processor
.hooks_list(params, app_server_client_name.as_deref())
.await
}
ClientRequest::MarketplaceAdd { params, .. } => {
self.marketplace_processor.marketplace_add(params).await
@@ -1180,7 +1188,9 @@ impl MessageProcessor {
self.plugin_processor.plugin_share_delete(params).await
}
ClientRequest::AppsList { params, .. } => {
self.apps_processor.apps_list(&request_id, params).await
self.apps_processor
.apps_list(&request_id, params, app_server_client_name.as_deref())
.await
}
ClientRequest::SkillsConfigWrite { params, .. } => {
self.catalog_processor.skills_config_write(params).await
@@ -1198,7 +1208,7 @@ impl MessageProcessor {
}
ClientRequest::ExperimentalFeatureList { params, .. } => {
self.catalog_processor
.experimental_feature_list(params)
.experimental_feature_list(params, app_server_client_name.as_deref())
.await
}
ClientRequest::PermissionProfileList { params, .. } => {
@@ -533,6 +533,18 @@ pub(crate) use self::thread_summary::summary_to_thread;
pub(crate) use self::thread_summary::thread_settings_from_config_snapshot;
pub(crate) use self::thread_summary::thread_settings_from_core_snapshot;
fn http_state_context(
config: &Config,
app_server_client_name: Option<&str>,
) -> codex_http_state::HttpStateContext {
codex_http_state::HttpStateContext::new(
config.codex_home.to_path_buf(),
codex_http_state::HttpStateSurface::from_app_server_client_name(
app_server_client_name.unwrap_or_default(),
),
)
}
pub(crate) fn build_api_turns_from_rollout_items(items: &[RolloutItem]) -> Vec<Turn> {
let mut builder = ThreadHistoryBuilder::new();
for item in items {
@@ -1,4 +1,5 @@
use super::*;
use codex_http_state::HttpStateContext;
pub(crate) struct AppsRequestProcessor {
auth_manager: Arc<AuthManager>,
@@ -35,8 +36,9 @@ impl AppsRequestProcessor {
&self,
request_id: &ConnectionRequestId,
params: AppsListParams,
app_server_client_name: Option<&str>,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
self.apps_list_inner(request_id, params)
self.apps_list_inner(request_id, params, app_server_client_name)
.await
.map(|response| response.map(Into::into))
}
@@ -45,6 +47,7 @@ impl AppsRequestProcessor {
&self,
request_id: &ConnectionRequestId,
params: AppsListParams,
app_server_client_name: Option<&str>,
) -> Result<Option<AppsListResponse>, JSONRPCErrorError> {
let thread = if let Some(thread_id) = params.thread_id.as_deref() {
let (_, loaded_thread) = self.load_thread(thread_id).await?;
@@ -65,6 +68,7 @@ impl AppsRequestProcessor {
}
let auth = self.auth_manager.auth().await;
let http_state = http_state_context(&config, app_server_client_name);
if !config
.features
.apps_enabled_for_auth(auth.as_ref().is_some_and(CodexAuth::uses_codex_backend))
@@ -76,7 +80,7 @@ impl AppsRequestProcessor {
}
if !self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
.await
{
return Ok(Some(AppsListResponse {
@@ -92,7 +96,7 @@ impl AppsRequestProcessor {
tokio::spawn(async move {
tokio::select! {
_ = shutdown_token.cancelled() => {}
_ = Self::apps_list_task(outgoing, request, params, config, environment_manager) => {}
_ = Self::apps_list_task(outgoing, request, params, config, environment_manager, http_state) => {}
}
});
Ok(None)
@@ -108,11 +112,15 @@ impl AppsRequestProcessor {
params: AppsListParams,
config: Config,
environment_manager: Arc<EnvironmentManager>,
http_state: HttpStateContext,
) {
let retry_params = params.clone();
let retry_config = config.clone();
let retry_environment_manager = Arc::clone(&environment_manager);
let result = Self::apps_list_response(&outgoing, params, config, environment_manager).await;
let retry_http_state = http_state.clone();
let result =
Self::apps_list_response(&outgoing, params, config, environment_manager, http_state)
.await;
let should_retry = result
.as_ref()
.is_ok_and(|(_, codex_apps_ready)| !codex_apps_ready);
@@ -128,6 +136,7 @@ impl AppsRequestProcessor {
retry_params,
retry_config,
retry_environment_manager,
retry_http_state,
)
.await
{
@@ -141,6 +150,7 @@ impl AppsRequestProcessor {
params: AppsListParams,
config: Config,
environment_manager: Arc<EnvironmentManager>,
http_state: HttpStateContext,
) -> Result<(AppsListResponse, bool), JSONRPCErrorError> {
let AppsListParams {
cursor,
@@ -180,9 +190,13 @@ impl AppsRequestProcessor {
let all_config = config.clone();
tokio::spawn(async move {
let result = connectors::list_all_connectors_with_options(&all_config, force_refetch)
.await
.map_err(|err| format!("failed to list apps: {err}"));
let result = connectors::list_all_connectors_with_options_and_http_state(
&all_config,
force_refetch,
Some(http_state),
)
.await
.map_err(|err| format!("failed to list apps: {err}"));
let _ = tx.send(AppListLoadResult::Directory(result));
});
@@ -303,11 +317,13 @@ impl AppsRequestProcessor {
&self,
config: &Config,
auth: Option<&CodexAuth>,
http_state: &HttpStateContext,
) -> bool {
match workspace_settings::codex_plugins_enabled_for_workspace(
match workspace_settings::codex_plugins_enabled_for_workspace_with_http_state(
config,
auth,
Some(&self.workspace_settings_cache),
Some(http_state.clone()),
)
.await
{
@@ -1,5 +1,6 @@
use super::*;
use codex_config::config_toml::ConfigToml;
use codex_http_state::HttpStateContext;
use codex_http_state::HttpStateSurface;
use futures::StreamExt;
@@ -121,8 +122,9 @@ impl CatalogRequestProcessor {
pub(crate) async fn skills_list(
&self,
params: SkillsListParams,
app_server_client_name: Option<&str>,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
self.skills_list_response(params)
self.skills_list_response(params, app_server_client_name)
.await
.map(|response| Some(response.into()))
}
@@ -130,8 +132,9 @@ impl CatalogRequestProcessor {
pub(crate) async fn hooks_list(
&self,
params: HooksListParams,
app_server_client_name: Option<&str>,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
self.hooks_list_response(params)
self.hooks_list_response(params, app_server_client_name)
.await
.map(|response| Some(response.into()))
}
@@ -167,8 +170,9 @@ impl CatalogRequestProcessor {
pub(crate) async fn experimental_feature_list(
&self,
params: ExperimentalFeatureListParams,
app_server_client_name: Option<&str>,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
self.experimental_feature_list_response(params)
self.experimental_feature_list_response(params, app_server_client_name)
.await
.map(|response| Some(response.into()))
}
@@ -229,11 +233,13 @@ impl CatalogRequestProcessor {
&self,
config: &Config,
auth: Option<&CodexAuth>,
http_state: &HttpStateContext,
) -> bool {
match workspace_settings::codex_plugins_enabled_for_workspace(
match workspace_settings::codex_plugins_enabled_for_workspace_with_http_state(
config,
auth,
Some(&self.workspace_settings_cache),
Some(http_state.clone()),
)
.await
{
@@ -320,6 +326,7 @@ impl CatalogRequestProcessor {
async fn experimental_feature_list_response(
&self,
params: ExperimentalFeatureListParams,
app_server_client_name: Option<&str>,
) -> Result<ExperimentalFeatureListResponse, JSONRPCErrorError> {
let ExperimentalFeatureListParams {
cursor,
@@ -343,9 +350,10 @@ impl CatalogRequestProcessor {
}
None => self.load_latest_config(/*fallback_cwd*/ None).await?,
};
let http_state = http_state_context(&config, app_server_client_name);
let auth = self.auth_manager.auth().await;
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
.await;
let data = FEATURES
@@ -509,6 +517,7 @@ impl CatalogRequestProcessor {
async fn skills_list_response(
&self,
params: SkillsListParams,
app_server_client_name: Option<&str>,
) -> Result<SkillsListResponse, JSONRPCErrorError> {
let SkillsListParams { cwds, force_reload } = params;
let cwds = if cwds.is_empty() {
@@ -518,9 +527,10 @@ impl CatalogRequestProcessor {
};
let config = self.load_latest_config(/*fallback_cwd*/ None).await?;
let http_state = http_state_context(&config, app_server_client_name);
let auth = self.auth_manager.auth().await;
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
.await;
let skills_manager = self.thread_manager.skills_manager();
let plugins_manager = self.thread_manager.plugins_manager();
@@ -615,6 +625,7 @@ impl CatalogRequestProcessor {
async fn hooks_list_response(
&self,
params: HooksListParams,
app_server_client_name: Option<&str>,
) -> Result<HooksListResponse, JSONRPCErrorError> {
let HooksListParams { cwds } = params;
let cwds = if cwds.is_empty() {
@@ -651,8 +662,9 @@ impl CatalogRequestProcessor {
continue;
}
};
let http_state = http_state_context(&config, app_server_client_name);
let workspace_codex_plugins_enabled = self
.workspace_codex_plugins_enabled(&config, auth.as_ref())
.workspace_codex_plugins_enabled(&config, auth.as_ref(), &http_state)
.await;
let plugins_enabled =
config.features.enabled(Feature::Plugins) && workspace_codex_plugins_enabled;
@@ -1,5 +1,6 @@
use std::sync::Arc;
use super::http_state_context;
use crate::config_manager::ConfigManager;
use crate::config_manager_service::ConfigManagerError;
use crate::error_code::internal_error;
@@ -150,6 +151,7 @@ impl ConfigRequestProcessor {
&self,
request_id: ConnectionRequestId,
params: ExperimentalFeatureEnablementSetParams,
app_server_client_name: Option<&str>,
) -> Result<Option<ClientResponsePayload>, JSONRPCErrorError> {
let should_refresh_apps_list = params.enablement.get("apps").copied() == Some(true);
let response = self
@@ -162,8 +164,10 @@ impl ConfigRequestProcessor {
)
.await;
if should_refresh_apps_list {
self.refresh_apps_list_after_experimental_feature_enablement_set()
.await;
self.refresh_apps_list_after_experimental_feature_enablement_set(
app_server_client_name,
)
.await;
}
Ok(None)
}
@@ -195,7 +199,10 @@ impl ConfigRequestProcessor {
Ok(response)
}
async fn refresh_apps_list_after_experimental_feature_enablement_set(&self) {
async fn refresh_apps_list_after_experimental_feature_enablement_set(
&self,
app_server_client_name: Option<&str>,
) {
let config = match self.load_latest_config(/*fallback_cwd*/ None).await {
Ok(config) => config,
Err(error) => {
@@ -206,6 +213,7 @@ impl ConfigRequestProcessor {
return;
}
};
let http_state = http_state_context(&config, app_server_client_name);
let auth = self.auth_manager.auth().await;
if !config.features.apps_enabled_for_auth(
auth.as_ref()
@@ -218,7 +226,11 @@ impl ConfigRequestProcessor {
let environment_manager = self.thread_manager.environment_manager();
tokio::spawn(async move {
let (all_connectors_result, accessible_connectors_result) = tokio::join!(
connectors::list_all_connectors_with_options(&config, /*force_refetch*/ true),
connectors::list_all_connectors_with_options_and_http_state(
&config,
/*force_refetch*/ true,
Some(http_state),
),
connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager(
&config,
/*force_refetch*/ true,