mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Allow disabling the update_plan tool (#35054)
## What changed - Add a default-on `tools.update_plan.enabled` configuration option. - Omit `update_plan` from the visible and registered tool sets when the option is disabled. ## Testing - Cover configuration resolution and tool registration for the disabled setting. GitOrigin-RevId: c13aa463a6911956fca9f0ef5b74841b543798c4
This commit is contained in:
@@ -636,6 +636,7 @@ pub struct ToolsToml {
|
||||
)]
|
||||
pub web_search: Option<WebSearchToolConfig>,
|
||||
pub experimental_request_user_input: Option<ExperimentalRequestUserInput>,
|
||||
pub update_plan: Option<UpdatePlanToolConfig>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
|
||||
@@ -645,6 +646,13 @@ pub struct ExperimentalRequestUserInput {
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
|
||||
#[schemars(deny_unknown_fields)]
|
||||
pub struct UpdatePlanToolConfig {
|
||||
#[serde(default = "default_true")]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum WebSearchToolConfigInput {
|
||||
|
||||
@@ -3147,6 +3147,9 @@
|
||||
"experimental_request_user_input": {
|
||||
"$ref": "#/definitions/ExperimentalRequestUserInput"
|
||||
},
|
||||
"update_plan": {
|
||||
"$ref": "#/definitions/UpdatePlanToolConfig"
|
||||
},
|
||||
"web_search": {
|
||||
"allOf": [
|
||||
{
|
||||
@@ -4648,6 +4651,16 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"UpdatePlanToolConfig": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"default": true,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"UriBasedFileOpener": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
||||
@@ -361,6 +361,7 @@ web_search = true
|
||||
Some(ToolsToml {
|
||||
web_search: None,
|
||||
experimental_request_user_input: None,
|
||||
update_plan: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -380,6 +381,7 @@ web_search = false
|
||||
Some(ToolsToml {
|
||||
web_search: None,
|
||||
experimental_request_user_input: None,
|
||||
update_plan: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -398,6 +400,7 @@ fn tools_experimental_request_user_input_defaults_to_enabled() {
|
||||
Some(ToolsToml {
|
||||
web_search: None,
|
||||
experimental_request_user_input: Some(ExperimentalRequestUserInput { enabled: true }),
|
||||
update_plan: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -417,6 +420,7 @@ enabled = false
|
||||
Some(ToolsToml {
|
||||
web_search: None,
|
||||
experimental_request_user_input: Some(ExperimentalRequestUserInput { enabled: false }),
|
||||
update_plan: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -431,6 +435,7 @@ async fn load_config_resolves_experimental_request_user_input_enabled() -> std::
|
||||
experimental_request_user_input: Some(ExperimentalRequestUserInput {
|
||||
enabled: false,
|
||||
}),
|
||||
update_plan: None,
|
||||
}),
|
||||
..ConfigToml::default()
|
||||
},
|
||||
@@ -502,6 +507,27 @@ async fn load_config_resolves_non_prefixed_mcp_tool_servers() -> std::io::Result
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_config_resolves_update_plan_enabled() -> std::io::Result<()> {
|
||||
let codex_home = tempdir()?;
|
||||
let config_toml = toml::from_str(
|
||||
r#"
|
||||
[tools.update_plan]
|
||||
enabled = false
|
||||
"#,
|
||||
)
|
||||
.expect("TOML deserialization should succeed");
|
||||
let config = Config::load_from_base_config_with_overrides(
|
||||
config_toml,
|
||||
ConfigOverrides::default(),
|
||||
codex_home.abs(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert!(!config.update_plan_enabled);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_config_resolves_code_mode_config() -> std::io::Result<()> {
|
||||
let codex_home = tempdir()?;
|
||||
|
||||
@@ -1030,6 +1030,9 @@ pub struct Config {
|
||||
/// Whether to register the experimental request_user_input tool.
|
||||
pub experimental_request_user_input_enabled: bool,
|
||||
|
||||
/// Whether to register the update_plan tool.
|
||||
pub update_plan_enabled: bool,
|
||||
|
||||
/// Configuration for the experimental code-mode tool surface.
|
||||
pub code_mode: CodeModeConfig,
|
||||
|
||||
@@ -2537,6 +2540,14 @@ fn resolve_experimental_request_user_input_enabled(config_toml: &ConfigToml) ->
|
||||
.is_none_or(|config| config.enabled)
|
||||
}
|
||||
|
||||
fn resolve_update_plan_enabled(config_toml: &ConfigToml) -> bool {
|
||||
config_toml
|
||||
.tools
|
||||
.as_ref()
|
||||
.and_then(|tools| tools.update_plan.as_ref())
|
||||
.is_none_or(|config| config.enabled)
|
||||
}
|
||||
|
||||
fn resolve_orchestrator_feature_enabled(
|
||||
feature: Option<&codex_config::config_toml::OrchestratorFeatureToml>,
|
||||
) -> bool {
|
||||
@@ -3577,6 +3588,7 @@ impl Config {
|
||||
let web_search_config = resolve_web_search_config(&cfg);
|
||||
let experimental_request_user_input_enabled =
|
||||
resolve_experimental_request_user_input_enabled(&cfg);
|
||||
let update_plan_enabled = resolve_update_plan_enabled(&cfg);
|
||||
let code_mode = resolve_code_mode_config(&cfg);
|
||||
let multi_agent_v2 = resolve_multi_agent_v2_config(&cfg);
|
||||
let token_budget = resolve_token_budget_config(&cfg, &features)?;
|
||||
@@ -4108,6 +4120,7 @@ impl Config {
|
||||
web_search_mode: constrained_web_search_mode.value,
|
||||
web_search_config,
|
||||
experimental_request_user_input_enabled,
|
||||
update_plan_enabled,
|
||||
code_mode,
|
||||
use_experimental_unified_exec_tool,
|
||||
background_terminal_max_timeout,
|
||||
|
||||
@@ -713,7 +713,9 @@ fn add_core_utility_tools(context: &CoreToolPlanContext<'_>, planned_tools: &mut
|
||||
let features = turn_context.config.features.get();
|
||||
let environment_mode = tool_environment_mode(context.environments);
|
||||
|
||||
planned_tools.add(PlanHandler);
|
||||
if turn_context.config.update_plan_enabled {
|
||||
planned_tools.add(PlanHandler);
|
||||
}
|
||||
|
||||
if features.enabled(Feature::DeferredExecutor) {
|
||||
planned_tools.add(WaitForEnvironmentHandler);
|
||||
|
||||
@@ -466,6 +466,22 @@ async fn request_user_input_tool_respects_experimental_config_gate() {
|
||||
disabled.assert_registered_lacks(&["request_user_input"]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_plan_tool_respects_config_gate() {
|
||||
let enabled = probe(|_| {}).await;
|
||||
enabled.assert_visible_contains(&["update_plan"]);
|
||||
enabled.assert_registered_contains(&["update_plan"]);
|
||||
|
||||
let disabled = probe(|turn| {
|
||||
update_config(turn, |config| {
|
||||
config.update_plan_enabled = false;
|
||||
});
|
||||
})
|
||||
.await;
|
||||
disabled.assert_visible_lacks(&["update_plan"]);
|
||||
disabled.assert_registered_lacks(&["update_plan"]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn request_user_input_stays_direct_in_code_mode_only() {
|
||||
let plan = probe(|turn| {
|
||||
|
||||
@@ -294,6 +294,7 @@ fn new_config(model: Option<String>, arg0_paths: Arg0DispatchPaths) -> anyhow::R
|
||||
web_search_mode: Constrained::allow_any(WebSearchMode::Disabled),
|
||||
web_search_config: None,
|
||||
experimental_request_user_input_enabled: true,
|
||||
update_plan_enabled: true,
|
||||
code_mode: Default::default(),
|
||||
use_experimental_unified_exec_tool: false,
|
||||
background_terminal_max_timeout: 300_000,
|
||||
|
||||
Reference in New Issue
Block a user