From 9157458552c95ab16016abae3de471688fe041d0 Mon Sep 17 00:00:00 2001 From: Cooper Gamble Date: Wed, 3 Jun 2026 09:48:30 +0000 Subject: [PATCH] [codex] attribute app-server plugin HTTP state [ci changed_files] --- codex-rs/app-server/src/message_processor.rs | 42 +++-- .../src/request_processors/plugins.rs | 148 +++++++++++++----- codex-rs/core-plugins/src/manager.rs | 66 +++++++- 3 files changed, 199 insertions(+), 57 deletions(-) diff --git a/codex-rs/app-server/src/message_processor.rs b/codex-rs/app-server/src/message_processor.rs index eea3882dca..0411237528 100644 --- a/codex-rs/app-server/src/message_processor.rs +++ b/codex-rs/app-server/src/message_processor.rs @@ -1159,33 +1159,49 @@ impl MessageProcessor { self.marketplace_processor.marketplace_upgrade(params).await } ClientRequest::PluginList { params, .. } => { - self.plugin_processor.plugin_list(params).await + self.plugin_processor + .plugin_list(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginInstalled { params, .. } => { - self.plugin_processor.plugin_installed(params).await + self.plugin_processor + .plugin_installed(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginRead { params, .. } => { - self.plugin_processor.plugin_read(params).await + self.plugin_processor + .plugin_read(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginSkillRead { params, .. } => { - self.plugin_processor.plugin_skill_read(params).await + self.plugin_processor + .plugin_skill_read(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginShareSave { params, .. } => { - self.plugin_processor.plugin_share_save(params).await + self.plugin_processor + .plugin_share_save(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginShareUpdateTargets { params, .. } => { self.plugin_processor - .plugin_share_update_targets(params) + .plugin_share_update_targets(params, app_server_client_name.as_deref()) .await } ClientRequest::PluginShareList { params, .. } => { - self.plugin_processor.plugin_share_list(params).await + self.plugin_processor + .plugin_share_list(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginShareCheckout { params, .. } => { - self.plugin_processor.plugin_share_checkout(params).await + self.plugin_processor + .plugin_share_checkout(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginShareDelete { params, .. } => { - self.plugin_processor.plugin_share_delete(params).await + self.plugin_processor + .plugin_share_delete(params, app_server_client_name.as_deref()) + .await } ClientRequest::AppsList { params, .. } => { self.apps_processor @@ -1196,10 +1212,14 @@ impl MessageProcessor { self.catalog_processor.skills_config_write(params).await } ClientRequest::PluginInstall { params, .. } => { - self.plugin_processor.plugin_install(params).await + self.plugin_processor + .plugin_install(params, app_server_client_name.as_deref()) + .await } ClientRequest::PluginUninstall { params, .. } => { - self.plugin_processor.plugin_uninstall(params).await + self.plugin_processor + .plugin_uninstall(params, app_server_client_name.as_deref()) + .await } ClientRequest::ModelList { params, .. } => { self.catalog_processor diff --git a/codex-rs/app-server/src/request_processors/plugins.rs b/codex-rs/app-server/src/request_processors/plugins.rs index b3422e03e9..bd134fa02a 100644 --- a/codex-rs/app-server/src/request_processors/plugins.rs +++ b/codex-rs/app-server/src/request_processors/plugins.rs @@ -26,6 +26,14 @@ pub(crate) struct PluginRequestProcessor { workspace_settings_cache: Arc, } +fn remote_plugin_service_config( + config: &Config, + app_server_client_name: Option<&str>, +) -> RemotePluginServiceConfig { + RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()) + .with_http_state(http_state_context(config, app_server_client_name)) +} + fn plugin_skills_to_info( skills: &[codex_core::skills::SkillMetadata], disabled_skill_paths: &HashSet, @@ -344,8 +352,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_list( &self, params: PluginListParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_list_response(params) + self.plugin_list_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -353,8 +362,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_installed( &self, params: PluginInstalledParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_installed_response(params) + self.plugin_installed_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -362,8 +372,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_read( &self, params: PluginReadParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_read_response(params) + self.plugin_read_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -371,8 +382,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_skill_read( &self, params: PluginSkillReadParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_skill_read_response(params) + self.plugin_skill_read_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -380,8 +392,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_share_save( &self, params: PluginShareSaveParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_share_save_response(params) + self.plugin_share_save_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -389,8 +402,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_share_update_targets( &self, params: PluginShareUpdateTargetsParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_share_update_targets_response(params) + self.plugin_share_update_targets_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -398,8 +412,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_share_list( &self, params: PluginShareListParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_share_list_response(params) + self.plugin_share_list_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -407,8 +422,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_share_checkout( &self, params: PluginShareCheckoutParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_share_checkout_response(params) + self.plugin_share_checkout_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -416,8 +432,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_share_delete( &self, params: PluginShareDeleteParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_share_delete_response(params) + self.plugin_share_delete_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -425,8 +442,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_install( &self, params: PluginInstallParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_install_response(params) + self.plugin_install_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -434,8 +452,9 @@ impl PluginRequestProcessor { pub(crate) async fn plugin_uninstall( &self, params: PluginUninstallParams, + app_server_client_name: Option<&str>, ) -> Result, JSONRPCErrorError> { - self.plugin_uninstall_response(params) + self.plugin_uninstall_response(params, app_server_client_name) .await .map(|response| Some(response.into())) } @@ -491,11 +510,13 @@ impl PluginRequestProcessor { &self, config: &Config, auth: Option<&CodexAuth>, + app_server_client_name: Option<&str>, ) -> 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_context(config, app_server_client_name)), ) .await { @@ -512,6 +533,7 @@ impl PluginRequestProcessor { async fn plugin_list_response( &self, params: PluginListParams, + app_server_client_name: Option<&str>, ) -> Result { let plugins_manager = self.thread_manager.plugins_manager(); let PluginListParams { @@ -536,7 +558,7 @@ impl PluginRequestProcessor { } let auth = self.auth_manager.auth().await; if !self - .workspace_codex_plugins_enabled(&config, auth.as_ref()) + .workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name) .await { return Ok(empty_response()); @@ -617,7 +639,7 @@ impl PluginRequestProcessor { // served directly from the normal remote catalog. if include_vertical && !config.features.enabled(Feature::RemotePlugin) { let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); match codex_core_plugins::remote::fetch_openai_curated_remote_collection_marketplace( &remote_plugin_service_config, auth.as_ref(), @@ -655,7 +677,7 @@ impl PluginRequestProcessor { } if !remote_sources.is_empty() { let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); match codex_core_plugins::remote::fetch_remote_marketplaces( &remote_plugin_service_config, auth.as_ref(), @@ -705,7 +727,11 @@ impl PluginRequestProcessor { .any(|marketplace| marketplace.name == OPENAI_CURATED_MARKETPLACE_NAME) { match plugins_manager - .featured_plugin_ids_for_config(&plugins_input, auth.as_ref()) + .featured_plugin_ids_for_config_with_http_state( + &plugins_input, + auth.as_ref(), + http_state_context(&config, app_server_client_name), + ) .await { Ok(featured_plugin_ids) => featured_plugin_ids, @@ -731,6 +757,7 @@ impl PluginRequestProcessor { async fn plugin_installed_response( &self, params: PluginInstalledParams, + app_server_client_name: Option<&str>, ) -> Result { let plugins_manager = self.thread_manager.plugins_manager(); let PluginInstalledParams { @@ -753,7 +780,7 @@ impl PluginRequestProcessor { } let auth = self.auth_manager.auth().await; if !self - .workspace_codex_plugins_enabled(&config, auth.as_ref()) + .workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name) .await { return Ok(empty_response()); @@ -781,9 +808,11 @@ impl PluginRequestProcessor { data.extend( self.load_remote_installed_plugins( plugins_manager, + &config, &plugins_input, &remote_installed_plugin_visible_scopes, auth.as_ref(), + app_server_client_name, ) .await, ); @@ -881,9 +910,11 @@ impl PluginRequestProcessor { async fn load_remote_installed_plugins( &self, plugins_manager: Arc, + config: &Config, plugins_input: &codex_core_plugins::PluginsConfigInput, visible_scopes: &[RemotePluginScope], auth: Option<&CodexAuth>, + app_server_client_name: Option<&str>, ) -> Vec { let remote_marketplaces = if let Some(remote_marketplaces) = plugins_manager.build_remote_installed_plugin_marketplaces_from_cache(visible_scopes) @@ -891,11 +922,12 @@ impl PluginRequestProcessor { Ok(remote_marketplaces) } else { plugins_manager - .build_and_cache_remote_installed_plugin_marketplaces( + .build_and_cache_remote_installed_plugin_marketplaces_with_http_state( plugins_input, auth, visible_scopes, Some(self.effective_plugins_changed_callback()), + http_state_context(config, app_server_client_name), ) .await }; @@ -922,6 +954,7 @@ impl PluginRequestProcessor { async fn plugin_read_response( &self, params: PluginReadParams, + app_server_client_name: Option<&str>, ) -> Result { let plugins_manager = self.thread_manager.plugins_manager(); let PluginReadParams { @@ -965,7 +998,7 @@ impl PluginRequestProcessor { Some(context) => { let auth = self.auth_manager.auth().await; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); match codex_core_plugins::remote::fetch_remote_plugin_share_context( &remote_plugin_service_config, auth.as_ref(), @@ -1013,6 +1046,7 @@ impl PluginRequestProcessor { &config, &outcome.plugin.apps, Arc::clone(&environment_manager), + app_server_client_name, ) .await; let visible_skills = outcome @@ -1070,7 +1104,7 @@ impl PluginRequestProcessor { } let auth = self.auth_manager.auth().await; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); validate_remote_plugin_id(&plugin_name)?; let remote_detail = codex_core_plugins::remote::fetch_remote_plugin_detail( &remote_plugin_service_config, @@ -1093,6 +1127,7 @@ impl PluginRequestProcessor { &config, &plugin_apps, Arc::clone(&environment_manager), + app_server_client_name, ) .await; remote_plugin_detail_to_info(remote_detail, app_summaries) @@ -1105,6 +1140,7 @@ impl PluginRequestProcessor { async fn plugin_skill_read_response( &self, params: PluginSkillReadParams, + app_server_client_name: Option<&str>, ) -> Result { let PluginSkillReadParams { remote_marketplace_name, @@ -1127,7 +1163,7 @@ impl PluginRequestProcessor { let auth = self.auth_manager.auth().await; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let remote_skill_detail = codex_core_plugins::remote::fetch_remote_plugin_skill_detail( &remote_plugin_service_config, auth.as_ref(), @@ -1148,6 +1184,7 @@ impl PluginRequestProcessor { async fn plugin_share_save_response( &self, params: PluginShareSaveParams, + app_server_client_name: Option<&str>, ) -> Result { let (config, auth) = self.load_plugin_share_config_and_auth().await?; if !config.features.enabled(Feature::PluginSharing) { @@ -1179,7 +1216,7 @@ impl PluginRequestProcessor { } let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let access_policy = codex_core_plugins::remote::RemotePluginShareAccessPolicy { discoverability: discoverability.map(remote_plugin_share_discoverability), share_targets: share_targets.map(remote_plugin_share_targets), @@ -1205,6 +1242,7 @@ impl PluginRequestProcessor { async fn plugin_share_update_targets_response( &self, params: PluginShareUpdateTargetsParams, + app_server_client_name: Option<&str>, ) -> Result { let (config, auth) = self.load_plugin_share_config_and_auth().await?; if !config.features.enabled(Feature::PluginSharing) { @@ -1221,7 +1259,7 @@ impl PluginRequestProcessor { validate_client_plugin_share_targets(&share_targets)?; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let result = codex_core_plugins::remote::update_remote_plugin_share_targets( &remote_plugin_service_config, auth.as_ref(), @@ -1247,10 +1285,11 @@ impl PluginRequestProcessor { async fn plugin_share_list_response( &self, _params: PluginShareListParams, + app_server_client_name: Option<&str>, ) -> Result { let (config, auth) = self.load_plugin_share_config_and_auth().await?; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let data = codex_core_plugins::remote::list_remote_plugin_shares( &remote_plugin_service_config, auth.as_ref(), @@ -1277,6 +1316,7 @@ impl PluginRequestProcessor { async fn plugin_share_checkout_response( &self, params: PluginShareCheckoutParams, + app_server_client_name: Option<&str>, ) -> Result { let (config, auth) = self.load_plugin_share_config_and_auth().await?; if !config.features.enabled(Feature::PluginSharing) { @@ -1288,7 +1328,7 @@ impl PluginRequestProcessor { } let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let result = codex_core_plugins::remote::checkout_remote_plugin_share( &remote_plugin_service_config, auth.as_ref(), @@ -1312,6 +1352,7 @@ impl PluginRequestProcessor { async fn plugin_share_delete_response( &self, params: PluginShareDeleteParams, + app_server_client_name: Option<&str>, ) -> Result { let (config, auth) = self.load_plugin_share_config_and_auth().await?; let PluginShareDeleteParams { remote_plugin_id } = params; @@ -1320,7 +1361,7 @@ impl PluginRequestProcessor { } let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); codex_core_plugins::remote::delete_remote_plugin_share( &remote_plugin_service_config, auth.as_ref(), @@ -1347,6 +1388,7 @@ impl PluginRequestProcessor { async fn plugin_install_response( &self, params: PluginInstallParams, + app_server_client_name: Option<&str>, ) -> Result { let PluginInstallParams { marketplace_path, @@ -1357,7 +1399,11 @@ impl PluginRequestProcessor { (Some(marketplace_path), None) => marketplace_path, (None, Some(remote_marketplace_name)) => { return self - .remote_plugin_install_response(remote_marketplace_name, plugin_name) + .remote_plugin_install_response( + remote_marketplace_name, + plugin_name, + app_server_client_name, + ) .await; } (Some(_), Some(_)) | (None, None) => { @@ -1371,7 +1417,7 @@ impl PluginRequestProcessor { let auth = self.auth_manager.auth().await; if !self - .workspace_codex_plugins_enabled(&config, auth.as_ref()) + .workspace_codex_plugins_enabled(&config, auth.as_ref(), app_server_client_name) .await { return Err(invalid_request( @@ -1415,6 +1461,7 @@ impl PluginRequestProcessor { auth.as_ref().is_some_and(CodexAuth::is_chatgpt_auth), &result.plugin_id.as_key(), &plugin_apps, + app_server_client_name, ) .await; @@ -1428,6 +1475,7 @@ impl PluginRequestProcessor { &self, remote_marketplace_name: String, remote_plugin_id: String, + app_server_client_name: Option<&str>, ) -> Result { let config = self.load_latest_config(/*fallback_cwd*/ None).await?; if !config.features.enabled(Feature::Plugins) { @@ -1439,7 +1487,7 @@ impl PluginRequestProcessor { let auth = self.auth_manager.auth().await; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let remote_detail = codex_core_plugins::remote::fetch_remote_plugin_detail_with_download_urls( &remote_plugin_service_config, @@ -1529,6 +1577,7 @@ impl PluginRequestProcessor { auth.as_ref().is_some_and(CodexAuth::is_chatgpt_auth), &result.plugin_id.as_key(), &plugin_apps, + app_server_client_name, ) .await; @@ -1544,6 +1593,7 @@ impl PluginRequestProcessor { is_chatgpt_auth: bool, plugin_id: &str, plugin_apps: &[codex_plugin::AppConnectorId], + app_server_client_name: Option<&str>, ) -> Vec { if plugin_apps.is_empty() || !config.features.apps_enabled_for_auth(is_chatgpt_auth) { return Vec::new(); @@ -1551,7 +1601,11 @@ impl PluginRequestProcessor { let environment_manager = self.thread_manager.environment_manager(); let (all_connectors_result, accessible_connectors_result) = tokio::join!( - connectors::list_all_connectors_with_options(config, /*force_refetch*/ false), + connectors::list_all_connectors_with_options_and_http_state( + config, + /*force_refetch*/ false, + Some(http_state_context(config, app_server_client_name)), + ), connectors::list_accessible_connectors_from_mcp_tools_with_environment_manager( config, /*force_refetch*/ true, @@ -1686,6 +1740,7 @@ impl PluginRequestProcessor { async fn plugin_uninstall_response( &self, params: PluginUninstallParams, + app_server_client_name: Option<&str>, ) -> Result { let PluginUninstallParams { plugin_id } = params; if codex_plugin::PluginId::parse(&plugin_id).is_err() @@ -1694,7 +1749,9 @@ impl PluginRequestProcessor { return Err(invalid_request("invalid remote plugin id")); } if is_valid_remote_plugin_id(&plugin_id) { - return self.remote_plugin_uninstall_response(plugin_id).await; + return self + .remote_plugin_uninstall_response(plugin_id, app_server_client_name) + .await; } let plugins_manager = self.thread_manager.plugins_manager(); @@ -1777,6 +1834,7 @@ impl PluginRequestProcessor { async fn remote_plugin_uninstall_response( &self, plugin_id: String, + app_server_client_name: Option<&str>, ) -> Result { let config = self.load_latest_config(/*fallback_cwd*/ None).await?; if !config.features.enabled(Feature::Plugins) { @@ -1786,7 +1844,7 @@ impl PluginRequestProcessor { let auth = self.auth_manager.auth().await; let remote_plugin_service_config = - RemotePluginServiceConfig::new(config.chatgpt_base_url.clone()); + remote_plugin_service_config(&config, app_server_client_name); let uninstall_result = codex_core_plugins::remote::uninstall_remote_plugin( &remote_plugin_service_config, auth.as_ref(), @@ -1821,21 +1879,27 @@ async fn load_plugin_app_summaries( config: &Config, plugin_apps: &[codex_plugin::AppConnectorId], environment_manager: Arc, + app_server_client_name: Option<&str>, ) -> Vec { if plugin_apps.is_empty() { return Vec::new(); } - let connectors = - match connectors::list_all_connectors_with_options(config, /*force_refetch*/ false).await { - Ok(connectors) => connectors, - Err(err) => { - warn!("failed to load app metadata for plugin/read: {err:#}"); - connectors::list_cached_all_connectors(config) - .await - .unwrap_or_default() - } - }; + let connectors = match connectors::list_all_connectors_with_options_and_http_state( + config, + /*force_refetch*/ false, + Some(http_state_context(config, app_server_client_name)), + ) + .await + { + Ok(connectors) => connectors, + Err(err) => { + warn!("failed to load app metadata for plugin/read: {err:#}"); + connectors::list_cached_all_connectors(config) + .await + .unwrap_or_default() + } + }; let plugin_connectors = connectors::connectors_for_plugin_apps(connectors, plugin_apps); diff --git a/codex-rs/core-plugins/src/manager.rs b/codex-rs/core-plugins/src/manager.rs index 0263b6e565..4740a01e50 100644 --- a/codex-rs/core-plugins/src/manager.rs +++ b/codex-rs/core-plugins/src/manager.rs @@ -58,6 +58,7 @@ use codex_config::types::PluginConfig; use codex_config::version_for_toml; use codex_core_skills::SkillMetadata; use codex_hooks::plugin_hook_declarations; +use codex_http_state::HttpStateContext; use codex_login::AuthManager; use codex_login::CodexAuth; use codex_plugin::AppConnectorId; @@ -622,11 +623,40 @@ impl PluginsManager { visible_scopes: &[RemotePluginScope], on_effective_plugins_changed: Option>, ) -> Result, RemotePluginCatalogError> { - let plugins = crate::remote::fetch_remote_installed_plugins( - &remote_plugin_service_config(config), + self.build_and_cache_remote_installed_plugin_marketplaces_with_service_config( + remote_plugin_service_config(config), auth, + visible_scopes, + on_effective_plugins_changed, ) - .await?; + .await + } + + pub async fn build_and_cache_remote_installed_plugin_marketplaces_with_http_state( + &self, + config: &PluginsConfigInput, + auth: Option<&CodexAuth>, + visible_scopes: &[RemotePluginScope], + on_effective_plugins_changed: Option>, + http_state: HttpStateContext, + ) -> Result, RemotePluginCatalogError> { + self.build_and_cache_remote_installed_plugin_marketplaces_with_service_config( + remote_plugin_service_config(config).with_http_state(http_state), + auth, + visible_scopes, + on_effective_plugins_changed, + ) + .await + } + + async fn build_and_cache_remote_installed_plugin_marketplaces_with_service_config( + &self, + service_config: RemotePluginServiceConfig, + auth: Option<&CodexAuth>, + visible_scopes: &[RemotePluginScope], + on_effective_plugins_changed: Option>, + ) -> Result, RemotePluginCatalogError> { + let plugins = crate::remote::fetch_remote_installed_plugins(&service_config, auth).await?; let marketplaces = crate::remote::group_remote_installed_plugins_by_marketplaces(&plugins, visible_scopes); let changed = self.write_remote_installed_plugins_cache(plugins); @@ -814,6 +844,34 @@ impl PluginsManager { &self, config: &PluginsConfigInput, auth: Option<&CodexAuth>, + ) -> Result, RemotePluginFetchError> { + self.featured_plugin_ids_for_config_with_service_config( + config, + auth, + remote_plugin_service_config(config), + ) + .await + } + + pub async fn featured_plugin_ids_for_config_with_http_state( + &self, + config: &PluginsConfigInput, + auth: Option<&CodexAuth>, + http_state: HttpStateContext, + ) -> Result, RemotePluginFetchError> { + self.featured_plugin_ids_for_config_with_service_config( + config, + auth, + remote_plugin_service_config(config).with_http_state(http_state), + ) + .await + } + + async fn featured_plugin_ids_for_config_with_service_config( + &self, + config: &PluginsConfigInput, + auth: Option<&CodexAuth>, + service_config: RemotePluginServiceConfig, ) -> Result, RemotePluginFetchError> { if !config.plugins_enabled { return Ok(Vec::new()); @@ -824,7 +882,7 @@ impl PluginsManager { return Ok(featured_plugin_ids); } let featured_plugin_ids = crate::remote_legacy::fetch_remote_featured_plugin_ids( - &remote_plugin_service_config(config), + &service_config, auth, self.restriction_product, )