mirror of
https://github.com/openai/codex.git
synced 2026-11-13 14:46:14 +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:
1 parent
bb24b67d33
commit
fb4e6ba2f4
7 files changed
+80
-1
No files matched your search
@@ -636,6 +636,7 @@ pub struct ToolsToml {
|
|||||||
)]
|
)]
|
||||||
pub web_search: Option<WebSearchToolConfig>,
|
pub web_search: Option<WebSearchToolConfig>,
|
||||||
pub experimental_request_user_input: Option<ExperimentalRequestUserInput>,
|
pub experimental_request_user_input: Option<ExperimentalRequestUserInput>,
|
||||||
|
pub update_plan: Option<UpdatePlanToolConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema)]
|
||||||
@@ -645,6 +646,13 @@ pub struct ExperimentalRequestUserInput {
|
|||||||
pub enabled: bool,
|
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)]
|
#[derive(Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
enum WebSearchToolConfigInput {
|
enum WebSearchToolConfigInput {
|
||||||
|
|||||||
@@ -3147,6 +3147,9 @@
|
|||||||
"experimental_request_user_input": {
|
"experimental_request_user_input": {
|
||||||
"$ref": "#/definitions/ExperimentalRequestUserInput"
|
"$ref": "#/definitions/ExperimentalRequestUserInput"
|
||||||
},
|
},
|
||||||
|
"update_plan": {
|
||||||
|
"$ref": "#/definitions/UpdatePlanToolConfig"
|
||||||
|
},
|
||||||
"web_search": {
|
"web_search": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
@@ -4648,6 +4651,16 @@
|
|||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"UpdatePlanToolConfig": {
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"enabled": {
|
||||||
|
"default": true,
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"UriBasedFileOpener": {
|
"UriBasedFileOpener": {
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ web_search = true
|
|||||||
Some(ToolsToml {
|
Some(ToolsToml {
|
||||||
web_search: None,
|
web_search: None,
|
||||||
experimental_request_user_input: None,
|
experimental_request_user_input: None,
|
||||||
|
update_plan: None,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -380,6 +381,7 @@ web_search = false
|
|||||||
Some(ToolsToml {
|
Some(ToolsToml {
|
||||||
web_search: None,
|
web_search: None,
|
||||||
experimental_request_user_input: None,
|
experimental_request_user_input: None,
|
||||||
|
update_plan: None,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -398,6 +400,7 @@ fn tools_experimental_request_user_input_defaults_to_enabled() {
|
|||||||
Some(ToolsToml {
|
Some(ToolsToml {
|
||||||
web_search: None,
|
web_search: None,
|
||||||
experimental_request_user_input: Some(ExperimentalRequestUserInput { enabled: true }),
|
experimental_request_user_input: Some(ExperimentalRequestUserInput { enabled: true }),
|
||||||
|
update_plan: None,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -417,6 +420,7 @@ enabled = false
|
|||||||
Some(ToolsToml {
|
Some(ToolsToml {
|
||||||
web_search: None,
|
web_search: None,
|
||||||
experimental_request_user_input: Some(ExperimentalRequestUserInput { enabled: false }),
|
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 {
|
experimental_request_user_input: Some(ExperimentalRequestUserInput {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
}),
|
}),
|
||||||
|
update_plan: None,
|
||||||
}),
|
}),
|
||||||
..ConfigToml::default()
|
..ConfigToml::default()
|
||||||
},
|
},
|
||||||
@@ -502,6 +507,27 @@ async fn load_config_resolves_non_prefixed_mcp_tool_servers() -> std::io::Result
|
|||||||
Ok(())
|
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]
|
#[tokio::test]
|
||||||
async fn load_config_resolves_code_mode_config() -> std::io::Result<()> {
|
async fn load_config_resolves_code_mode_config() -> std::io::Result<()> {
|
||||||
let codex_home = tempdir()?;
|
let codex_home = tempdir()?;
|
||||||
|
|||||||
@@ -1030,6 +1030,9 @@ pub struct Config {
|
|||||||
/// Whether to register the experimental request_user_input tool.
|
/// Whether to register the experimental request_user_input tool.
|
||||||
pub experimental_request_user_input_enabled: bool,
|
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.
|
/// Configuration for the experimental code-mode tool surface.
|
||||||
pub code_mode: CodeModeConfig,
|
pub code_mode: CodeModeConfig,
|
||||||
|
|
||||||
@@ -2537,6 +2540,14 @@ fn resolve_experimental_request_user_input_enabled(config_toml: &ConfigToml) ->
|
|||||||
.is_none_or(|config| config.enabled)
|
.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(
|
fn resolve_orchestrator_feature_enabled(
|
||||||
feature: Option<&codex_config::config_toml::OrchestratorFeatureToml>,
|
feature: Option<&codex_config::config_toml::OrchestratorFeatureToml>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@@ -3577,6 +3588,7 @@ impl Config {
|
|||||||
let web_search_config = resolve_web_search_config(&cfg);
|
let web_search_config = resolve_web_search_config(&cfg);
|
||||||
let experimental_request_user_input_enabled =
|
let experimental_request_user_input_enabled =
|
||||||
resolve_experimental_request_user_input_enabled(&cfg);
|
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 code_mode = resolve_code_mode_config(&cfg);
|
||||||
let multi_agent_v2 = resolve_multi_agent_v2_config(&cfg);
|
let multi_agent_v2 = resolve_multi_agent_v2_config(&cfg);
|
||||||
let token_budget = resolve_token_budget_config(&cfg, &features)?;
|
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_mode: constrained_web_search_mode.value,
|
||||||
web_search_config,
|
web_search_config,
|
||||||
experimental_request_user_input_enabled,
|
experimental_request_user_input_enabled,
|
||||||
|
update_plan_enabled,
|
||||||
code_mode,
|
code_mode,
|
||||||
use_experimental_unified_exec_tool,
|
use_experimental_unified_exec_tool,
|
||||||
background_terminal_max_timeout,
|
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 features = turn_context.config.features.get();
|
||||||
let environment_mode = tool_environment_mode(context.environments);
|
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) {
|
if features.enabled(Feature::DeferredExecutor) {
|
||||||
planned_tools.add(WaitForEnvironmentHandler);
|
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"]);
|
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]
|
#[tokio::test]
|
||||||
async fn request_user_input_stays_direct_in_code_mode_only() {
|
async fn request_user_input_stays_direct_in_code_mode_only() {
|
||||||
let plan = probe(|turn| {
|
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_mode: Constrained::allow_any(WebSearchMode::Disabled),
|
||||||
web_search_config: None,
|
web_search_config: None,
|
||||||
experimental_request_user_input_enabled: true,
|
experimental_request_user_input_enabled: true,
|
||||||
|
update_plan_enabled: true,
|
||||||
code_mode: Default::default(),
|
code_mode: Default::default(),
|
||||||
use_experimental_unified_exec_tool: false,
|
use_experimental_unified_exec_tool: false,
|
||||||
background_terminal_max_timeout: 300_000,
|
background_terminal_max_timeout: 300_000,
|
||||||
|
|||||||
Reference in new issue
Block a user