From aef40ad91fdb8afed89bc6b2821e58cc6f929608 Mon Sep 17 00:00:00 2001 From: felixxia-oai Date: Sat, 13 Jun 2026 02:00:31 +0100 Subject: [PATCH] [codex] Add auth mode to plugin manager constructor (#27652) ## Context Plugins can expose more than one way for Codex to use them: App connectors for ChatGPT/SIWC-backed sessions and MCP servers for API key login sessions. The broader goal is to make `PluginsManager` the place that understands which plugin surfaces should be visible for the current auth route, so callers do not each have to make that decision themselves. This PR is the small setup step for that work. It lets the plugin manager be created with the current `AuthMode`, which gives the followup auth routing PRs the information they need without relying on setter injection. ## Stack - PR1: #27652 seed plugin manager auth at construction. - PR2: #27459 route plugin surfaces by auth mode. - PR3: #27607 dedupe plugin MCP servers by App declaration name. - PR4: #27602 preserve plugin Apps in connector listings. - PR5: #27461 skip install-time plugin MCP OAuth for matching App routes. ## Summary - Let `PluginsManager::new_with_restriction_product` accept an initial `AuthMode`. - Keep `PluginsManager::new` behavior unchanged for ordinary callers. ## Validation ```bash cargo test -p codex-core-plugins plugins_manager_tracks_auth_mode cargo test -p codex-core list_tool_suggest_discoverable_plugins git diff --check ``` --------- Co-authored-by: Xin Lin --- codex-rs/core-plugins/src/manager.rs | 7 ++++--- codex-rs/core-plugins/src/manager_tests.rs | 13 +++++++++++-- codex-rs/core/src/thread_manager.rs | 8 ++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/codex-rs/core-plugins/src/manager.rs b/codex-rs/core-plugins/src/manager.rs index 6f7e46f3e..da9b7d117 100644 --- a/codex-rs/core-plugins/src/manager.rs +++ b/codex-rs/core-plugins/src/manager.rs @@ -354,12 +354,13 @@ struct PluginLoadCacheKey { impl PluginsManager { pub fn new(codex_home: PathBuf) -> Self { - Self::new_with_restriction_product(codex_home, Some(Product::Codex)) + Self::new_with_options(codex_home, Some(Product::Codex), /*auth_mode*/ None) } - pub fn new_with_restriction_product( + pub fn new_with_options( codex_home: PathBuf, restriction_product: Option, + auth_mode: Option, ) -> Self { // Product restrictions are enforced at marketplace admission time for a given CODEX_HOME: // listing, install, and curated refresh all consult this restriction context before new @@ -386,7 +387,7 @@ impl PluginsManager { GlobalRemoteCatalogCacheRefreshState::default(), ), restriction_product, - auth_mode: RwLock::new(None), + auth_mode: RwLock::new(auth_mode), analytics_events_client: RwLock::new(None), } } diff --git a/codex-rs/core-plugins/src/manager_tests.rs b/codex-rs/core-plugins/src/manager_tests.rs index 1a268a488..fa80eca5c 100644 --- a/codex-rs/core-plugins/src/manager_tests.rs +++ b/codex-rs/core-plugins/src/manager_tests.rs @@ -61,6 +61,13 @@ fn plugins_manager_tracks_auth_mode() { assert_eq!(manager.auth_mode(), Some(AuthMode::ChatgptAuthTokens)); assert!(manager.set_auth_mode(/*auth_mode*/ None)); assert_eq!(manager.auth_mode(), None); + + let manager_with_auth = PluginsManager::new_with_options( + tmp.path().join("auth"), + Some(Product::Codex), + Some(AuthMode::Chatgpt), + ); + assert_eq!(manager_with_auth.auth_mode(), Some(AuthMode::Chatgpt)); } fn write_plugin_with_version( @@ -3038,9 +3045,10 @@ plugins = true let mut config = load_config(tmp.path(), tmp.path()).await; config.chatgpt_base_url = format!("{}/backend-api/", server.uri()); - let manager = PluginsManager::new_with_restriction_product( + let manager = PluginsManager::new_with_options( tmp.path().to_path_buf(), Some(Product::Chatgpt), + /*auth_mode*/ None, ); let featured_plugin_ids = manager @@ -3074,9 +3082,10 @@ plugins = true let mut config = load_config(tmp.path(), tmp.path()).await; config.chatgpt_base_url = format!("{}/backend-api/", server.uri()); - let manager = PluginsManager::new_with_restriction_product( + let manager = PluginsManager::new_with_options( tmp.path().to_path_buf(), /*restriction_product*/ None, + /*auth_mode*/ None, ); let featured_plugin_ids = manager diff --git a/codex-rs/core/src/thread_manager.rs b/codex-rs/core/src/thread_manager.rs index 123f89cf8..19070898d 100644 --- a/codex-rs/core/src/thread_manager.rs +++ b/codex-rs/core/src/thread_manager.rs @@ -273,11 +273,11 @@ impl ThreadManager { let codex_home = config.codex_home.clone(); let restriction_product = session_source.restriction_product(); let (thread_created_tx, _) = broadcast::channel(THREAD_CREATED_CHANNEL_CAPACITY); - let plugins_manager = Arc::new(PluginsManager::new_with_restriction_product( + let plugins_manager = Arc::new(PluginsManager::new_with_options( codex_home.to_path_buf(), restriction_product, + auth_manager.get_api_auth_mode(), )); - plugins_manager.set_auth_mode(auth_manager.get_api_auth_mode()); let mcp_manager = Arc::new(McpManager::new_with_extensions( Arc::clone(&plugins_manager), Arc::clone(&extensions), @@ -368,11 +368,11 @@ impl ThreadManager { }; let (thread_created_tx, _) = broadcast::channel(THREAD_CREATED_CHANNEL_CAPACITY); let restriction_product = SessionSource::Exec.restriction_product(); - let plugins_manager = Arc::new(PluginsManager::new_with_restriction_product( + let plugins_manager = Arc::new(PluginsManager::new_with_options( codex_home.clone(), restriction_product, + auth_manager.get_api_auth_mode(), )); - plugins_manager.set_auth_mode(auth_manager.get_api_auth_mode()); let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager))); let skills_manager = Arc::new(SkillsManager::new_with_restriction_product( skills_codex_home,