inject analytics_manager

This commit is contained in:
alexsong-oai
2026-03-12 17:36:48 -07:00
parent 0e0fc9dd5b
commit 3db6995357
13 changed files with 56 additions and 56 deletions

View File

@@ -192,9 +192,12 @@ impl MessageProcessor {
auth_manager.set_external_auth_refresher(Arc::new(ExternalAuthRefreshBridge {
outgoing: outgoing.clone(),
}));
let analytics_events_client =
AnalyticsEventsClient::new(Arc::clone(&config), Arc::clone(&auth_manager));
let thread_manager = Arc::new(ThreadManager::new(
config.as_ref(),
auth_manager.clone(),
Some(analytics_events_client.clone()),
session_source,
CollaborationModesConfig {
default_mode_request_user_input: config
@@ -207,11 +210,6 @@ impl MessageProcessor {
.plugins_manager()
.maybe_start_curated_repo_sync_for_config(&config);
let cloud_requirements = Arc::new(RwLock::new(cloud_requirements));
let analytics_events_client =
AnalyticsEventsClient::new(Arc::clone(&config), Arc::clone(&auth_manager));
thread_manager
.plugins_manager()
.set_analytics_events_client(analytics_events_client.clone());
let codex_message_processor = CodexMessageProcessor::new(CodexMessageProcessorArgs {
auth_manager,
thread_manager: Arc::clone(&thread_manager),

View File

@@ -567,7 +567,7 @@ enabled = false
.await
.expect("custom role should apply");
let plugins_manager = Arc::new(PluginsManager::new(home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(home.path().to_path_buf(), None));
let skills_manager = SkillsManager::new(home.path().to_path_buf(), plugins_manager, true);
let outcome = skills_manager.skills_for_config(&config);
let skill = outcome

View File

@@ -2003,7 +2003,7 @@ async fn session_new_fails_when_zsh_fork_enabled_without_zsh_path() {
let (tx_event, _rx_event) = async_channel::unbounded();
let (agent_status_tx, _agent_status_rx) = watch::channel(AgentStatus::PendingInit);
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone(), None));
let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager)));
let skills_manager = Arc::new(SkillsManager::new(
config.codex_home.clone(),
@@ -2106,7 +2106,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
);
let state = SessionState::new(session_configuration.clone());
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone(), None));
let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager)));
let skills_manager = Arc::new(SkillsManager::new(
config.codex_home.clone(),
@@ -2748,7 +2748,7 @@ pub(crate) async fn make_session_and_context_with_dynamic_tools_and_rx(
);
let state = SessionState::new(session_configuration.clone());
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone(), None));
let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager)));
let skills_manager = Arc::new(SkillsManager::new(
config.codex_home.clone(),

View File

@@ -359,7 +359,7 @@ async fn guardian_subagent_does_not_inherit_parent_exec_policy_rules() {
None,
CollaborationModesConfig::default(),
));
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(config.codex_home.clone(), None));
let skills_manager = Arc::new(SkillsManager::new(
config.codex_home.clone(),
Arc::clone(&plugins_manager),

View File

@@ -173,7 +173,10 @@ pub async fn list_accessible_connectors_from_mcp_tools_with_options_and_status(
});
}
let cache_key = accessible_connectors_cache_key(config, auth.as_ref());
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(config.codex_home.clone())));
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(
config.codex_home.clone(),
None,
)));
let tool_plugin_provenance = mcp_manager.tool_plugin_provenance(config);
if !force_refetch && let Some(cached_connectors) = read_cached_accessible_connectors(&cache_key)
{

View File

@@ -281,7 +281,10 @@ pub async fn collect_mcp_snapshot(config: &Config) -> McpListToolsResponseEvent
config.cli_auth_credentials_store_mode,
);
let auth = auth_manager.auth().await;
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(config.codex_home.clone())));
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(
config.codex_home.clone(),
None,
)));
let mcp_servers = mcp_manager.effective_servers(config, auth.as_ref());
let tool_plugin_provenance = mcp_manager.tool_plugin_provenance(config);
if mcp_servers.is_empty() {

View File

@@ -312,7 +312,10 @@ async fn effective_mcp_servers_include_plugins_without_overriding_user_config()
.set(configured_servers)
.expect("test config should accept MCP servers");
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(config.codex_home.clone())));
let mcp_manager = McpManager::new(Arc::new(PluginsManager::new(
config.codex_home.clone(),
None,
)));
let effective = mcp_manager.effective_servers(&config, None);
let sample = effective.get("sample").expect("user server should exist");

View File

@@ -394,31 +394,19 @@ pub struct PluginsManager {
codex_home: PathBuf,
store: PluginStore,
cache_by_cwd: RwLock<HashMap<PathBuf, PluginLoadOutcome>>,
analytics_events_client: RwLock<Option<AnalyticsEventsClient>>,
analytics_events_client: Option<AnalyticsEventsClient>,
}
impl PluginsManager {
pub fn new(codex_home: PathBuf) -> Self {
pub fn new(
codex_home: PathBuf,
analytics_events_client: Option<AnalyticsEventsClient>,
) -> Self {
Self {
codex_home: codex_home.clone(),
store: PluginStore::new(codex_home),
cache_by_cwd: RwLock::new(HashMap::new()),
analytics_events_client: RwLock::new(None),
}
}
pub fn set_analytics_events_client(&self, analytics_events_client: AnalyticsEventsClient) {
let mut stored_client = match self.analytics_events_client.write() {
Ok(client_guard) => client_guard,
Err(err) => err.into_inner(),
};
*stored_client = Some(analytics_events_client);
}
fn analytics_events_client(&self) -> Option<AnalyticsEventsClient> {
match self.analytics_events_client.read() {
Ok(client) => client.clone(),
Err(err) => err.into_inner().clone(),
analytics_events_client,
}
}
@@ -508,7 +496,7 @@ impl PluginsManager {
.map(|_| ())
.map_err(PluginInstallError::from)?;
if let Some(analytics_events_client) = self.analytics_events_client() {
if let Some(analytics_events_client) = self.analytics_events_client.as_ref() {
analytics_events_client.track_plugin_installed(plugin_telemetry_metadata_from_root(
&result.plugin_id,
result.installed_path.as_path(),
@@ -543,7 +531,7 @@ impl PluginsManager {
.await?;
if let Some(plugin_telemetry) = plugin_telemetry
&& let Some(analytics_events_client) = self.analytics_events_client()
&& let Some(analytics_events_client) = self.analytics_events_client.as_ref()
{
analytics_events_client.track_plugin_uninstalled(plugin_telemetry);
}

View File

@@ -110,7 +110,8 @@ fn load_plugins_from_config(config_toml: &str, codex_home: &Path) -> PluginLoadO
ConfigRequirementsToml::default(),
)
.expect("config layer stack should build");
PluginsManager::new(codex_home.to_path_buf()).plugins_for_layer_stack(codex_home, &stack, false)
PluginsManager::new(codex_home.to_path_buf(), None)
.plugins_for_layer_stack(codex_home, &stack, false)
}
async fn load_config(codex_home: &Path, cwd: &Path) -> crate::config::Config {
@@ -748,7 +749,7 @@ async fn install_plugin_updates_config_with_relative_path_and_plugin_key() {
)
.unwrap();
let result = PluginsManager::new(tmp.path().to_path_buf())
let result = PluginsManager::new(tmp.path().to_path_buf(), None)
.install_plugin(PluginInstallRequest {
plugin_name: "sample-plugin".to_string(),
marketplace_path: AbsolutePathBuf::try_from(
@@ -793,7 +794,7 @@ enabled = true
"#,
);
let manager = PluginsManager::new(tmp.path().to_path_buf());
let manager = PluginsManager::new(tmp.path().to_path_buf(), None);
manager
.uninstall_plugin("sample-plugin@debug".to_string())
.await
@@ -865,7 +866,7 @@ enabled = false
);
let config = load_config(tmp.path(), &repo_root).await;
let marketplaces = PluginsManager::new(tmp.path().to_path_buf())
let marketplaces = PluginsManager::new(tmp.path().to_path_buf(), None)
.list_marketplaces_for_config(&config, &[AbsolutePathBuf::try_from(repo_root).unwrap()])
.unwrap();
@@ -951,7 +952,7 @@ async fn list_marketplaces_includes_curated_repo_marketplace() {
.unwrap();
let config = load_config(tmp.path(), tmp.path()).await;
let marketplaces = PluginsManager::new(tmp.path().to_path_buf())
let marketplaces = PluginsManager::new(tmp.path().to_path_buf(), None)
.list_marketplaces_for_config(&config, &[])
.unwrap();
@@ -1044,7 +1045,7 @@ enabled = false
);
let config = load_config(tmp.path(), &repo_a_root).await;
let marketplaces = PluginsManager::new(tmp.path().to_path_buf())
let marketplaces = PluginsManager::new(tmp.path().to_path_buf(), None)
.list_marketplaces_for_config(
&config,
&[
@@ -1147,7 +1148,7 @@ enabled = true
);
let config = load_config(tmp.path(), &repo_root).await;
let marketplaces = PluginsManager::new(tmp.path().to_path_buf())
let marketplaces = PluginsManager::new(tmp.path().to_path_buf(), None)
.list_marketplaces_for_config(&config, &[AbsolutePathBuf::try_from(repo_root).unwrap()])
.unwrap();
@@ -1231,7 +1232,7 @@ enabled = true
let mut config = load_config(tmp.path(), tmp.path()).await;
config.chatgpt_base_url = format!("{}/backend-api/", server.uri());
let manager = PluginsManager::new(tmp.path().to_path_buf());
let manager = PluginsManager::new(tmp.path().to_path_buf(), None);
let result = manager
.sync_plugins_from_remote(
&config,
@@ -1325,7 +1326,7 @@ enabled = false
let mut config = load_config(tmp.path(), tmp.path()).await;
config.chatgpt_base_url = format!("{}/backend-api/", server.uri());
let manager = PluginsManager::new(tmp.path().to_path_buf());
let manager = PluginsManager::new(tmp.path().to_path_buf(), None);
let result = manager
.sync_plugins_from_remote(
&config,
@@ -1387,7 +1388,7 @@ enabled = false
let mut config = load_config(tmp.path(), tmp.path()).await;
config.chatgpt_base_url = format!("{}/backend-api/", server.uri());
let manager = PluginsManager::new(tmp.path().to_path_buf());
let manager = PluginsManager::new(tmp.path().to_path_buf(), None);
let err = manager
.sync_plugins_from_remote(
&config,
@@ -1475,7 +1476,7 @@ 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(tmp.path().to_path_buf());
let manager = PluginsManager::new(tmp.path().to_path_buf(), None);
let result = manager
.sync_plugins_from_remote(
&config,
@@ -1616,11 +1617,8 @@ fn load_plugins_ignores_project_config_files() {
)
.expect("config layer stack should build");
let outcome = PluginsManager::new(codex_home.path().to_path_buf()).plugins_for_layer_stack(
&project_root,
&stack,
false,
);
let outcome = PluginsManager::new(codex_home.path().to_path_buf(), None)
.plugins_for_layer_stack(&project_root, &stack, false);
assert_eq!(outcome, PluginLoadOutcome::default());
}

View File

@@ -25,7 +25,7 @@ fn new_with_disabled_bundled_skills_removes_stale_cached_system_skills() {
fs::write(stale_system_skill_dir.join("SKILL.md"), "# stale\n")
.expect("write stale system skill");
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf(), None));
let _skills_manager =
SkillsManager::new(codex_home.path().to_path_buf(), plugins_manager, false);
@@ -50,7 +50,7 @@ async fn skills_for_config_seeds_cache_by_cwd() {
.await
.expect("defaults for test should always succeed");
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf(), None));
let skills_manager = SkillsManager::new(codex_home.path().to_path_buf(), plugins_manager, true);
write_user_skill(&codex_home, "a", "skill-a", "from a");
@@ -84,7 +84,7 @@ async fn skills_for_cwd_reuses_cached_entry_even_when_entry_has_extra_roots() {
.await
.expect("defaults for test should always succeed");
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf(), None));
let skills_manager = SkillsManager::new(codex_home.path().to_path_buf(), plugins_manager, true);
let _ = skills_manager.skills_for_config(&config);
@@ -145,7 +145,7 @@ async fn skills_for_config_excludes_bundled_skills_when_disabled_in_config() {
.await
.expect("load config");
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf(), None));
let skills_manager = SkillsManager::new(
codex_home.path().to_path_buf(),
plugins_manager,
@@ -193,7 +193,7 @@ async fn skills_for_cwd_with_extra_roots_only_refreshes_on_force_reload() {
.await
.expect("defaults for test should always succeed");
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.path().to_path_buf(), None));
let skills_manager = SkillsManager::new(codex_home.path().to_path_buf(), plugins_manager, true);
let _ = skills_manager.skills_for_config(&config);

View File

@@ -1,3 +1,4 @@
use crate::AnalyticsEventsClient;
use crate::AuthManager;
use crate::CodexAuth;
use crate::ModelProviderInfo;
@@ -164,12 +165,16 @@ impl ThreadManager {
pub fn new(
config: &Config,
auth_manager: Arc<AuthManager>,
analytics_events_client: Option<AnalyticsEventsClient>,
session_source: SessionSource,
collaboration_modes_config: CollaborationModesConfig,
) -> Self {
let codex_home = config.codex_home.clone();
let (thread_created_tx, _) = broadcast::channel(THREAD_CREATED_CHANNEL_CAPACITY);
let plugins_manager = Arc::new(PluginsManager::new(codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(
codex_home.clone(),
analytics_events_client,
));
let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager)));
let skills_manager = Arc::new(SkillsManager::new(
codex_home.clone(),
@@ -229,7 +234,7 @@ impl ThreadManager {
set_thread_manager_test_mode_for_tests(true);
let auth_manager = AuthManager::from_auth_for_testing(auth);
let (thread_created_tx, _) = broadcast::channel(THREAD_CREATED_CHANNEL_CAPACITY);
let plugins_manager = Arc::new(PluginsManager::new(codex_home.clone()));
let plugins_manager = Arc::new(PluginsManager::new(codex_home.clone(), None));
let mcp_manager = Arc::new(McpManager::new(Arc::clone(&plugins_manager)));
let skills_manager = Arc::new(SkillsManager::new(
codex_home.clone(),

View File

@@ -183,6 +183,7 @@ impl TestCodexBuilder {
ThreadManager::new(
&config,
codex_core::test_support::auth_manager_from_auth(auth.clone()),
None,
SessionSource::Exec,
CollaborationModesConfig::default(),
)

View File

@@ -818,6 +818,7 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() {
let thread_manager = ThreadManager::new(
&config,
auth_manager,
None,
SessionSource::Exec,
CollaborationModesConfig {
default_mode_request_user_input: config