mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
[codex] Clarify plugin load and runtime capability stages (#28472)
## Summary Plugin loading and auth projection both previously produced `PluginLoadOutcome`. That made an unfiltered load result look like runtime-ready capabilities and generated capability summaries before auth routing had run. This change keeps loaded plugin records in the cache, applies the current auth policy in `PluginsManager`, and only then builds `PluginLoadOutcome` and its summaries. Auth changes still reuse the cached disk load and re-resolve apps and MCP servers without reloading plugins. The updated tests cover cached auth changes and verify that capability summaries match the effective app/MCP surface. ## Testing - `just test -p codex-core-plugins` - `just test -p codex-plugin` - `just fix -p codex-core-plugins`
This commit is contained in:
committed by
GitHub
Unverified
parent
ef8eb8bdd9
commit
de1f77bfdd
@@ -359,7 +359,7 @@ enabled = true
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn plugin_auth_projection_reprojects_cached_outcome_when_auth_changes() {
|
||||
async fn plugin_auth_projection_reprojects_cached_plugins_when_auth_changes() {
|
||||
let codex_home = TempDir::new().unwrap();
|
||||
write_auth_projection_plugin(codex_home.path(), "sample", /*include_app*/ true);
|
||||
write_auth_projection_plugin(codex_home.path(), "docs", /*include_app*/ false);
|
||||
@@ -379,6 +379,27 @@ async fn plugin_auth_projection_reprojects_cached_outcome_when_auth_changes() {
|
||||
chatgpt_outcome.effective_apps(),
|
||||
vec![AppConnectorId("connector_sample".to_string())]
|
||||
);
|
||||
assert_eq!(
|
||||
chatgpt_outcome.capability_summaries(),
|
||||
&[
|
||||
PluginCapabilitySummary {
|
||||
config_name: "docs@test".to_string(),
|
||||
display_name: "docs".to_string(),
|
||||
description: None,
|
||||
has_skills: false,
|
||||
mcp_server_names: vec!["docs".to_string()],
|
||||
app_connector_ids: Vec::new(),
|
||||
},
|
||||
PluginCapabilitySummary {
|
||||
config_name: "sample@test".to_string(),
|
||||
display_name: "sample".to_string(),
|
||||
description: None,
|
||||
has_skills: false,
|
||||
mcp_server_names: Vec::new(),
|
||||
app_connector_ids: vec![AppConnectorId("connector_sample".to_string())],
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
assert!(manager.set_auth_mode(Some(AuthMode::ApiKey)));
|
||||
let api_key_outcome = manager.plugins_for_config(&config).await;
|
||||
@@ -388,6 +409,27 @@ async fn plugin_auth_projection_reprojects_cached_outcome_when_auth_changes() {
|
||||
vec!["docs".to_string(), "sample".to_string()]
|
||||
);
|
||||
assert!(api_key_outcome.effective_apps().is_empty());
|
||||
assert_eq!(
|
||||
api_key_outcome.capability_summaries(),
|
||||
&[
|
||||
PluginCapabilitySummary {
|
||||
config_name: "docs@test".to_string(),
|
||||
display_name: "docs".to_string(),
|
||||
description: None,
|
||||
has_skills: false,
|
||||
mcp_server_names: vec!["docs".to_string()],
|
||||
app_connector_ids: Vec::new(),
|
||||
},
|
||||
PluginCapabilitySummary {
|
||||
config_name: "sample@test".to_string(),
|
||||
display_name: "sample".to_string(),
|
||||
description: None,
|
||||
has_skills: false,
|
||||
mcp_server_names: vec!["sample".to_string()],
|
||||
app_connector_ids: Vec::new(),
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
fn write_plugin_with_version(
|
||||
@@ -1781,7 +1823,7 @@ async fn plugin_cache_ignores_unrelated_session_overrides() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_cache_invalidation_rejects_stale_load_completion() {
|
||||
fn loaded_plugins_cache_invalidation_rejects_stale_load_completion() {
|
||||
let codex_home = TempDir::new().unwrap();
|
||||
let manager = PluginsManager::new(codex_home.path().to_path_buf());
|
||||
let cache_key = PluginLoadCacheKey {
|
||||
@@ -1789,16 +1831,12 @@ fn plugin_cache_invalidation_rejects_stale_load_completion() {
|
||||
skill_config_rules: SkillConfigRules::default(),
|
||||
remote_plugin_enabled: false,
|
||||
};
|
||||
let stale_generation = manager.enabled_outcome_cache_generation();
|
||||
let stale_generation = manager.loaded_plugins_cache_generation();
|
||||
|
||||
manager.clear_enabled_outcome_cache();
|
||||
manager.cache_enabled_outcome_if_current(
|
||||
stale_generation,
|
||||
cache_key.clone(),
|
||||
PluginLoadOutcome::default(),
|
||||
);
|
||||
manager.clear_loaded_plugins_cache();
|
||||
manager.cache_loaded_plugins_if_current(stale_generation, cache_key.clone(), Vec::new());
|
||||
|
||||
assert_eq!(manager.cached_enabled_outcome(&cache_key), None);
|
||||
assert_eq!(manager.cached_loaded_plugins(&cache_key), None);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -4265,7 +4303,7 @@ async fn load_plugins_ignores_project_config_files() {
|
||||
)
|
||||
.expect("config layer stack should build");
|
||||
|
||||
let outcome = load_plugins_from_layer_stack(
|
||||
let plugins = load_plugins_from_layer_stack(
|
||||
&stack,
|
||||
std::collections::HashMap::new(),
|
||||
&PluginStore::new(codex_home.path().to_path_buf()),
|
||||
@@ -4274,7 +4312,7 @@ async fn load_plugins_ignores_project_config_files() {
|
||||
)
|
||||
.await;
|
||||
|
||||
assert_eq!(outcome, PluginLoadOutcome::default());
|
||||
assert_eq!(plugins, Vec::new());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
Reference in New Issue
Block a user