From 6264299254b7283c9d9b09f8024e513b66bf1a65 Mon Sep 17 00:00:00 2001 From: canvrno-oai Date: Tue, 24 Mar 2026 16:56:08 -0700 Subject: [PATCH] Remove provenance filtering for apps and skills from plugins --- codex-rs/tui/src/bottom_pane/chat_composer.rs | 108 ++---------------- .../src/bottom_pane/chat_composer.rs | 62 ++-------- 2 files changed, 22 insertions(+), 148 deletions(-) diff --git a/codex-rs/tui/src/bottom_pane/chat_composer.rs b/codex-rs/tui/src/bottom_pane/chat_composer.rs index 7e5831ab5b0..6d5c92d4903 100644 --- a/codex-rs/tui/src/bottom_pane/chat_composer.rs +++ b/codex-rs/tui/src/bottom_pane/chat_composer.rs @@ -3584,41 +3584,8 @@ impl ChatComposer { fn mention_items(&self) -> Vec { let mut mentions = Vec::new(); - let plugin_namespaces: HashSet = - self.plugins.as_ref().map_or_else(HashSet::new, |plugins| { - plugins - .iter() - .filter_map(|plugin| { - let (plugin_name, _) = plugin - .config_name - .split_once('@') - .unwrap_or((plugin.config_name.as_str(), "")); - let plugin_name = plugin_name.trim(); - if plugin_name.is_empty() { - None - } else { - Some(plugin_name.to_ascii_lowercase()) - } - }) - .collect() - }); - let plugin_display_names: HashSet = - self.plugins.as_ref().map_or_else(HashSet::new, |plugins| { - plugins - .iter() - .map(|plugin| plugin.display_name.to_ascii_lowercase()) - .collect() - }); - if let Some(skills) = self.skills.as_ref() { for skill in skills { - let is_plugin_namespaced_skill = - skill.name.split_once(':').is_some_and(|(namespace, _)| { - plugin_namespaces.contains(&namespace.to_ascii_lowercase()) - }); - if is_plugin_namespaced_skill { - continue; - } let display_name = skill_display_name(skill).to_string(); let description = skill_description(skill); let skill_name = skill.name.clone(); @@ -3698,30 +3665,18 @@ impl ChatComposer { if !connector.is_accessible || !connector.is_enabled { continue; } - let plugin_backed_connector = connector - .plugin_display_names - .iter() - .any(|name| plugin_display_names.contains(&name.to_ascii_lowercase())); - if plugin_backed_connector { - continue; - } let display_name = connectors::connector_display_label(connector); let description = Some(Self::connector_brief_description(connector)); let slug = codex_core::connectors::connector_mention_slug(connector); let search_terms = vec![display_name.clone(), connector.id.clone(), slug.clone()]; let connector_id = connector.id.as_str(); - let category_tag = if connector.plugin_display_names.is_empty() { - "[App]".to_string() - } else { - "[Plugin]".to_string() - }; mentions.push(MentionItem { display_name: display_name.clone(), description, insert_text: format!("${slug}"), search_terms, path: Some(format!("app://{connector_id}")), - category_tag: Some(category_tag), + category_tag: Some("[App]".to_string()), sort_rank: 1, }); } @@ -5428,7 +5383,7 @@ mod tests { } #[test] - fn mention_items_hide_plugin_owned_skill_and_app_duplicates() { + fn mention_items_show_plugin_owned_skill_and_app_duplicates() { let (tx, _rx) = unbounded_channel::(); let sender = AppEventSender::new(tx); let mut composer = ChatComposer::new( @@ -5491,63 +5446,20 @@ mod tests { })); let mentions = composer.mention_items(); - assert_eq!(mentions.len(), 1); - assert_eq!(mentions[0].display_name, "Google Calendar".to_string()); - assert_eq!(mentions[0].category_tag, Some("[Plugin]".to_string())); + assert_eq!(mentions.len(), 3); + assert_eq!(mentions[0].category_tag, Some("[Skill]".to_string())); assert_eq!( mentions[0].path, - Some("plugin://google-calendar@debug".to_string()) + Some("/tmp/repo/google-calendar/SKILL.md".to_string()) ); - } - - #[test] - fn mention_items_hide_plugin_owned_app_duplicates_when_provenance_matches() { - let (tx, _rx) = unbounded_channel::(); - let sender = AppEventSender::new(tx); - let mut composer = ChatComposer::new( - true, - sender, - false, - "Ask Codex to do anything".to_string(), - false, - ); - composer.set_connectors_enabled(true); - composer.set_text_content("$goog".to_string(), Vec::new(), Vec::new()); - composer.set_plugin_mentions(Some(vec![PluginCapabilitySummary { - config_name: "google-calendar@debug".to_string(), - display_name: "Google Calendar".to_string(), - description: None, - has_skills: false, - mcp_server_names: vec!["google-calendar".to_string()], - app_connector_ids: vec![codex_core::plugins::AppConnectorId( - "google_calendar".to_string(), - )], - }])); - composer.set_connector_mentions(Some(ConnectorsSnapshot { - connectors: vec![AppInfo { - id: "google_calendar".to_string(), - name: "Google Calendar".to_string(), - description: Some("Look up events and availability".to_string()), - logo_url: None, - logo_url_dark: None, - distribution_channel: None, - branding: None, - app_metadata: None, - labels: None, - install_url: Some("https://example.test/google-calendar".to_string()), - is_accessible: true, - is_enabled: true, - plugin_display_names: vec!["Google Calendar".to_string()], - }], - })); - - let mentions = composer.mention_items(); - assert_eq!(mentions.len(), 1); - assert_eq!(mentions[0].category_tag, Some("[Plugin]".to_string())); + assert_eq!(mentions[0].display_name, "Google Calendar".to_string()); + assert_eq!(mentions[1].category_tag, Some("[Plugin]".to_string())); assert_eq!( - mentions[0].path, + mentions[1].path, Some("plugin://google-calendar@debug".to_string()) ); + assert_eq!(mentions[2].category_tag, Some("[App]".to_string())); + assert_eq!(mentions[2].path, Some("app://google_calendar".to_string())); } #[test] diff --git a/codex-rs/tui_app_server/src/bottom_pane/chat_composer.rs b/codex-rs/tui_app_server/src/bottom_pane/chat_composer.rs index d7dc0ae0967..fea3b8c2adf 100644 --- a/codex-rs/tui_app_server/src/bottom_pane/chat_composer.rs +++ b/codex-rs/tui_app_server/src/bottom_pane/chat_composer.rs @@ -3599,41 +3599,8 @@ impl ChatComposer { fn mention_items(&self) -> Vec { let mut mentions = Vec::new(); - let plugin_namespaces: HashSet = - self.plugins.as_ref().map_or_else(HashSet::new, |plugins| { - plugins - .iter() - .filter_map(|plugin| { - let (plugin_name, _) = plugin - .config_name - .split_once('@') - .unwrap_or((plugin.config_name.as_str(), "")); - let plugin_name = plugin_name.trim(); - if plugin_name.is_empty() { - None - } else { - Some(plugin_name.to_ascii_lowercase()) - } - }) - .collect() - }); - let plugin_display_names: HashSet = - self.plugins.as_ref().map_or_else(HashSet::new, |plugins| { - plugins - .iter() - .map(|plugin| plugin.display_name.to_ascii_lowercase()) - .collect() - }); - if let Some(skills) = self.skills.as_ref() { for skill in skills { - let is_plugin_namespaced_skill = - skill.name.split_once(':').is_some_and(|(namespace, _)| { - plugin_namespaces.contains(&namespace.to_ascii_lowercase()) - }); - if is_plugin_namespaced_skill { - continue; - } let display_name = skill_display_name(skill).to_string(); let description = skill_description(skill); let skill_name = skill.name.clone(); @@ -3713,30 +3680,18 @@ impl ChatComposer { if !connector.is_accessible || !connector.is_enabled { continue; } - let plugin_backed_connector = connector - .plugin_display_names - .iter() - .any(|name| plugin_display_names.contains(&name.to_ascii_lowercase())); - if plugin_backed_connector { - continue; - } let display_name = connectors::connector_display_label(connector); let description = Some(Self::connector_brief_description(connector)); let slug = codex_core::connectors::connector_mention_slug(connector); let search_terms = vec![display_name.clone(), connector.id.clone(), slug.clone()]; let connector_id = connector.id.as_str(); - let category_tag = if connector.plugin_display_names.is_empty() { - "[App]".to_string() - } else { - "[Plugin]".to_string() - }; mentions.push(MentionItem { display_name: display_name.clone(), description, insert_text: format!("${slug}"), search_terms, path: Some(format!("app://{connector_id}")), - category_tag: Some(category_tag), + category_tag: Some("[App]".to_string()), sort_rank: 1, }); } @@ -5443,7 +5398,7 @@ mod tests { } #[test] - fn mention_items_hide_plugin_owned_skill_and_app_duplicates() { + fn mention_items_show_plugin_owned_skill_and_app_duplicates() { let (tx, _rx) = unbounded_channel::(); let sender = AppEventSender::new(tx); let mut composer = ChatComposer::new( @@ -5506,13 +5461,20 @@ mod tests { })); let mentions = composer.mention_items(); - assert_eq!(mentions.len(), 1); - assert_eq!(mentions[0].display_name, "Google Calendar".to_string()); - assert_eq!(mentions[0].category_tag, Some("[Plugin]".to_string())); + assert_eq!(mentions.len(), 3); + assert_eq!(mentions[0].category_tag, Some("[Skill]".to_string())); assert_eq!( mentions[0].path, + Some("/tmp/repo/google-calendar/SKILL.md".to_string()) + ); + assert_eq!(mentions[0].display_name, "Google Calendar".to_string()); + assert_eq!(mentions[1].category_tag, Some("[Plugin]".to_string())); + assert_eq!( + mentions[1].path, Some("plugin://google-calendar@debug".to_string()) ); + assert_eq!(mentions[2].category_tag, Some("[App]".to_string())); + assert_eq!(mentions[2].path, Some("app://google_calendar".to_string())); } #[test]