Support disabling tool suggest for specific tools. (#20072)

## Summary
- Add `disable_tool_suggest` to app and plugin config, schema, and
TypeScript output
- Exclude disabled connectors and plugins from tool suggestion discovery
- Persist "never show again" tool-suggestion choices back into
`config.toml`
- Update config docs and add coverage for connector and plugin
suppression

## Testing
- Added and updated unit tests for config persistence and tool-suggest
filtering
- Not run (not requested)
This commit is contained in:
Matthew Zeng
2026-04-28 17:19:34 -07:00
committed by GitHub
Unverified
parent 1211a90a35
commit ebdf3a878c
17 changed files with 681 additions and 6 deletions
+3
View File
@@ -18,6 +18,7 @@ use crate::build_available_skills;
use crate::commit_attribution::commit_message_trailer_instruction;
use crate::compact;
use crate::config::ManagedFeatures;
use crate::config::resolve_tool_suggest_config_from_layer_stack;
use crate::connectors;
use crate::context::ApprovedCommandPrefixSaved;
use crate::context::AppsInstructions;
@@ -1407,6 +1408,8 @@ impl Session {
config.config_layer_stack = config
.config_layer_stack
.with_user_config(&config_toml_path, user_config);
config.tool_suggest =
resolve_tool_suggest_config_from_layer_stack(&config.config_layer_stack);
state.session_configuration.original_config_do_not_use = Arc::new(config);
self.services.skills_manager.clear_cache();
self.services.plugins_manager.clear_cache();
+30
View File
@@ -19,6 +19,7 @@ use codex_config::NetworkDomainPermissionsToml;
use codex_config::RequirementSource;
use codex_config::Sourced;
use codex_config::loader::project_trust_key;
use codex_config::types::ToolSuggestDisabledTool;
use codex_features::Feature;
use codex_features::Features;
@@ -1155,6 +1156,35 @@ async fn reload_user_config_layer_updates_effective_apps_config() {
assert_eq!(app.destructive_enabled, Some(false));
}
#[tokio::test]
async fn reload_user_config_layer_updates_effective_tool_suggest_config() {
let (session, _turn_context) = make_session_and_context().await;
let codex_home = session.codex_home().await;
std::fs::create_dir_all(&codex_home).expect("create codex home");
let config_toml_path = codex_home.join(CONFIG_TOML_FILE);
std::fs::write(
&config_toml_path,
r#"[tool_suggest]
disabled_tools = [
{ type = "connector", id = " calendar " },
{ type = "plugin", id = "slack@openai-curated" },
]
"#,
)
.expect("write user config");
session.reload_user_config_layer().await;
let config = session.get_config().await;
assert_eq!(
config.tool_suggest.disabled_tools,
vec![
ToolSuggestDisabledTool::connector("calendar"),
ToolSuggestDisabledTool::plugin("slack@openai-curated"),
]
);
}
#[test]
fn filter_connectors_for_input_skips_duplicate_slug_mentions() {
let connectors = vec![