mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Move plugin out of core. (#20348)
This commit is contained in:
@@ -2,9 +2,9 @@ use super::*;
|
||||
use crate::SkillsManager;
|
||||
use crate::config::CONFIG_TOML_FILE;
|
||||
use crate::config::ConfigBuilder;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::skills_load_input_from_config;
|
||||
use codex_config::ConfigLayerStackOrdering;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_protocol::config_types::ReasoningSummary;
|
||||
use codex_protocol::config_types::Verbosity;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
@@ -655,7 +655,8 @@ enabled = false
|
||||
let plugins_manager = Arc::new(PluginsManager::new(home.path().to_path_buf()));
|
||||
let skills_manager =
|
||||
SkillsManager::new(home.path().abs(), /*bundled_skills_enabled*/ true);
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&config).await;
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&plugins_input).await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input = skills_load_input_from_config(&config, effective_skill_roots);
|
||||
let outcome = skills_manager
|
||||
|
||||
@@ -4,7 +4,6 @@ use crate::config::ThreadStoreConfig;
|
||||
use crate::config::edit::ConfigEdit;
|
||||
use crate::config::edit::ConfigEditsBuilder;
|
||||
use crate::config::edit::apply_blocking;
|
||||
use crate::plugins::PluginsManager;
|
||||
use assert_matches::assert_matches;
|
||||
use codex_config::CONFIG_TOML_FILE;
|
||||
use codex_config::RequirementSource;
|
||||
@@ -53,6 +52,7 @@ use codex_config::types::TuiKeymap;
|
||||
use codex_config::types::TuiNotificationSettings;
|
||||
use codex_config::types::WindowsSandboxModeToml;
|
||||
use codex_config::types::WindowsToml;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
use codex_features::Feature;
|
||||
use codex_features::FeaturesToml;
|
||||
|
||||
@@ -54,6 +54,7 @@ use codex_config::types::TuiKeymap;
|
||||
use codex_config::types::TuiNotificationSettings;
|
||||
use codex_config::types::UriBasedFileOpener;
|
||||
use codex_config::types::WindowsSandboxModeToml;
|
||||
use codex_core_plugins::PluginsConfigInput;
|
||||
use codex_exec_server::ExecutorFileSystem;
|
||||
use codex_exec_server::LOCAL_FS;
|
||||
use codex_features::AppsMcpPathOverrideConfigToml;
|
||||
@@ -995,11 +996,23 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the plugin-manager input from the effective config.
|
||||
pub fn plugins_config_input(&self) -> PluginsConfigInput {
|
||||
PluginsConfigInput::new(
|
||||
self.config_layer_stack.clone(),
|
||||
self.features.enabled(Feature::Plugins),
|
||||
self.features.enabled(Feature::RemotePlugin),
|
||||
self.features.enabled(Feature::PluginHooks),
|
||||
self.chatgpt_base_url.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn to_mcp_config(
|
||||
&self,
|
||||
plugins_manager: &crate::plugins::PluginsManager,
|
||||
plugins_manager: &codex_core_plugins::PluginsManager,
|
||||
) -> McpConfig {
|
||||
let loaded_plugins = plugins_manager.plugins_for_config(self).await;
|
||||
let plugins_input = self.plugins_config_input();
|
||||
let loaded_plugins = plugins_manager.plugins_for_config(&plugins_input).await;
|
||||
let mut configured_mcp_servers = self.mcp_servers.get().clone();
|
||||
for plugin in loaded_plugins
|
||||
.plugins()
|
||||
|
||||
@@ -26,13 +26,13 @@ use tracing::warn;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::mcp::McpManager;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::plugins::list_tool_suggest_discoverable_plugins;
|
||||
use crate::session::INITIAL_SUBMIT_ID;
|
||||
use codex_config::AppsRequirementsToml;
|
||||
use codex_config::types::AppToolApproval;
|
||||
use codex_config::types::AppsConfigToml;
|
||||
use codex_config::types::ToolSuggestDiscoverableType;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_features::Feature;
|
||||
use codex_login::AuthManager;
|
||||
use codex_login::CodexAuth;
|
||||
@@ -403,8 +403,9 @@ fn write_cached_accessible_connectors(
|
||||
}
|
||||
|
||||
async fn tool_suggest_connector_ids(config: &Config) -> HashSet<String> {
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let mut connector_ids = PluginsManager::new(config.codex_home.to_path_buf())
|
||||
.plugins_for_config(config)
|
||||
.plugins_for_config(&plugins_input)
|
||||
.await
|
||||
.capability_summaries()
|
||||
.iter()
|
||||
|
||||
@@ -67,7 +67,7 @@ pub use message_history::history_metadata as message_history_metadata;
|
||||
pub use message_history::lookup as lookup_message_history_entry;
|
||||
pub use utils::path_utils;
|
||||
pub mod personality_migration;
|
||||
pub mod plugins;
|
||||
pub(crate) mod plugins;
|
||||
#[doc(hidden)]
|
||||
pub(crate) mod prompt_debug;
|
||||
#[doc(hidden)]
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::plugins::PluginsManager;
|
||||
use codex_config::McpServerConfig;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_login::CodexAuth;
|
||||
use codex_mcp::ToolPluginProvenance;
|
||||
use codex_mcp::configured_mcp_servers;
|
||||
|
||||
@@ -804,7 +804,7 @@ async fn custom_mcp_tool_approval_mode(
|
||||
|
||||
sess.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(turn_context.config.as_ref())
|
||||
.plugins_for_config(&turn_context.config.plugins_config_input())
|
||||
.await
|
||||
.plugins()
|
||||
.iter()
|
||||
@@ -1853,7 +1853,7 @@ async fn persist_non_app_mcp_tool_approval(
|
||||
let plugin_config_name = sess
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(config)
|
||||
.plugins_for_config(&config.plugins_config_input())
|
||||
.await
|
||||
.plugins()
|
||||
.iter()
|
||||
|
||||
@@ -1660,7 +1660,7 @@ enabled = true
|
||||
session
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&initial_config)
|
||||
.plugins_for_config(&initial_config.plugins_config_input())
|
||||
.await;
|
||||
std::fs::write(
|
||||
codex_home.join(CONFIG_TOML_FILE),
|
||||
|
||||
@@ -3,11 +3,11 @@ use std::collections::HashSet;
|
||||
use tracing::warn;
|
||||
|
||||
use super::PluginCapabilitySummary;
|
||||
use super::PluginsManager;
|
||||
use crate::config::Config;
|
||||
use codex_config::types::ToolSuggestDiscoverableType;
|
||||
use codex_core_plugins::OPENAI_BUNDLED_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_core_plugins::TOOL_SUGGEST_DISCOVERABLE_PLUGIN_ALLOWLIST;
|
||||
use codex_features::Feature;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
@@ -25,6 +25,7 @@ pub(crate) async fn list_tool_suggest_discoverable_plugins(
|
||||
}
|
||||
|
||||
let plugins_manager = PluginsManager::new(config.codex_home.to_path_buf());
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let configured_plugin_ids = config
|
||||
.tool_suggest
|
||||
.discoverables
|
||||
@@ -40,7 +41,7 @@ pub(crate) async fn list_tool_suggest_discoverable_plugins(
|
||||
.map(|disabled_tool| disabled_tool.id.as_str())
|
||||
.collect::<HashSet<_>>();
|
||||
let marketplaces = plugins_manager
|
||||
.list_marketplaces_for_config(config, &[])
|
||||
.list_marketplaces_for_config(&plugins_input, &[])
|
||||
.context("failed to list plugin marketplaces for tool suggestions")?
|
||||
.marketplaces;
|
||||
let mut discoverable_plugins = Vec::<DiscoverablePluginInfo>::new();
|
||||
@@ -62,7 +63,11 @@ pub(crate) async fn list_tool_suggest_discoverable_plugins(
|
||||
let plugin_id = plugin.id.clone();
|
||||
|
||||
match plugins_manager
|
||||
.read_plugin_detail_for_marketplace_plugin(config, &marketplace_name, plugin)
|
||||
.read_plugin_detail_for_marketplace_plugin(
|
||||
&plugins_input,
|
||||
&marketplace_name,
|
||||
plugin,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(plugin) => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::*;
|
||||
use crate::plugins::PluginInstallRequest;
|
||||
use crate::plugins::test_support::load_plugins_config;
|
||||
use crate::plugins::test_support::write_curated_plugin;
|
||||
use crate::plugins::test_support::write_curated_plugin_sha;
|
||||
use crate::plugins::test_support::write_file;
|
||||
use crate::plugins::test_support::write_openai_curated_marketplace;
|
||||
use crate::plugins::test_support::write_plugins_feature_config;
|
||||
use codex_core_plugins::PluginInstallRequest;
|
||||
use codex_core_plugins::startup_sync::curated_plugins_repo_path;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,43 +1,14 @@
|
||||
use codex_config::types::McpServerConfig;
|
||||
|
||||
mod discoverable;
|
||||
mod injection;
|
||||
mod manager;
|
||||
mod mentions;
|
||||
mod render;
|
||||
mod startup_sync;
|
||||
#[cfg(test)]
|
||||
pub(crate) mod test_support;
|
||||
|
||||
pub use codex_core_plugins::marketplace_upgrade::ConfiguredMarketplaceUpgradeError as PluginMarketplaceUpgradeError;
|
||||
pub use codex_core_plugins::marketplace_upgrade::ConfiguredMarketplaceUpgradeOutcome as PluginMarketplaceUpgradeOutcome;
|
||||
pub use codex_plugin::AppConnectorId;
|
||||
pub use codex_plugin::EffectiveSkillRoots;
|
||||
pub use codex_plugin::PluginCapabilitySummary;
|
||||
pub use codex_plugin::PluginId;
|
||||
pub use codex_plugin::PluginIdError;
|
||||
pub use codex_plugin::PluginTelemetryMetadata;
|
||||
pub use codex_plugin::validate_plugin_segment;
|
||||
|
||||
pub type LoadedPlugin = codex_plugin::LoadedPlugin<McpServerConfig>;
|
||||
pub type PluginLoadOutcome = codex_plugin::PluginLoadOutcome<McpServerConfig>;
|
||||
pub(crate) use codex_plugin::PluginCapabilitySummary;
|
||||
|
||||
pub(crate) use discoverable::list_tool_suggest_discoverable_plugins;
|
||||
pub(crate) use injection::build_plugin_injections;
|
||||
pub use manager::ConfiguredMarketplace;
|
||||
pub use manager::ConfiguredMarketplaceListOutcome;
|
||||
pub use manager::ConfiguredMarketplacePlugin;
|
||||
pub use manager::PluginDetail;
|
||||
pub use manager::PluginDetailsUnavailableReason;
|
||||
pub use manager::PluginInstallError;
|
||||
pub use manager::PluginInstallOutcome;
|
||||
pub use manager::PluginInstallRequest;
|
||||
pub use manager::PluginReadOutcome;
|
||||
pub use manager::PluginReadRequest;
|
||||
pub use manager::PluginRemoteSyncError;
|
||||
pub use manager::PluginUninstallError;
|
||||
pub use manager::PluginsManager;
|
||||
pub use manager::RemotePluginSyncResult;
|
||||
pub(crate) use render::render_explicit_plugin_instructions;
|
||||
|
||||
pub(crate) use mentions::build_connector_slug_counts;
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::plugins::PluginsManager;
|
||||
use codex_core_plugins::startup_sync::has_local_curated_plugins_snapshot;
|
||||
use codex_login::AuthManager;
|
||||
use tracing::info;
|
||||
use tracing::warn;
|
||||
|
||||
const STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE: &str = ".tmp/app-server-remote-plugin-sync-v1";
|
||||
const STARTUP_REMOTE_PLUGIN_SYNC_PREREQUISITE_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
|
||||
pub(crate) fn start_startup_remote_plugin_sync_once(
|
||||
manager: Arc<PluginsManager>,
|
||||
codex_home: PathBuf,
|
||||
config: Config,
|
||||
auth_manager: Arc<AuthManager>,
|
||||
) {
|
||||
let marker_path = startup_remote_plugin_sync_marker_path(codex_home.as_path());
|
||||
if marker_path.is_file() {
|
||||
return;
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
if marker_path.is_file() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !wait_for_startup_remote_plugin_sync_prerequisites(codex_home.as_path()).await {
|
||||
warn!(
|
||||
codex_home = %codex_home.display(),
|
||||
"skipping startup remote plugin sync because curated marketplace is not ready"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let auth = auth_manager.auth().await;
|
||||
match manager
|
||||
.sync_plugins_from_remote(&config, auth.as_ref(), /*additive_only*/ true)
|
||||
.await
|
||||
{
|
||||
Ok(sync_result) => {
|
||||
info!(
|
||||
installed_plugin_ids = ?sync_result.installed_plugin_ids,
|
||||
enabled_plugin_ids = ?sync_result.enabled_plugin_ids,
|
||||
disabled_plugin_ids = ?sync_result.disabled_plugin_ids,
|
||||
uninstalled_plugin_ids = ?sync_result.uninstalled_plugin_ids,
|
||||
"completed startup remote plugin sync"
|
||||
);
|
||||
if let Err(err) =
|
||||
write_startup_remote_plugin_sync_marker(codex_home.as_path()).await
|
||||
{
|
||||
warn!(
|
||||
error = %err,
|
||||
path = %marker_path.display(),
|
||||
"failed to persist startup remote plugin sync marker"
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!(
|
||||
error = %err,
|
||||
"startup remote plugin sync failed; will retry on next app-server start"
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn startup_remote_plugin_sync_marker_path(codex_home: &Path) -> PathBuf {
|
||||
codex_home.join(STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE)
|
||||
}
|
||||
|
||||
async fn wait_for_startup_remote_plugin_sync_prerequisites(codex_home: &Path) -> bool {
|
||||
let deadline = tokio::time::Instant::now() + STARTUP_REMOTE_PLUGIN_SYNC_PREREQUISITE_TIMEOUT;
|
||||
loop {
|
||||
if has_local_curated_plugins_snapshot(codex_home) {
|
||||
return true;
|
||||
}
|
||||
if tokio::time::Instant::now() >= deadline {
|
||||
return false;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn write_startup_remote_plugin_sync_marker(codex_home: &Path) -> std::io::Result<()> {
|
||||
let marker_path = startup_remote_plugin_sync_marker_path(codex_home);
|
||||
if let Some(parent) = marker_path.parent() {
|
||||
tokio::fs::create_dir_all(parent).await?;
|
||||
}
|
||||
tokio::fs::write(marker_path, b"ok\n").await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "startup_sync_tests.rs"]
|
||||
mod tests;
|
||||
@@ -1,90 +0,0 @@
|
||||
use super::*;
|
||||
use crate::config::CONFIG_TOML_FILE;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::plugins::test_support::TEST_CURATED_PLUGIN_CACHE_VERSION;
|
||||
use crate::plugins::test_support::write_curated_plugin_sha;
|
||||
use crate::plugins::test_support::write_file;
|
||||
use crate::plugins::test_support::write_openai_curated_marketplace;
|
||||
use codex_core_plugins::startup_sync::curated_plugins_repo_path;
|
||||
use codex_login::AuthManager;
|
||||
use codex_login::CodexAuth;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tempfile::tempdir;
|
||||
use wiremock::Mock;
|
||||
use wiremock::MockServer;
|
||||
use wiremock::ResponseTemplate;
|
||||
use wiremock::matchers::header;
|
||||
use wiremock::matchers::method;
|
||||
use wiremock::matchers::path;
|
||||
|
||||
#[tokio::test]
|
||||
async fn startup_remote_plugin_sync_writes_marker_and_reconciles_state() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let curated_root = curated_plugins_repo_path(tmp.path());
|
||||
write_openai_curated_marketplace(&curated_root, &["linear"]);
|
||||
write_curated_plugin_sha(tmp.path());
|
||||
write_file(
|
||||
&tmp.path().join(CONFIG_TOML_FILE),
|
||||
r#"[features]
|
||||
plugins = true
|
||||
|
||||
[plugins."linear@openai-curated"]
|
||||
enabled = false
|
||||
"#,
|
||||
);
|
||||
|
||||
let server = MockServer::start().await;
|
||||
Mock::given(method("GET"))
|
||||
.and(path("/backend-api/plugins/list"))
|
||||
.and(header("authorization", "Bearer Access Token"))
|
||||
.and(header("chatgpt-account-id", "account_id"))
|
||||
.respond_with(ResponseTemplate::new(200).set_body_string(
|
||||
r#"[
|
||||
{"id":"1","name":"linear","marketplace_name":"openai-curated","version":"1.0.0","enabled":true}
|
||||
]"#,
|
||||
))
|
||||
.mount(&server)
|
||||
.await;
|
||||
|
||||
let mut config = crate::plugins::test_support::load_plugins_config(tmp.path()).await;
|
||||
config.chatgpt_base_url = format!("{}/backend-api/", server.uri());
|
||||
let manager = Arc::new(PluginsManager::new(tmp.path().to_path_buf()));
|
||||
let auth_manager =
|
||||
AuthManager::from_auth_for_testing(CodexAuth::create_dummy_chatgpt_auth_for_testing());
|
||||
|
||||
start_startup_remote_plugin_sync_once(
|
||||
Arc::clone(&manager),
|
||||
tmp.path().to_path_buf(),
|
||||
config,
|
||||
auth_manager,
|
||||
);
|
||||
|
||||
let marker_path = tmp.path().join(STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE);
|
||||
tokio::time::timeout(Duration::from_secs(5), async {
|
||||
loop {
|
||||
if marker_path.is_file() {
|
||||
break;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_millis(10)).await;
|
||||
}
|
||||
})
|
||||
.await
|
||||
.expect("marker should be written");
|
||||
|
||||
assert!(
|
||||
tmp.path()
|
||||
.join(format!(
|
||||
"plugins/cache/openai-curated/linear/{TEST_CURATED_PLUGIN_CACHE_VERSION}"
|
||||
))
|
||||
.is_dir()
|
||||
);
|
||||
let config =
|
||||
std::fs::read_to_string(tmp.path().join(CONFIG_TOML_FILE)).expect("config should exist");
|
||||
assert!(config.contains(r#"[plugins."linear@openai-curated"]"#));
|
||||
assert!(config.contains("enabled = true"));
|
||||
|
||||
let marker_contents = std::fs::read_to_string(marker_path).expect("marker should be readable");
|
||||
assert_eq!(marker_contents, "ok\n");
|
||||
}
|
||||
@@ -6,7 +6,6 @@ use std::path::Path;
|
||||
use codex_core_plugins::OPENAI_CURATED_MARKETPLACE_NAME;
|
||||
|
||||
pub(crate) const TEST_CURATED_PLUGIN_SHA: &str = "0123456789abcdef0123456789abcdef01234567";
|
||||
pub(crate) const TEST_CURATED_PLUGIN_CACHE_VERSION: &str = "01234567";
|
||||
|
||||
pub(crate) fn write_file(path: &Path, contents: &str) {
|
||||
fs::create_dir_all(path.parent().expect("file should have a parent")).unwrap();
|
||||
|
||||
@@ -620,8 +620,9 @@ pub async fn list_skills(sess: &Session, sub_id: String, cwds: Vec<PathBuf>, for
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let effective_skill_roots = plugins_manager
|
||||
.effective_skill_roots_for_layer_stack(&config_layer_stack, &config)
|
||||
.effective_skill_roots_for_layer_stack(&config_layer_stack, &plugins_input)
|
||||
.await;
|
||||
let skills_input = crate::SkillsLoadInput::new(
|
||||
cwd_abs.clone(),
|
||||
|
||||
@@ -274,7 +274,6 @@ use crate::exec_policy::ExecPolicyUpdateError;
|
||||
use crate::guardian::GuardianReviewSessionManager;
|
||||
use crate::mcp::McpManager;
|
||||
use crate::network_policy_decision::execpolicy_network_rule_amendment;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::rollout::map_session_init_error;
|
||||
use crate::session_startup_prewarm::SessionStartupPrewarmHandle;
|
||||
use crate::shell;
|
||||
@@ -301,6 +300,7 @@ use crate::turn_timing::TurnTimingState;
|
||||
use crate::turn_timing::record_turn_ttfm_metric;
|
||||
use crate::unified_exec::UnifiedExecProcessManager;
|
||||
use crate::windows_sandbox::WindowsSandboxLevelExt;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_git_utils::get_git_repo_root;
|
||||
use codex_mcp::compute_auth_statuses;
|
||||
use codex_mcp::with_codex_apps_mcp;
|
||||
@@ -475,7 +475,8 @@ impl Codex {
|
||||
let fs = environment
|
||||
.as_ref()
|
||||
.map(|environment| environment.get_filesystem());
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&config).await;
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&plugins_input).await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input = skills_load_input_from_config(&config, effective_skill_roots);
|
||||
let loaded_skills = skills_manager.skills_for_config(&skills_input, fs).await;
|
||||
@@ -2666,7 +2667,7 @@ impl Session {
|
||||
let loaded_plugins = self
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&turn_context.config)
|
||||
.plugins_for_config(&turn_context.config.plugins_config_input())
|
||||
.await;
|
||||
if let Some(plugin_instructions) =
|
||||
AvailablePluginsInstructions::from_plugins(loaded_plugins.capability_summaries())
|
||||
@@ -3362,7 +3363,8 @@ async fn build_hooks_for_config(
|
||||
let _ = hook_shell_argv.pop();
|
||||
let plugin_hooks_enabled = config.features.enabled(Feature::PluginHooks);
|
||||
let (plugin_hook_sources, plugin_hook_load_warnings) = if plugin_hooks_enabled {
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(config).await;
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&plugins_input).await;
|
||||
(
|
||||
plugin_outcome.effective_plugin_hook_sources(),
|
||||
plugin_outcome.effective_plugin_hook_warnings(),
|
||||
|
||||
@@ -3558,7 +3558,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
|
||||
|
||||
let plugin_outcome = services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&per_turn_config)
|
||||
.plugins_for_config(&per_turn_config.plugins_config_input())
|
||||
.await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input =
|
||||
@@ -4987,7 +4987,7 @@ where
|
||||
|
||||
let plugin_outcome = services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&per_turn_config)
|
||||
.plugins_for_config(&per_turn_config.plugins_config_input())
|
||||
.await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input =
|
||||
|
||||
@@ -170,7 +170,7 @@ pub(crate) async fn run_turn(
|
||||
let loaded_plugins = sess
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&turn_context.config)
|
||||
.plugins_for_config(&turn_context.config.plugins_config_input())
|
||||
.await;
|
||||
// Structured plugin:// mentions are resolved from the current session's
|
||||
// enabled plugins, then converted into turn-scoped guidance below.
|
||||
@@ -1124,7 +1124,7 @@ pub(crate) async fn built_tools(
|
||||
let loaded_plugins = sess
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&turn_context.config)
|
||||
.plugins_for_config(&turn_context.config.plugins_config_input())
|
||||
.await;
|
||||
|
||||
let mut effective_explicitly_enabled_connectors = explicitly_enabled_connectors.clone();
|
||||
|
||||
@@ -696,7 +696,7 @@ impl Session {
|
||||
let plugin_outcome = self
|
||||
.services
|
||||
.plugins_manager
|
||||
.plugins_for_config(&per_turn_config)
|
||||
.plugins_for_config(&per_turn_config.plugins_config_input())
|
||||
.await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input = skills_load_input_from_config(&per_turn_config, effective_skill_roots);
|
||||
|
||||
@@ -16,8 +16,8 @@ use crate::file_watcher::Receiver;
|
||||
use crate::file_watcher::ThrottledWatchReceiver;
|
||||
use crate::file_watcher::WatchPath;
|
||||
use crate::file_watcher::WatchRegistration;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::skills_load_input_from_config;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
|
||||
#[cfg(not(test))]
|
||||
const WATCHER_THROTTLE_INTERVAL: Duration = Duration::from_secs(10);
|
||||
@@ -61,7 +61,8 @@ impl SkillsWatcher {
|
||||
plugins_manager: &PluginsManager,
|
||||
fs: Option<Arc<dyn codex_exec_server::ExecutorFileSystem>>,
|
||||
) -> WatchRegistration {
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(config).await;
|
||||
let plugins_input = config.plugins_config_input();
|
||||
let plugin_outcome = plugins_manager.plugins_for_config(&plugins_input).await;
|
||||
let effective_skill_roots = plugin_outcome.effective_skill_roots();
|
||||
let skills_input = skills_load_input_from_config(config, effective_skill_roots);
|
||||
let roots = skills_manager
|
||||
|
||||
@@ -9,7 +9,6 @@ use crate::exec_policy::ExecPolicyManager;
|
||||
use crate::guardian::GuardianRejection;
|
||||
use crate::guardian::GuardianRejectionCircuitBreaker;
|
||||
use crate::mcp::McpManager;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::skills_watcher::SkillsWatcher;
|
||||
use crate::tools::code_mode::CodeModeService;
|
||||
use crate::tools::network_approval::NetworkApprovalService;
|
||||
@@ -17,6 +16,7 @@ use crate::tools::sandboxing::ApprovalStore;
|
||||
use crate::unified_exec::UnifiedExecProcessManager;
|
||||
use arc_swap::ArcSwap;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_hooks::Hooks;
|
||||
use codex_login::AuthManager;
|
||||
|
||||
@@ -8,7 +8,6 @@ use crate::environment_selection::selected_primary_environment;
|
||||
use crate::environment_selection::validate_environment_selections;
|
||||
use crate::file_watcher::FileWatcher;
|
||||
use crate::mcp::McpManager;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::rollout::RolloutRecorder;
|
||||
use crate::rollout::truncation;
|
||||
use crate::session::Codex;
|
||||
@@ -23,6 +22,7 @@ use crate::tasks::interrupted_turn_history_marker;
|
||||
use codex_analytics::AnalyticsEventsClient;
|
||||
use codex_app_server_protocol::ThreadHistoryBuilder;
|
||||
use codex_app_server_protocol::TurnStatus;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_exec_server::EnvironmentManager;
|
||||
use codex_login::AuthManager;
|
||||
use codex_login::CodexAuth;
|
||||
|
||||
@@ -314,10 +314,11 @@ async fn refresh_missing_suggested_connectors(
|
||||
fn verified_plugin_suggestion_completed(
|
||||
tool_id: &str,
|
||||
config: &crate::config::Config,
|
||||
plugins_manager: &crate::plugins::PluginsManager,
|
||||
plugins_manager: &codex_core_plugins::PluginsManager,
|
||||
) -> bool {
|
||||
let plugins_input = config.plugins_config_input();
|
||||
plugins_manager
|
||||
.list_marketplaces_for_config(config, &[])
|
||||
.list_marketplaces_for_config(&plugins_input, &[])
|
||||
.ok()
|
||||
.into_iter()
|
||||
.flat_map(|outcome| outcome.marketplaces)
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use super::*;
|
||||
use crate::plugins::PluginInstallRequest;
|
||||
use crate::plugins::PluginsManager;
|
||||
use crate::plugins::test_support::load_plugins_config;
|
||||
use crate::plugins::test_support::write_curated_plugin_sha;
|
||||
use crate::plugins::test_support::write_openai_curated_marketplace;
|
||||
@@ -11,6 +9,8 @@ use codex_config::types::ToolSuggestConfig;
|
||||
use codex_config::types::ToolSuggestDisabledTool;
|
||||
use codex_config::types::ToolSuggestDiscoverable;
|
||||
use codex_config::types::ToolSuggestDiscoverableType;
|
||||
use codex_core_plugins::PluginInstallRequest;
|
||||
use codex_core_plugins::PluginsManager;
|
||||
use codex_core_plugins::startup_sync::curated_plugins_repo_path;
|
||||
use codex_rmcp_client::ElicitationResponse;
|
||||
use codex_tools::DiscoverablePluginInfo;
|
||||
|
||||
Reference in New Issue
Block a user