mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
Route curated plugin catalogs by authentication mode (#38429)
## Why The model provider does not reliably identify which curated plugin catalog is available. ChatGPT authentication can be used with a custom provider, while an unauthenticated session should use the API-compatible catalog regardless of its provider. ## What changed - Select the ChatGPT curated catalog only for authentication modes that use the Codex backend; use the API curated catalog for API-key and unauthenticated sessions. - Initialize standalone plugin managers with the current authentication mode across CLI, app-server, MCP, and external-agent migration paths. - Preserve authentication mode while detecting and importing migrated plugins. ## Testing - Cover catalog and skill routing across ChatGPT, API-key, unauthenticated, Bedrock, and custom-provider configurations. - Verify authenticated plugin migration uses the ChatGPT curated marketplace. GitOrigin-RevId: 660a339ee8891c33aad961078d3a979242a6a166
This commit is contained in:
committed by
copyberry
parent
507ef0b371
commit
f898ebcafd
@@ -1,7 +1,7 @@
|
||||
use crate::plugins::plugins_manager_for_config;
|
||||
use crate::plugins::test_support::load_plugins_config;
|
||||
use crate::plugins::test_support::write_file;
|
||||
use crate::plugins::test_support::write_openai_curated_marketplace;
|
||||
use crate::plugins::test_support::write_openai_api_curated_marketplace;
|
||||
use codex_core_plugins::startup_sync::curated_plugins_repo_path;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
use pretty_assertions::assert_eq;
|
||||
@@ -11,7 +11,7 @@ async fn list_discoverable_plugins(
|
||||
config: &crate::config::Config,
|
||||
loaded_plugin_app_connector_ids: &[String],
|
||||
) -> anyhow::Result<Vec<DiscoverablePluginInfo>> {
|
||||
let plugins_manager = plugins_manager_for_config(config);
|
||||
let plugins_manager = plugins_manager_for_config(config, /*auth_mode*/ None);
|
||||
super::list_tool_suggest_discoverable_plugins(
|
||||
config,
|
||||
&plugins_manager,
|
||||
@@ -25,7 +25,7 @@ async fn list_discoverable_plugins(
|
||||
async fn list_tool_suggest_discoverable_plugins_returns_empty_when_plugins_feature_disabled() {
|
||||
let codex_home = tempdir().expect("tempdir should succeed");
|
||||
let curated_root = curated_plugins_repo_path(codex_home.path());
|
||||
write_openai_curated_marketplace(&curated_root, &["slack"]);
|
||||
write_openai_api_curated_marketplace(&curated_root, &["slack"]);
|
||||
write_file(
|
||||
&codex_home.path().join(crate::config::CONFIG_TOML_FILE),
|
||||
r#"[features]
|
||||
@@ -43,7 +43,7 @@ plugins = false
|
||||
async fn list_tool_suggest_discoverable_plugins_omits_disabled_tool_suggestions() {
|
||||
let codex_home = tempdir().expect("tempdir should succeed");
|
||||
let curated_root = curated_plugins_repo_path(codex_home.path());
|
||||
write_openai_curated_marketplace(&curated_root, &["slack"]);
|
||||
write_openai_api_curated_marketplace(&curated_root, &["slack"]);
|
||||
write_file(
|
||||
&codex_home.path().join(crate::config::CONFIG_TOML_FILE),
|
||||
r#"[features]
|
||||
@@ -51,7 +51,7 @@ plugins = true
|
||||
|
||||
[tool_suggest]
|
||||
disabled_tools = [
|
||||
{ type = "plugin", id = "slack@openai-curated" }
|
||||
{ type = "plugin", id = "slack@openai-api-curated" }
|
||||
]
|
||||
"#,
|
||||
);
|
||||
@@ -66,14 +66,14 @@ disabled_tools = [
|
||||
async fn list_tool_suggest_discoverable_plugins_includes_configured_plugin_ids() {
|
||||
let codex_home = tempdir().expect("tempdir should succeed");
|
||||
let curated_root = curated_plugins_repo_path(codex_home.path());
|
||||
write_openai_curated_marketplace(&curated_root, &["sample"]);
|
||||
write_openai_api_curated_marketplace(&curated_root, &["sample"]);
|
||||
write_file(
|
||||
&codex_home.path().join(crate::config::CONFIG_TOML_FILE),
|
||||
r#"[features]
|
||||
plugins = true
|
||||
|
||||
[tool_suggest]
|
||||
discoverables = [{ type = "plugin", id = "sample@openai-curated" }]
|
||||
discoverables = [{ type = "plugin", id = "sample@openai-api-curated" }]
|
||||
"#,
|
||||
);
|
||||
|
||||
@@ -83,7 +83,7 @@ discoverables = [{ type = "plugin", id = "sample@openai-curated" }]
|
||||
assert_eq!(
|
||||
discoverable_plugins,
|
||||
vec![DiscoverablePluginInfo {
|
||||
id: "sample@openai-curated".to_string(),
|
||||
id: "sample@openai-api-curated".to_string(),
|
||||
remote_plugin_id: None,
|
||||
name: "sample".to_string(),
|
||||
description: Some(
|
||||
|
||||
@@ -11,6 +11,7 @@ pub(crate) mod test_support;
|
||||
|
||||
use crate::config::Config;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_protocol::auth::AuthMode;
|
||||
use codex_skills_extension::HostSkillsService;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -28,10 +29,14 @@ pub(crate) use mentions::collect_tool_mentions_from_messages;
|
||||
/// Constructs a standalone plugin manager with extension-owned plugin skill loading.
|
||||
///
|
||||
/// Callers that already own a host skills service should inject that existing service instead.
|
||||
pub fn plugins_manager_for_config(config: &Config) -> PluginsManager {
|
||||
pub fn plugins_manager_for_config(config: &Config, auth_mode: Option<AuthMode>) -> PluginsManager {
|
||||
let skill_root_loader = Arc::new(HostSkillsService::new(
|
||||
config.codex_home.clone(),
|
||||
/*bundled_skills_enabled*/ false,
|
||||
));
|
||||
PluginsManager::new(config.codex_home.to_path_buf(), skill_root_loader)
|
||||
PluginsManager::new(
|
||||
config.codex_home.to_path_buf(),
|
||||
auth_mode,
|
||||
skill_root_loader,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::config::ConfigBuilder;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::OPENAI_API_CURATED_MARKETPLACE_NAME;
|
||||
|
||||
pub(crate) const TEST_CURATED_PLUGIN_SHA: &str = "0123456789abcdef0123456789abcdef01234567";
|
||||
|
||||
@@ -50,7 +50,7 @@ pub(crate) fn write_curated_plugin(root: &Path, plugin_name: &str) {
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn write_openai_curated_marketplace(root: &Path, plugin_names: &[&str]) {
|
||||
pub(crate) fn write_openai_api_curated_marketplace(root: &Path, plugin_names: &[&str]) {
|
||||
let plugins = plugin_names
|
||||
.iter()
|
||||
.map(|plugin_name| {
|
||||
@@ -67,10 +67,10 @@ pub(crate) fn write_openai_curated_marketplace(root: &Path, plugin_names: &[&str
|
||||
.collect::<Vec<_>>()
|
||||
.join(",\n");
|
||||
write_file(
|
||||
&root.join(".agents/plugins/marketplace.json"),
|
||||
&root.join(".agents/plugins/api_marketplace.json"),
|
||||
&format!(
|
||||
r#"{{
|
||||
"name": "{OPENAI_CURATED_MARKETPLACE_NAME}",
|
||||
"name": "{OPENAI_API_CURATED_MARKETPLACE_NAME}",
|
||||
"plugins": [
|
||||
{plugins}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user