Enable plan tool by default (#5384)
## Summary - make the plan tool available by default by removing the feature flag and always registering the handler - drop plan-tool CLI and API toggles across the exec, TUI, MCP server, and app server code paths - update tests and configs to reflect the always-on plan tool and guard workspace restriction tests against env leakage ## Testing Manually tested the extension. ------ https://chatgpt.com/codex/tasks/task_i_68f67a3ff2d083209562a773f814c1f9
This commit is contained in:
@@ -247,10 +247,6 @@ pub struct NewConversationParams {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub base_instructions: Option<String>,
|
pub base_instructions: Option<String>,
|
||||||
|
|
||||||
/// Whether to include the plan tool in the conversation.
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
|
|
||||||
/// Whether to include the apply patch tool in the conversation.
|
/// Whether to include the apply patch tool in the conversation.
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub include_apply_patch_tool: Option<bool>,
|
pub include_apply_patch_tool: Option<bool>,
|
||||||
@@ -886,7 +882,6 @@ mod tests {
|
|||||||
sandbox: None,
|
sandbox: None,
|
||||||
config: None,
|
config: None,
|
||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
include_plan_tool: None,
|
|
||||||
include_apply_patch_tool: None,
|
include_apply_patch_tool: None,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1421,7 +1421,6 @@ async fn derive_config_from_params(
|
|||||||
sandbox: sandbox_mode,
|
sandbox: sandbox_mode,
|
||||||
config: cli_overrides,
|
config: cli_overrides,
|
||||||
base_instructions,
|
base_instructions,
|
||||||
include_plan_tool,
|
|
||||||
include_apply_patch_tool,
|
include_apply_patch_tool,
|
||||||
} = params;
|
} = params;
|
||||||
let overrides = ConfigOverrides {
|
let overrides = ConfigOverrides {
|
||||||
@@ -1434,7 +1433,6 @@ async fn derive_config_from_params(
|
|||||||
model_provider: None,
|
model_provider: None,
|
||||||
codex_linux_sandbox_exe,
|
codex_linux_sandbox_exe,
|
||||||
base_instructions,
|
base_instructions,
|
||||||
include_plan_tool,
|
|
||||||
include_apply_patch_tool,
|
include_apply_patch_tool,
|
||||||
include_view_image_tool: None,
|
include_view_image_tool: None,
|
||||||
show_raw_agent_reasoning: None,
|
show_raw_agent_reasoning: None,
|
||||||
|
|||||||
@@ -1386,9 +1386,8 @@ async fn spawn_review_thread(
|
|||||||
let model = config.review_model.clone();
|
let model = config.review_model.clone();
|
||||||
let review_model_family = find_family_for_model(&model)
|
let review_model_family = find_family_for_model(&model)
|
||||||
.unwrap_or_else(|| parent_turn_context.client.get_model_family());
|
.unwrap_or_else(|| parent_turn_context.client.get_model_family());
|
||||||
// For reviews, disable plan, web_search, view_image regardless of global settings.
|
// For reviews, disable web_search and view_image regardless of global settings.
|
||||||
let mut review_features = config.features.clone();
|
let mut review_features = config.features.clone();
|
||||||
review_features.disable(crate::features::Feature::PlanTool);
|
|
||||||
review_features.disable(crate::features::Feature::WebSearchRequest);
|
review_features.disable(crate::features::Feature::WebSearchRequest);
|
||||||
review_features.disable(crate::features::Feature::ViewImageTool);
|
review_features.disable(crate::features::Feature::ViewImageTool);
|
||||||
review_features.disable(crate::features::Feature::StreamableShell);
|
review_features.disable(crate::features::Feature::StreamableShell);
|
||||||
|
|||||||
@@ -216,9 +216,6 @@ pub struct Config {
|
|||||||
/// When set, restricts the login mechanism users may use.
|
/// When set, restricts the login mechanism users may use.
|
||||||
pub forced_login_method: Option<ForcedLoginMethod>,
|
pub forced_login_method: Option<ForcedLoginMethod>,
|
||||||
|
|
||||||
/// Include an experimental plan tool that the model can use to update its current plan and status of each step.
|
|
||||||
pub include_plan_tool: bool,
|
|
||||||
|
|
||||||
/// Include the `apply_patch` tool for models that benefit from invoking
|
/// Include the `apply_patch` tool for models that benefit from invoking
|
||||||
/// file edits as a structured tool call. When unset, this falls back to the
|
/// file edits as a structured tool call. When unset, this falls back to the
|
||||||
/// model family's default preference.
|
/// model family's default preference.
|
||||||
@@ -1117,7 +1114,6 @@ pub struct ConfigOverrides {
|
|||||||
pub config_profile: Option<String>,
|
pub config_profile: Option<String>,
|
||||||
pub codex_linux_sandbox_exe: Option<PathBuf>,
|
pub codex_linux_sandbox_exe: Option<PathBuf>,
|
||||||
pub base_instructions: Option<String>,
|
pub base_instructions: Option<String>,
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
pub include_apply_patch_tool: Option<bool>,
|
pub include_apply_patch_tool: Option<bool>,
|
||||||
pub include_view_image_tool: Option<bool>,
|
pub include_view_image_tool: Option<bool>,
|
||||||
pub show_raw_agent_reasoning: Option<bool>,
|
pub show_raw_agent_reasoning: Option<bool>,
|
||||||
@@ -1147,7 +1143,6 @@ impl Config {
|
|||||||
config_profile: config_profile_key,
|
config_profile: config_profile_key,
|
||||||
codex_linux_sandbox_exe,
|
codex_linux_sandbox_exe,
|
||||||
base_instructions,
|
base_instructions,
|
||||||
include_plan_tool: include_plan_tool_override,
|
|
||||||
include_apply_patch_tool: include_apply_patch_tool_override,
|
include_apply_patch_tool: include_apply_patch_tool_override,
|
||||||
include_view_image_tool: include_view_image_tool_override,
|
include_view_image_tool: include_view_image_tool_override,
|
||||||
show_raw_agent_reasoning,
|
show_raw_agent_reasoning,
|
||||||
@@ -1174,7 +1169,6 @@ impl Config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let feature_overrides = FeatureOverrides {
|
let feature_overrides = FeatureOverrides {
|
||||||
include_plan_tool: include_plan_tool_override,
|
|
||||||
include_apply_patch_tool: include_apply_patch_tool_override,
|
include_apply_patch_tool: include_apply_patch_tool_override,
|
||||||
include_view_image_tool: include_view_image_tool_override,
|
include_view_image_tool: include_view_image_tool_override,
|
||||||
web_search_request: override_tools_web_search_request,
|
web_search_request: override_tools_web_search_request,
|
||||||
@@ -1269,7 +1263,6 @@ impl Config {
|
|||||||
|
|
||||||
let history = cfg.history.unwrap_or_default();
|
let history = cfg.history.unwrap_or_default();
|
||||||
|
|
||||||
let include_plan_tool_flag = features.enabled(Feature::PlanTool);
|
|
||||||
let include_apply_patch_tool_flag = features.enabled(Feature::ApplyPatchFreeform);
|
let include_apply_patch_tool_flag = features.enabled(Feature::ApplyPatchFreeform);
|
||||||
let include_view_image_tool_flag = features.enabled(Feature::ViewImageTool);
|
let include_view_image_tool_flag = features.enabled(Feature::ViewImageTool);
|
||||||
let tools_web_search_request = features.enabled(Feature::WebSearchRequest);
|
let tools_web_search_request = features.enabled(Feature::WebSearchRequest);
|
||||||
@@ -1399,7 +1392,6 @@ impl Config {
|
|||||||
.unwrap_or("https://chatgpt.com/backend-api/".to_string()),
|
.unwrap_or("https://chatgpt.com/backend-api/".to_string()),
|
||||||
forced_chatgpt_workspace_id,
|
forced_chatgpt_workspace_id,
|
||||||
forced_login_method,
|
forced_login_method,
|
||||||
include_plan_tool: include_plan_tool_flag,
|
|
||||||
include_apply_patch_tool: include_apply_patch_tool_flag,
|
include_apply_patch_tool: include_apply_patch_tool_flag,
|
||||||
tools_web_search_request,
|
tools_web_search_request,
|
||||||
use_experimental_streamable_shell_tool,
|
use_experimental_streamable_shell_tool,
|
||||||
@@ -1765,7 +1757,6 @@ approve_all = true
|
|||||||
profiles.insert(
|
profiles.insert(
|
||||||
"work".to_string(),
|
"work".to_string(),
|
||||||
ConfigProfile {
|
ConfigProfile {
|
||||||
include_plan_tool: Some(true),
|
|
||||||
include_view_image_tool: Some(false),
|
include_view_image_tool: Some(false),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -1782,9 +1773,7 @@ approve_all = true
|
|||||||
codex_home.path().to_path_buf(),
|
codex_home.path().to_path_buf(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert!(config.features.enabled(Feature::PlanTool));
|
|
||||||
assert!(!config.features.enabled(Feature::ViewImageTool));
|
assert!(!config.features.enabled(Feature::ViewImageTool));
|
||||||
assert!(config.include_plan_tool);
|
|
||||||
assert!(!config.include_view_image_tool);
|
assert!(!config.include_view_image_tool);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1794,7 +1783,6 @@ approve_all = true
|
|||||||
fn feature_table_overrides_legacy_flags() -> std::io::Result<()> {
|
fn feature_table_overrides_legacy_flags() -> std::io::Result<()> {
|
||||||
let codex_home = TempDir::new()?;
|
let codex_home = TempDir::new()?;
|
||||||
let mut entries = BTreeMap::new();
|
let mut entries = BTreeMap::new();
|
||||||
entries.insert("plan_tool".to_string(), false);
|
|
||||||
entries.insert("apply_patch_freeform".to_string(), false);
|
entries.insert("apply_patch_freeform".to_string(), false);
|
||||||
let cfg = ConfigToml {
|
let cfg = ConfigToml {
|
||||||
features: Some(crate::features::FeaturesToml { entries }),
|
features: Some(crate::features::FeaturesToml { entries }),
|
||||||
@@ -1807,9 +1795,7 @@ approve_all = true
|
|||||||
codex_home.path().to_path_buf(),
|
codex_home.path().to_path_buf(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert!(!config.features.enabled(Feature::PlanTool));
|
|
||||||
assert!(!config.features.enabled(Feature::ApplyPatchFreeform));
|
assert!(!config.features.enabled(Feature::ApplyPatchFreeform));
|
||||||
assert!(!config.include_plan_tool);
|
|
||||||
assert!(!config.include_apply_patch_tool);
|
assert!(!config.include_apply_patch_tool);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -2908,7 +2894,6 @@ model_verbosity = "high"
|
|||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
forced_chatgpt_workspace_id: None,
|
forced_chatgpt_workspace_id: None,
|
||||||
forced_login_method: None,
|
forced_login_method: None,
|
||||||
include_plan_tool: false,
|
|
||||||
include_apply_patch_tool: false,
|
include_apply_patch_tool: false,
|
||||||
tools_web_search_request: false,
|
tools_web_search_request: false,
|
||||||
use_experimental_streamable_shell_tool: false,
|
use_experimental_streamable_shell_tool: false,
|
||||||
@@ -2977,7 +2962,6 @@ model_verbosity = "high"
|
|||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
forced_chatgpt_workspace_id: None,
|
forced_chatgpt_workspace_id: None,
|
||||||
forced_login_method: None,
|
forced_login_method: None,
|
||||||
include_plan_tool: false,
|
|
||||||
include_apply_patch_tool: false,
|
include_apply_patch_tool: false,
|
||||||
tools_web_search_request: false,
|
tools_web_search_request: false,
|
||||||
use_experimental_streamable_shell_tool: false,
|
use_experimental_streamable_shell_tool: false,
|
||||||
@@ -3061,7 +3045,6 @@ model_verbosity = "high"
|
|||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
forced_chatgpt_workspace_id: None,
|
forced_chatgpt_workspace_id: None,
|
||||||
forced_login_method: None,
|
forced_login_method: None,
|
||||||
include_plan_tool: false,
|
|
||||||
include_apply_patch_tool: false,
|
include_apply_patch_tool: false,
|
||||||
tools_web_search_request: false,
|
tools_web_search_request: false,
|
||||||
use_experimental_streamable_shell_tool: false,
|
use_experimental_streamable_shell_tool: false,
|
||||||
@@ -3131,7 +3114,6 @@ model_verbosity = "high"
|
|||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
forced_chatgpt_workspace_id: None,
|
forced_chatgpt_workspace_id: None,
|
||||||
forced_login_method: None,
|
forced_login_method: None,
|
||||||
include_plan_tool: false,
|
|
||||||
include_apply_patch_tool: false,
|
include_apply_patch_tool: false,
|
||||||
tools_web_search_request: false,
|
tools_web_search_request: false,
|
||||||
use_experimental_streamable_shell_tool: false,
|
use_experimental_streamable_shell_tool: false,
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ pub struct ConfigProfile {
|
|||||||
pub model_verbosity: Option<Verbosity>,
|
pub model_verbosity: Option<Verbosity>,
|
||||||
pub chatgpt_base_url: Option<String>,
|
pub chatgpt_base_url: Option<String>,
|
||||||
pub experimental_instructions_file: Option<PathBuf>,
|
pub experimental_instructions_file: Option<PathBuf>,
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
pub include_apply_patch_tool: Option<bool>,
|
pub include_apply_patch_tool: Option<bool>,
|
||||||
pub include_view_image_tool: Option<bool>,
|
pub include_view_image_tool: Option<bool>,
|
||||||
pub experimental_use_unified_exec_tool: Option<bool>,
|
pub experimental_use_unified_exec_tool: Option<bool>,
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ pub enum Feature {
|
|||||||
StreamableShell,
|
StreamableShell,
|
||||||
/// Use the official Rust MCP client (rmcp).
|
/// Use the official Rust MCP client (rmcp).
|
||||||
RmcpClient,
|
RmcpClient,
|
||||||
/// Include the plan tool.
|
|
||||||
PlanTool,
|
|
||||||
/// Include the freeform apply_patch tool.
|
/// Include the freeform apply_patch tool.
|
||||||
ApplyPatchFreeform,
|
ApplyPatchFreeform,
|
||||||
/// Include the view_image tool.
|
/// Include the view_image tool.
|
||||||
@@ -74,7 +72,6 @@ pub struct Features {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct FeatureOverrides {
|
pub struct FeatureOverrides {
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
pub include_apply_patch_tool: Option<bool>,
|
pub include_apply_patch_tool: Option<bool>,
|
||||||
pub include_view_image_tool: Option<bool>,
|
pub include_view_image_tool: Option<bool>,
|
||||||
pub web_search_request: Option<bool>,
|
pub web_search_request: Option<bool>,
|
||||||
@@ -83,7 +80,6 @@ pub struct FeatureOverrides {
|
|||||||
impl FeatureOverrides {
|
impl FeatureOverrides {
|
||||||
fn apply(self, features: &mut Features) {
|
fn apply(self, features: &mut Features) {
|
||||||
LegacyFeatureToggles {
|
LegacyFeatureToggles {
|
||||||
include_plan_tool: self.include_plan_tool,
|
|
||||||
include_apply_patch_tool: self.include_apply_patch_tool,
|
include_apply_patch_tool: self.include_apply_patch_tool,
|
||||||
include_view_image_tool: self.include_view_image_tool,
|
include_view_image_tool: self.include_view_image_tool,
|
||||||
tools_web_search: self.web_search_request,
|
tools_web_search: self.web_search_request,
|
||||||
@@ -158,7 +154,6 @@ impl Features {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let profile_legacy = LegacyFeatureToggles {
|
let profile_legacy = LegacyFeatureToggles {
|
||||||
include_plan_tool: config_profile.include_plan_tool,
|
|
||||||
include_apply_patch_tool: config_profile.include_apply_patch_tool,
|
include_apply_patch_tool: config_profile.include_apply_patch_tool,
|
||||||
include_view_image_tool: config_profile.include_view_image_tool,
|
include_view_image_tool: config_profile.include_view_image_tool,
|
||||||
experimental_use_freeform_apply_patch: config_profile
|
experimental_use_freeform_apply_patch: config_profile
|
||||||
@@ -225,12 +220,6 @@ pub const FEATURES: &[FeatureSpec] = &[
|
|||||||
stage: Stage::Experimental,
|
stage: Stage::Experimental,
|
||||||
default_enabled: false,
|
default_enabled: false,
|
||||||
},
|
},
|
||||||
FeatureSpec {
|
|
||||||
id: Feature::PlanTool,
|
|
||||||
key: "plan_tool",
|
|
||||||
stage: Stage::Stable,
|
|
||||||
default_enabled: false,
|
|
||||||
},
|
|
||||||
FeatureSpec {
|
FeatureSpec {
|
||||||
id: Feature::ApplyPatchFreeform,
|
id: Feature::ApplyPatchFreeform,
|
||||||
key: "apply_patch_freeform",
|
key: "apply_patch_freeform",
|
||||||
|
|||||||
@@ -29,10 +29,6 @@ const ALIASES: &[Alias] = &[
|
|||||||
legacy_key: "include_apply_patch_tool",
|
legacy_key: "include_apply_patch_tool",
|
||||||
feature: Feature::ApplyPatchFreeform,
|
feature: Feature::ApplyPatchFreeform,
|
||||||
},
|
},
|
||||||
Alias {
|
|
||||||
legacy_key: "include_plan_tool",
|
|
||||||
feature: Feature::PlanTool,
|
|
||||||
},
|
|
||||||
Alias {
|
Alias {
|
||||||
legacy_key: "include_view_image_tool",
|
legacy_key: "include_view_image_tool",
|
||||||
feature: Feature::ViewImageTool,
|
feature: Feature::ViewImageTool,
|
||||||
@@ -55,7 +51,6 @@ pub(crate) fn feature_for_key(key: &str) -> Option<Feature> {
|
|||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct LegacyFeatureToggles {
|
pub struct LegacyFeatureToggles {
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
pub include_apply_patch_tool: Option<bool>,
|
pub include_apply_patch_tool: Option<bool>,
|
||||||
pub include_view_image_tool: Option<bool>,
|
pub include_view_image_tool: Option<bool>,
|
||||||
pub experimental_use_freeform_apply_patch: Option<bool>,
|
pub experimental_use_freeform_apply_patch: Option<bool>,
|
||||||
@@ -68,12 +63,6 @@ pub struct LegacyFeatureToggles {
|
|||||||
|
|
||||||
impl LegacyFeatureToggles {
|
impl LegacyFeatureToggles {
|
||||||
pub fn apply(self, features: &mut Features) {
|
pub fn apply(self, features: &mut Features) {
|
||||||
set_if_some(
|
|
||||||
features,
|
|
||||||
Feature::PlanTool,
|
|
||||||
self.include_plan_tool,
|
|
||||||
"include_plan_tool",
|
|
||||||
);
|
|
||||||
set_if_some(
|
set_if_some(
|
||||||
features,
|
features,
|
||||||
Feature::ApplyPatchFreeform,
|
Feature::ApplyPatchFreeform,
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ pub enum ConfigShellToolType {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct ToolsConfig {
|
pub(crate) struct ToolsConfig {
|
||||||
pub shell_type: ConfigShellToolType,
|
pub shell_type: ConfigShellToolType,
|
||||||
pub plan_tool: bool,
|
|
||||||
pub apply_patch_tool_type: Option<ApplyPatchToolType>,
|
pub apply_patch_tool_type: Option<ApplyPatchToolType>,
|
||||||
pub web_search_request: bool,
|
pub web_search_request: bool,
|
||||||
pub include_view_image_tool: bool,
|
pub include_view_image_tool: bool,
|
||||||
@@ -46,7 +45,6 @@ impl ToolsConfig {
|
|||||||
} = params;
|
} = params;
|
||||||
let use_streamable_shell_tool = features.enabled(Feature::StreamableShell);
|
let use_streamable_shell_tool = features.enabled(Feature::StreamableShell);
|
||||||
let experimental_unified_exec_tool = features.enabled(Feature::UnifiedExec);
|
let experimental_unified_exec_tool = features.enabled(Feature::UnifiedExec);
|
||||||
let include_plan_tool = features.enabled(Feature::PlanTool);
|
|
||||||
let include_apply_patch_tool = features.enabled(Feature::ApplyPatchFreeform);
|
let include_apply_patch_tool = features.enabled(Feature::ApplyPatchFreeform);
|
||||||
let include_web_search_request = features.enabled(Feature::WebSearchRequest);
|
let include_web_search_request = features.enabled(Feature::WebSearchRequest);
|
||||||
let include_view_image_tool = features.enabled(Feature::ViewImageTool);
|
let include_view_image_tool = features.enabled(Feature::ViewImageTool);
|
||||||
@@ -73,7 +71,6 @@ impl ToolsConfig {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
shell_type,
|
shell_type,
|
||||||
plan_tool: include_plan_tool,
|
|
||||||
apply_patch_tool_type,
|
apply_patch_tool_type,
|
||||||
web_search_request: include_web_search_request,
|
web_search_request: include_web_search_request,
|
||||||
include_view_image_tool,
|
include_view_image_tool,
|
||||||
@@ -870,10 +867,8 @@ pub(crate) fn build_specs(
|
|||||||
builder.register_handler("list_mcp_resource_templates", mcp_resource_handler.clone());
|
builder.register_handler("list_mcp_resource_templates", mcp_resource_handler.clone());
|
||||||
builder.register_handler("read_mcp_resource", mcp_resource_handler);
|
builder.register_handler("read_mcp_resource", mcp_resource_handler);
|
||||||
|
|
||||||
if config.plan_tool {
|
builder.push_spec(PLAN_TOOL.clone());
|
||||||
builder.push_spec(PLAN_TOOL.clone());
|
builder.register_handler("update_plan", plan_handler);
|
||||||
builder.register_handler("update_plan", plan_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(apply_patch_tool_type) = &config.apply_patch_tool_type {
|
if let Some(apply_patch_tool_type) = &config.apply_patch_tool_type {
|
||||||
match apply_patch_tool_type {
|
match apply_patch_tool_type {
|
||||||
@@ -1006,7 +1001,6 @@ mod tests {
|
|||||||
let model_family = find_family_for_model("codex-mini-latest")
|
let model_family = find_family_for_model("codex-mini-latest")
|
||||||
.expect("codex-mini-latest should be a valid model family");
|
.expect("codex-mini-latest should be a valid model family");
|
||||||
let mut features = Features::with_defaults();
|
let mut features = Features::with_defaults();
|
||||||
features.enable(Feature::PlanTool);
|
|
||||||
features.enable(Feature::WebSearchRequest);
|
features.enable(Feature::WebSearchRequest);
|
||||||
features.enable(Feature::UnifiedExec);
|
features.enable(Feature::UnifiedExec);
|
||||||
let config = ToolsConfig::new(&ToolsConfigParams {
|
let config = ToolsConfig::new(&ToolsConfigParams {
|
||||||
@@ -1033,7 +1027,6 @@ mod tests {
|
|||||||
fn test_build_specs_default_shell() {
|
fn test_build_specs_default_shell() {
|
||||||
let model_family = find_family_for_model("o3").expect("o3 should be a valid model family");
|
let model_family = find_family_for_model("o3").expect("o3 should be a valid model family");
|
||||||
let mut features = Features::with_defaults();
|
let mut features = Features::with_defaults();
|
||||||
features.enable(Feature::PlanTool);
|
|
||||||
features.enable(Feature::WebSearchRequest);
|
features.enable(Feature::WebSearchRequest);
|
||||||
features.enable(Feature::UnifiedExec);
|
features.enable(Feature::UnifiedExec);
|
||||||
let config = ToolsConfig::new(&ToolsConfigParams {
|
let config = ToolsConfig::new(&ToolsConfigParams {
|
||||||
@@ -1162,6 +1155,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
"test_server/do_something_cool",
|
"test_server/do_something_cool",
|
||||||
@@ -1281,6 +1275,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"view_image",
|
"view_image",
|
||||||
"test_server/cool",
|
"test_server/cool",
|
||||||
"test_server/do",
|
"test_server/do",
|
||||||
@@ -1332,6 +1327,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"apply_patch",
|
"apply_patch",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
@@ -1340,7 +1336,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tools[7].spec,
|
tools[8].spec,
|
||||||
ToolSpec::Function(ResponsesApiTool {
|
ToolSpec::Function(ResponsesApiTool {
|
||||||
name: "dash/search".to_string(),
|
name: "dash/search".to_string(),
|
||||||
parameters: JsonSchema::Object {
|
parameters: JsonSchema::Object {
|
||||||
@@ -1400,6 +1396,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"apply_patch",
|
"apply_patch",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
@@ -1407,7 +1404,7 @@ mod tests {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tools[7].spec,
|
tools[8].spec,
|
||||||
ToolSpec::Function(ResponsesApiTool {
|
ToolSpec::Function(ResponsesApiTool {
|
||||||
name: "dash/paginate".to_string(),
|
name: "dash/paginate".to_string(),
|
||||||
parameters: JsonSchema::Object {
|
parameters: JsonSchema::Object {
|
||||||
@@ -1466,6 +1463,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"apply_patch",
|
"apply_patch",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
@@ -1473,7 +1471,7 @@ mod tests {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tools[7].spec,
|
tools[8].spec,
|
||||||
ToolSpec::Function(ResponsesApiTool {
|
ToolSpec::Function(ResponsesApiTool {
|
||||||
name: "dash/tags".to_string(),
|
name: "dash/tags".to_string(),
|
||||||
parameters: JsonSchema::Object {
|
parameters: JsonSchema::Object {
|
||||||
@@ -1534,6 +1532,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"apply_patch",
|
"apply_patch",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
@@ -1541,7 +1540,7 @@ mod tests {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tools[7].spec,
|
tools[8].spec,
|
||||||
ToolSpec::Function(ResponsesApiTool {
|
ToolSpec::Function(ResponsesApiTool {
|
||||||
name: "dash/value".to_string(),
|
name: "dash/value".to_string(),
|
||||||
parameters: JsonSchema::Object {
|
parameters: JsonSchema::Object {
|
||||||
@@ -1639,6 +1638,7 @@ mod tests {
|
|||||||
"list_mcp_resources",
|
"list_mcp_resources",
|
||||||
"list_mcp_resource_templates",
|
"list_mcp_resource_templates",
|
||||||
"read_mcp_resource",
|
"read_mcp_resource",
|
||||||
|
"update_plan",
|
||||||
"apply_patch",
|
"apply_patch",
|
||||||
"web_search",
|
"web_search",
|
||||||
"view_image",
|
"view_image",
|
||||||
@@ -1647,7 +1647,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tools[7].spec,
|
tools[8].spec,
|
||||||
ToolSpec::Function(ResponsesApiTool {
|
ToolSpec::Function(ResponsesApiTool {
|
||||||
name: "test_server/do_something_cool".to_string(),
|
name: "test_server/do_something_cool".to_string(),
|
||||||
parameters: JsonSchema::Object {
|
parameters: JsonSchema::Object {
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ async fn collect_tool_identifiers_for_model(model: &str) -> Vec<String> {
|
|||||||
config.model = model.to_string();
|
config.model = model.to_string();
|
||||||
config.model_family =
|
config.model_family =
|
||||||
find_family_for_model(model).unwrap_or_else(|| panic!("unknown model family for {model}"));
|
find_family_for_model(model).unwrap_or_else(|| panic!("unknown model family for {model}"));
|
||||||
config.features.disable(Feature::PlanTool);
|
|
||||||
config.features.disable(Feature::ApplyPatchFreeform);
|
config.features.disable(Feature::ApplyPatchFreeform);
|
||||||
config.features.disable(Feature::ViewImageTool);
|
config.features.disable(Feature::ViewImageTool);
|
||||||
config.features.disable(Feature::WebSearchRequest);
|
config.features.disable(Feature::WebSearchRequest);
|
||||||
@@ -98,7 +97,8 @@ async fn model_selects_expected_tools() {
|
|||||||
"local_shell".to_string(),
|
"local_shell".to_string(),
|
||||||
"list_mcp_resources".to_string(),
|
"list_mcp_resources".to_string(),
|
||||||
"list_mcp_resource_templates".to_string(),
|
"list_mcp_resource_templates".to_string(),
|
||||||
"read_mcp_resource".to_string()
|
"read_mcp_resource".to_string(),
|
||||||
|
"update_plan".to_string()
|
||||||
],
|
],
|
||||||
"codex-mini-latest should expose the local shell tool",
|
"codex-mini-latest should expose the local shell tool",
|
||||||
);
|
);
|
||||||
@@ -110,7 +110,8 @@ async fn model_selects_expected_tools() {
|
|||||||
"shell".to_string(),
|
"shell".to_string(),
|
||||||
"list_mcp_resources".to_string(),
|
"list_mcp_resources".to_string(),
|
||||||
"list_mcp_resource_templates".to_string(),
|
"list_mcp_resource_templates".to_string(),
|
||||||
"read_mcp_resource".to_string()
|
"read_mcp_resource".to_string(),
|
||||||
|
"update_plan".to_string()
|
||||||
],
|
],
|
||||||
"o3 should expose the generic shell tool",
|
"o3 should expose the generic shell tool",
|
||||||
);
|
);
|
||||||
@@ -123,6 +124,7 @@ async fn model_selects_expected_tools() {
|
|||||||
"list_mcp_resources".to_string(),
|
"list_mcp_resources".to_string(),
|
||||||
"list_mcp_resource_templates".to_string(),
|
"list_mcp_resource_templates".to_string(),
|
||||||
"read_mcp_resource".to_string(),
|
"read_mcp_resource".to_string(),
|
||||||
|
"update_plan".to_string(),
|
||||||
"apply_patch".to_string()
|
"apply_patch".to_string()
|
||||||
],
|
],
|
||||||
"gpt-5-codex should expose the apply_patch tool",
|
"gpt-5-codex should expose the apply_patch tool",
|
||||||
|
|||||||
@@ -186,7 +186,6 @@ async fn prompt_tools_are_consistent_across_requests() {
|
|||||||
config.cwd = cwd.path().to_path_buf();
|
config.cwd = cwd.path().to_path_buf();
|
||||||
config.model_provider = model_provider;
|
config.model_provider = model_provider;
|
||||||
config.user_instructions = Some("be consistent and helpful".to_string());
|
config.user_instructions = Some("be consistent and helpful".to_string());
|
||||||
config.features.enable(Feature::PlanTool);
|
|
||||||
|
|
||||||
let conversation_manager =
|
let conversation_manager =
|
||||||
ConversationManager::with_auth(CodexAuth::from_api_key("Test API Key"));
|
ConversationManager::with_auth(CodexAuth::from_api_key("Test API Key"));
|
||||||
|
|||||||
@@ -106,9 +106,7 @@ async fn update_plan_tool_emits_plan_update_event() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let server = start_mock_server().await;
|
let server = start_mock_server().await;
|
||||||
|
|
||||||
let mut builder = test_codex().with_config(|config| {
|
let mut builder = test_codex();
|
||||||
config.features.enable(Feature::PlanTool);
|
|
||||||
});
|
|
||||||
let TestCodex {
|
let TestCodex {
|
||||||
codex,
|
codex,
|
||||||
cwd,
|
cwd,
|
||||||
@@ -193,9 +191,7 @@ async fn update_plan_tool_rejects_malformed_payload() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
let server = start_mock_server().await;
|
let server = start_mock_server().await;
|
||||||
|
|
||||||
let mut builder = test_codex().with_config(|config| {
|
let mut builder = test_codex();
|
||||||
config.features.enable(Feature::PlanTool);
|
|
||||||
});
|
|
||||||
let TestCodex {
|
let TestCodex {
|
||||||
codex,
|
codex,
|
||||||
cwd,
|
cwd,
|
||||||
|
|||||||
@@ -67,10 +67,6 @@ pub struct Cli {
|
|||||||
#[arg(long = "json", alias = "experimental-json", default_value_t = false)]
|
#[arg(long = "json", alias = "experimental-json", default_value_t = false)]
|
||||||
pub json: bool,
|
pub json: bool,
|
||||||
|
|
||||||
/// Whether to include the plan tool in the conversation.
|
|
||||||
#[arg(long = "include-plan-tool")]
|
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
|
|
||||||
/// Specifies file where the last message from the agent should be written.
|
/// Specifies file where the last message from the agent should be written.
|
||||||
#[arg(long = "output-last-message", short = 'o', value_name = "FILE")]
|
#[arg(long = "output-last-message", short = 'o', value_name = "FILE")]
|
||||||
pub last_message_file: Option<PathBuf>,
|
pub last_message_file: Option<PathBuf>,
|
||||||
|
|||||||
@@ -70,14 +70,9 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> any
|
|||||||
sandbox_mode: sandbox_mode_cli_arg,
|
sandbox_mode: sandbox_mode_cli_arg,
|
||||||
prompt,
|
prompt,
|
||||||
output_schema: output_schema_path,
|
output_schema: output_schema_path,
|
||||||
include_plan_tool,
|
|
||||||
config_overrides,
|
config_overrides,
|
||||||
} = cli;
|
} = cli;
|
||||||
|
|
||||||
if include_plan_tool.is_some() {
|
|
||||||
eprintln!("include-plan-tool is deprecated. Plan tool is now enabled by default.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the prompt source (parent or subcommand) and read from stdin if needed.
|
// Determine the prompt source (parent or subcommand) and read from stdin if needed.
|
||||||
let prompt_arg = match &command {
|
let prompt_arg = match &command {
|
||||||
// Allow prompt before the subcommand by falling back to the parent-level prompt
|
// Allow prompt before the subcommand by falling back to the parent-level prompt
|
||||||
@@ -181,7 +176,6 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> any
|
|||||||
model_provider,
|
model_provider,
|
||||||
codex_linux_sandbox_exe,
|
codex_linux_sandbox_exe,
|
||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
include_plan_tool: Some(include_plan_tool.unwrap_or(true)),
|
|
||||||
include_apply_patch_tool: None,
|
include_apply_patch_tool: None,
|
||||||
include_view_image_tool: None,
|
include_view_image_tool: None,
|
||||||
show_raw_agent_reasoning: oss.then_some(true),
|
show_raw_agent_reasoning: oss.then_some(true),
|
||||||
|
|||||||
@@ -49,10 +49,6 @@ pub struct CodexToolCallParam {
|
|||||||
/// The set of instructions to use instead of the default ones.
|
/// The set of instructions to use instead of the default ones.
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||||
pub base_instructions: Option<String>,
|
pub base_instructions: Option<String>,
|
||||||
|
|
||||||
/// Whether to include the plan tool in the conversation.
|
|
||||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
||||||
pub include_plan_tool: Option<bool>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom enum mirroring [`AskForApproval`], but has an extra dependency on
|
/// Custom enum mirroring [`AskForApproval`], but has an extra dependency on
|
||||||
@@ -145,7 +141,6 @@ impl CodexToolCallParam {
|
|||||||
sandbox,
|
sandbox,
|
||||||
config: cli_overrides,
|
config: cli_overrides,
|
||||||
base_instructions,
|
base_instructions,
|
||||||
include_plan_tool,
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
// Build the `ConfigOverrides` recognized by codex-core.
|
// Build the `ConfigOverrides` recognized by codex-core.
|
||||||
@@ -159,7 +154,6 @@ impl CodexToolCallParam {
|
|||||||
model_provider: None,
|
model_provider: None,
|
||||||
codex_linux_sandbox_exe,
|
codex_linux_sandbox_exe,
|
||||||
base_instructions,
|
base_instructions,
|
||||||
include_plan_tool,
|
|
||||||
include_apply_patch_tool: None,
|
include_apply_patch_tool: None,
|
||||||
include_view_image_tool: None,
|
include_view_image_tool: None,
|
||||||
show_raw_agent_reasoning: None,
|
show_raw_agent_reasoning: None,
|
||||||
@@ -277,10 +271,6 @@ mod tests {
|
|||||||
"description": "Working directory for the session. If relative, it is resolved against the server process's current working directory.",
|
"description": "Working directory for the session. If relative, it is resolved against the server process's current working directory.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"include-plan-tool": {
|
|
||||||
"description": "Whether to include the plan tool in the conversation.",
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"model": {
|
"model": {
|
||||||
"description": "Optional override for the model name (e.g. \"o3\", \"o4-mini\").",
|
"description": "Optional override for the model name (e.g. \"o3\", \"o4-mini\").",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ pub async fn run_main(
|
|||||||
config_profile: cli.config_profile.clone(),
|
config_profile: cli.config_profile.clone(),
|
||||||
codex_linux_sandbox_exe,
|
codex_linux_sandbox_exe,
|
||||||
base_instructions: None,
|
base_instructions: None,
|
||||||
include_plan_tool: Some(true),
|
|
||||||
include_apply_patch_tool: None,
|
include_apply_patch_tool: None,
|
||||||
include_view_image_tool: None,
|
include_view_image_tool: None,
|
||||||
show_raw_agent_reasoning: cli.oss.then_some(true),
|
show_raw_agent_reasoning: cli.oss.then_some(true),
|
||||||
|
|||||||
10
scripts/debug-codex.sh
Executable file
10
scripts/debug-codex.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Set "chatgpt.cliExecutable": "/Users/<USERNAME>/code/codex/scripts/debug-codex.sh" in VSCode settings to always get the
|
||||||
|
# latest codex-rs binary when debugging Codex Extension.
|
||||||
|
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
CODEX_RS_DIR=$(realpath "$(dirname "$0")/../codex-rs")
|
||||||
|
(cd "$CODEX_RS_DIR" && cargo run --quiet --bin codex -- "$@")
|
||||||
Reference in New Issue
Block a user