mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Use cached remote plugin catalog for plugin list (#26932)
## Summary This changes the default remote plugin marketplace listing to use the cached global remote catalog when it is already present on disk. The foreground `plugin/list` response can then return from the local catalog cache instead of waiting on `/ps/plugins/list`. When a cached global catalog was present at the start of the request, `plugin/list` still schedules a background refresh through the existing plugin-list background task path so the disk cache is updated for future requests. Cache misses keep the existing synchronous remote fetch path and write the cache, and they do not schedule an extra duplicate background `/ps/plugins/list` refresh. Installed/enabled state continues to come from the existing remote installed overlay path. This change only affects the global remote catalog directory data used by `plugin/list`. ## Testing - `just fmt` - `just test -p codex-app-server plugin_list_uses_cached_global_remote_catalog_and_refreshes_it` - `just test -p codex-core-plugins` - `git diff --check`
This commit is contained in:
@@ -7,6 +7,7 @@ use codex_app_server_protocol::PluginSharePrincipalRole;
|
||||
use codex_app_server_protocol::PluginShareTargetRole;
|
||||
use codex_config::types::McpServerConfig;
|
||||
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::PluginListBackgroundTaskOptions;
|
||||
use codex_core_plugins::remote::REMOTE_GLOBAL_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::remote::RemoteAppTemplateUnavailableReason;
|
||||
use codex_core_plugins::remote::RemotePluginScope;
|
||||
@@ -543,21 +544,30 @@ impl PluginRequestProcessor {
|
||||
return Ok(empty_response());
|
||||
}
|
||||
let plugins_input = config.plugins_config_input();
|
||||
if include_local || marketplace_kinds.contains(&PluginListMarketplaceKind::SharedWithMe) {
|
||||
plugins_manager.maybe_start_plugin_list_background_tasks_for_config(
|
||||
&plugins_input,
|
||||
auth.clone(),
|
||||
&roots,
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
let include_shared_with_me =
|
||||
marketplace_kinds.contains(&PluginListMarketplaceKind::SharedWithMe);
|
||||
let include_global_remote =
|
||||
!explicit_marketplace_kinds && config.features.enabled(Feature::RemotePlugin);
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
let refresh_global_remote_catalog_cache = include_global_remote
|
||||
&& codex_core_plugins::remote::has_cached_global_remote_plugin_catalog(
|
||||
config.codex_home.as_path(),
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
);
|
||||
}
|
||||
let (mut data, marketplace_load_errors) = if include_local {
|
||||
let config_for_marketplace_listing = plugins_input.clone();
|
||||
let plugins_manager_for_marketplace_listing = plugins_manager.clone();
|
||||
let roots_for_marketplace_listing = roots.clone();
|
||||
let shared_plugin_ids_by_local_path = load_shared_plugin_ids_by_local_path(&config)?;
|
||||
match tokio::task::spawn_blocking(move || {
|
||||
let outcome = plugins_manager_for_marketplace_listing
|
||||
.list_marketplaces_for_config(&config_for_marketplace_listing, &roots)?;
|
||||
.list_marketplaces_for_config(
|
||||
&config_for_marketplace_listing,
|
||||
&roots_for_marketplace_listing,
|
||||
)?;
|
||||
Ok::<
|
||||
(
|
||||
Vec<PluginMarketplaceEntry>,
|
||||
@@ -617,9 +627,6 @@ impl PluginRequestProcessor {
|
||||
// TODO(remote plugins): Remove this once remote plugins are ready and vertical plugins are
|
||||
// served directly from the normal remote catalog.
|
||||
if include_vertical && !config.features.enabled(Feature::RemotePlugin) {
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
match codex_core_plugins::remote::fetch_openai_curated_remote_collection_marketplace(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -644,21 +651,16 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
|
||||
let mut remote_sources = Vec::new();
|
||||
if !explicit_marketplace_kinds && config.features.enabled(Feature::RemotePlugin) {
|
||||
if include_global_remote {
|
||||
remote_sources.push(RemoteMarketplaceSource::Global);
|
||||
}
|
||||
if marketplace_kinds.contains(&PluginListMarketplaceKind::WorkspaceDirectory) {
|
||||
remote_sources.push(RemoteMarketplaceSource::WorkspaceDirectory);
|
||||
}
|
||||
if marketplace_kinds.contains(&PluginListMarketplaceKind::SharedWithMe)
|
||||
&& config.features.enabled(Feature::PluginSharing)
|
||||
{
|
||||
if include_shared_with_me && config.features.enabled(Feature::PluginSharing) {
|
||||
remote_sources.push(RemoteMarketplaceSource::SharedWithMe);
|
||||
}
|
||||
if !remote_sources.is_empty() {
|
||||
let remote_plugin_service_config = RemotePluginServiceConfig {
|
||||
chatgpt_base_url: config.chatgpt_base_url.clone(),
|
||||
};
|
||||
match codex_core_plugins::remote::fetch_remote_marketplaces(
|
||||
&remote_plugin_service_config,
|
||||
auth.as_ref(),
|
||||
@@ -702,6 +704,17 @@ impl PluginRequestProcessor {
|
||||
}
|
||||
}
|
||||
}
|
||||
if include_local || include_shared_with_me || include_global_remote {
|
||||
plugins_manager.maybe_start_plugin_list_background_tasks_for_config(
|
||||
&plugins_input,
|
||||
auth.clone(),
|
||||
&roots,
|
||||
PluginListBackgroundTaskOptions {
|
||||
refresh_global_remote_catalog_cache,
|
||||
},
|
||||
Some(self.effective_plugins_changed_callback()),
|
||||
);
|
||||
}
|
||||
|
||||
let featured_plugin_ids = if data
|
||||
.iter()
|
||||
|
||||
Reference in New Issue
Block a user