@@ -182,6 +182,7 @@ use crate::mentions::build_skill_name_counts;
182182use crate :: mentions:: collect_explicit_app_ids;
183183use crate :: mentions:: collect_tool_mentions_from_messages;
184184use crate :: network_policy_decision:: execpolicy_network_rule_amendment;
185+ use crate :: plugins:: PluginsManager ;
185186use crate :: project_doc:: get_user_instructions;
186187use crate :: protocol:: AgentMessageContentDeltaEvent ;
187188use crate :: protocol:: AgentReasoningSectionBreakEvent ;
@@ -315,6 +316,7 @@ impl Codex {
315316 auth_manager : Arc < AuthManager > ,
316317 models_manager : Arc < ModelsManager > ,
317318 skills_manager : Arc < SkillsManager > ,
319+ plugins_manager : Arc < PluginsManager > ,
318320 file_watcher : Arc < FileWatcher > ,
319321 conversation_history : InitialHistory ,
320322 session_source : SessionSource ,
@@ -326,6 +328,7 @@ impl Codex {
326328 let ( tx_sub, rx_sub) = async_channel:: bounded ( SUBMISSION_CHANNEL_CAPACITY ) ;
327329 let ( tx_event, rx_event) = async_channel:: unbounded ( ) ;
328330
331+ let loaded_plugins = plugins_manager. plugins_for_config ( & config) ;
329332 let loaded_skills = skills_manager. skills_for_config ( & config) ;
330333
331334 for err in & loaded_skills. errors {
@@ -335,6 +338,19 @@ impl Codex {
335338 err. message
336339 ) ;
337340 }
341+ for plugin in loaded_plugins
342+ . plugins
343+ . iter ( )
344+ . filter ( |plugin| plugin. error . is_some ( ) )
345+ {
346+ if let Some ( error) = plugin. error . as_deref ( ) {
347+ warn ! (
348+ plugin = plugin. config_name,
349+ path = %plugin. root. display( ) ,
350+ "failed to load plugin: {error}"
351+ ) ;
352+ }
353+ }
338354
339355 if let SessionSource :: SubAgent ( SubAgentSource :: ThreadSpawn { depth, .. } ) = session_source
340356 && depth >= config. agent_max_depth
@@ -462,6 +478,7 @@ impl Codex {
462478 conversation_history,
463479 session_source_clone,
464480 skills_manager,
481+ plugins_manager,
465482 file_watcher,
466483 agent_control,
467484 )
@@ -1062,6 +1079,7 @@ impl Session {
10621079 initial_history : InitialHistory ,
10631080 session_source : SessionSource ,
10641081 skills_manager : Arc < SkillsManager > ,
1082+ plugins_manager : Arc < PluginsManager > ,
10651083 file_watcher : Arc < FileWatcher > ,
10661084 agent_control : AgentControl ,
10671085 ) -> anyhow:: Result < Arc < Self > > {
@@ -1144,9 +1162,11 @@ impl Session {
11441162 let history_meta_fut = crate :: message_history:: history_metadata ( & config) ;
11451163 let auth_manager_clone = Arc :: clone ( & auth_manager) ;
11461164 let config_for_mcp = Arc :: clone ( & config) ;
1165+ let plugins_manager_for_mcp = Arc :: clone ( & plugins_manager) ;
11471166 let auth_and_mcp_fut = async move {
11481167 let auth = auth_manager_clone. auth ( ) . await ;
1149- let mcp_servers = effective_mcp_servers ( & config_for_mcp, auth. as_ref ( ) ) ;
1168+ let mcp_servers =
1169+ effective_mcp_servers ( & config_for_mcp, auth. as_ref ( ) , & plugins_manager_for_mcp) ;
11501170 let auth_statuses = compute_auth_statuses (
11511171 mcp_servers. iter ( ) ,
11521172 config_for_mcp. mcp_oauth_credentials_store_mode ,
@@ -1394,6 +1414,7 @@ impl Session {
13941414 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
13951415 execve_session_approvals : RwLock :: new ( HashMap :: new ( ) ) ,
13961416 skills_manager,
1417+ plugins_manager,
13971418 file_watcher,
13981419 agent_control,
13991420 network_proxy,
@@ -2307,6 +2328,8 @@ impl Session {
23072328 . config_layer_stack
23082329 . with_user_config ( & config_toml_path, user_config) ;
23092330 state. session_configuration . original_config_do_not_use = Arc :: new ( config) ;
2331+ self . services . skills_manager . clear_cache ( ) ;
2332+ self . services . plugins_manager . clear_cache ( ) ;
23102333 }
23112334
23122335 pub ( crate ) async fn new_default_turn_with_sub_id ( & self , sub_id : String ) -> Arc < TurnContext > {
@@ -4120,7 +4143,11 @@ mod handlers {
41204143 pub async fn list_mcp_tools ( sess : & Session , config : & Arc < Config > , sub_id : String ) {
41214144 let mcp_connection_manager = sess. services . mcp_connection_manager . read ( ) . await ;
41224145 let auth = sess. services . auth_manager . auth ( ) . await ;
4123- let mcp_servers = effective_mcp_servers ( config, auth. as_ref ( ) ) ;
4146+ let mcp_servers = effective_mcp_servers (
4147+ config,
4148+ auth. as_ref ( ) ,
4149+ sess. services . plugins_manager . as_ref ( ) ,
4150+ ) ;
41244151 let snapshot = collect_mcp_snapshot_from_manager (
41254152 & mcp_connection_manager,
41264153 compute_auth_statuses ( mcp_servers. iter ( ) , config. mcp_oauth_credentials_store_mode )
@@ -8280,6 +8307,11 @@ mod tests {
82808307
82818308 let ( tx_event, _rx_event) = async_channel:: unbounded ( ) ;
82828309 let ( agent_status_tx, _agent_status_rx) = watch:: channel ( AgentStatus :: PendingInit ) ;
8310+ let plugins_manager = Arc :: new ( PluginsManager :: new ( config. codex_home . clone ( ) ) ) ;
8311+ let skills_manager = Arc :: new ( SkillsManager :: new (
8312+ config. codex_home . clone ( ) ,
8313+ Arc :: clone ( & plugins_manager) ,
8314+ ) ) ;
82838315 let result = Session :: new (
82848316 session_configuration,
82858317 Arc :: clone ( & config) ,
@@ -8290,7 +8322,8 @@ mod tests {
82908322 agent_status_tx,
82918323 InitialHistory :: New ,
82928324 SessionSource :: Exec ,
8293- Arc :: new ( SkillsManager :: new ( config. codex_home . clone ( ) ) ) ,
8325+ skills_manager,
8326+ plugins_manager,
82948327 Arc :: new ( FileWatcher :: noop ( ) ) ,
82958328 AgentControl :: default ( ) ,
82968329 )
@@ -8371,7 +8404,11 @@ mod tests {
83718404 ) ;
83728405
83738406 let state = SessionState :: new ( session_configuration. clone ( ) ) ;
8374- let skills_manager = Arc :: new ( SkillsManager :: new ( config. codex_home . clone ( ) ) ) ;
8407+ let plugins_manager = Arc :: new ( PluginsManager :: new ( config. codex_home . clone ( ) ) ) ;
8408+ let skills_manager = Arc :: new ( SkillsManager :: new (
8409+ config. codex_home . clone ( ) ,
8410+ Arc :: clone ( & plugins_manager) ,
8411+ ) ) ;
83758412 let network_approval = Arc :: new ( NetworkApprovalService :: default ( ) ) ;
83768413
83778414 let file_watcher = Arc :: new ( FileWatcher :: noop ( ) ) ;
@@ -8405,6 +8442,7 @@ mod tests {
84058442 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
84068443 execve_session_approvals : RwLock :: new ( HashMap :: new ( ) ) ,
84078444 skills_manager,
8445+ plugins_manager,
84088446 file_watcher,
84098447 agent_control,
84108448 network_proxy : None ,
@@ -8530,7 +8568,11 @@ mod tests {
85308568 ) ;
85318569
85328570 let state = SessionState :: new ( session_configuration. clone ( ) ) ;
8533- let skills_manager = Arc :: new ( SkillsManager :: new ( config. codex_home . clone ( ) ) ) ;
8571+ let plugins_manager = Arc :: new ( PluginsManager :: new ( config. codex_home . clone ( ) ) ) ;
8572+ let skills_manager = Arc :: new ( SkillsManager :: new (
8573+ config. codex_home . clone ( ) ,
8574+ Arc :: clone ( & plugins_manager) ,
8575+ ) ) ;
85348576 let network_approval = Arc :: new ( NetworkApprovalService :: default ( ) ) ;
85358577
85368578 let file_watcher = Arc :: new ( FileWatcher :: noop ( ) ) ;
@@ -8564,6 +8606,7 @@ mod tests {
85648606 tool_approvals : Mutex :: new ( ApprovalStore :: default ( ) ) ,
85658607 execve_session_approvals : RwLock :: new ( HashMap :: new ( ) ) ,
85668608 skills_manager,
8609+ plugins_manager,
85678610 file_watcher,
85688611 agent_control,
85698612 network_proxy : None ,
0 commit comments