mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
Prefer remote Sites over the bundled plugin (#42100)
## Why When the remote Sites plugin is installed and its local bundle is available, exposing the bundled copy as well creates duplicate catalog entries and can load the wrong skills. ## What changed - Persist an account- and backend-scoped exclusion for `sites@openai-bundled` once the remote replacement is installed and loadable. - Apply the exclusion to plugin catalogs, search, direct reads and installs, runtime loading, hooks, and skill caches while preserving the remote plugin's server-owned enabled state. - Restore the bundled fallback when the remote plugin is absent or its local files are unavailable, and throttle repeated availability checks for 60 seconds. ## Testing - Added manager tests for persistence across restarts, account/backend isolation, fallback restoration, concurrent checks, and refresh throttling. - Added app-server and agent-turn tests confirming that catalog, search, and skill loading prefer remote Sites. GitOrigin-RevId: bc1154f79d3107910fee9fa27389a0ddb48ce6cf
This commit is contained in:
@@ -53,6 +53,7 @@ use codex_utils_plugins::SkillDiscoveryMode;
|
||||
use codex_utils_plugins::find_plugin_manifest_path;
|
||||
use codex_utils_plugins::migrated_command_skills_root;
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::fs;
|
||||
@@ -128,6 +129,8 @@ pub(crate) fn log_plugin_load_errors(plugins: &[LoadedPlugin<McpServerConfig>])
|
||||
}
|
||||
|
||||
/// Load configured plugins without applying auth-dependent runtime policies.
|
||||
// TODO(sites-migration): Remove the exclusion parameter and lint allowance when bundled Sites is retired.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[instrument(level = "trace", skip_all)]
|
||||
pub(crate) async fn load_plugins_from_layer_stack(
|
||||
config_layer_stack: &ConfigLayerStack,
|
||||
@@ -137,6 +140,7 @@ pub(crate) async fn load_plugins_from_layer_stack(
|
||||
restriction_product: Option<Product>,
|
||||
remote_global_catalog_active: bool,
|
||||
skill_root_loader: &dyn SkillRootLoader<PluginSkillRoot>,
|
||||
excluded_plugin_ids: &BTreeSet<String>,
|
||||
) -> Vec<LoadedPlugin<McpServerConfig>> {
|
||||
let skill_config_rules = skill_config_rules_from_stack(config_layer_stack);
|
||||
let RemoteInstalledPluginsSnapshot {
|
||||
@@ -146,6 +150,7 @@ pub(crate) async fn load_plugins_from_layer_stack(
|
||||
load_plugins_from_layer_stack_with_scope(
|
||||
config_layer_stack,
|
||||
extra_plugins,
|
||||
excluded_plugin_ids,
|
||||
store,
|
||||
remote_global_catalog_active,
|
||||
PluginLoadScope::AllCapabilities {
|
||||
@@ -162,16 +167,18 @@ pub(crate) async fn load_plugins_from_layer_stack(
|
||||
async fn load_plugins_from_layer_stack_with_scope(
|
||||
config_layer_stack: &ConfigLayerStack,
|
||||
extra_plugins: HashMap<String, PluginConfig>,
|
||||
excluded_plugin_ids: &BTreeSet<String>,
|
||||
store: &PluginStore,
|
||||
remote_global_catalog_active: bool,
|
||||
scope: PluginLoadScope<'_>,
|
||||
) -> Vec<LoadedPlugin<McpServerConfig>> {
|
||||
let configured_plugins = merge_configured_plugins_with_remote_installed(
|
||||
let mut configured_plugins = merge_configured_plugins_with_remote_installed(
|
||||
configured_plugins_from_stack(config_layer_stack, store.codex_home().as_path()),
|
||||
extra_plugins,
|
||||
store,
|
||||
remote_global_catalog_active,
|
||||
);
|
||||
configured_plugins.retain(|id, _| !excluded_plugin_ids.contains(id));
|
||||
let mut configured_plugins: Vec<_> = configured_plugins.into_iter().collect();
|
||||
configured_plugins.sort_unstable_by(|(a, _), (b, _)| a.cmp(b));
|
||||
|
||||
@@ -201,6 +208,7 @@ async fn load_plugins_from_layer_stack_with_scope(
|
||||
pub async fn load_plugin_hooks_from_layer_stack(
|
||||
config_layer_stack: &ConfigLayerStack,
|
||||
extra_plugins: HashMap<String, PluginConfig>,
|
||||
excluded_plugin_ids: &BTreeSet<String>,
|
||||
store: &PluginStore,
|
||||
target_curated_marketplace: TargetCuratedMarketplace,
|
||||
remote_global_catalog_active: bool,
|
||||
@@ -208,6 +216,7 @@ pub async fn load_plugin_hooks_from_layer_stack(
|
||||
let mut plugins = load_plugins_from_layer_stack_with_scope(
|
||||
config_layer_stack,
|
||||
extra_plugins,
|
||||
excluded_plugin_ids,
|
||||
store,
|
||||
remote_global_catalog_active,
|
||||
PluginLoadScope::HooksOnly,
|
||||
|
||||
Reference in New Issue
Block a user