chore(features) rm Feature::ApplyPatchFreeform (#22711)

## Summary
Removes the feature since this is effectively on by default in all cases
where we should use it, or can be configured via models.json.

## Testing
- [x] unit tests pass
This commit is contained in:
Dylan Hurd
2026-05-14 16:15:56 -07:00
committed by GitHub
parent 7c11c14efc
commit 51b0e94105
28 changed files with 71 additions and 172 deletions
-11
View File
@@ -21,10 +21,6 @@ const ALIASES: &[Alias] = &[
legacy_key: "experimental_use_unified_exec_tool",
feature: Feature::UnifiedExec,
},
Alias {
legacy_key: "include_apply_patch_tool",
feature: Feature::ApplyPatchFreeform,
},
Alias {
legacy_key: "request_permissions",
feature: Feature::ExecPermissionApprovals,
@@ -67,18 +63,11 @@ pub(crate) fn feature_for_key(key: &str) -> Option<Feature> {
#[derive(Debug, Default)]
pub(crate) struct LegacyFeatureToggles {
pub include_apply_patch_tool: Option<bool>,
pub experimental_use_unified_exec_tool: Option<bool>,
}
impl LegacyFeatureToggles {
pub fn apply(self, features: &mut Features) {
set_if_some(
features,
Feature::ApplyPatchFreeform,
self.include_apply_patch_tool,
"include_apply_patch_tool",
);
set_if_some(
features,
Feature::UnifiedExec,
+6 -5
View File
@@ -99,7 +99,7 @@ pub enum Feature {
ShellZshFork,
/// Reflow transcript scrollback when the terminal is resized.
TerminalResizeReflow,
/// Include the freeform apply_patch tool.
/// Removed compatibility flag for the deleted apply_patch fallback feature.
ApplyPatchFreeform,
/// Stream structured progress while apply_patch input is being generated.
ApplyPatchStreamingEvents,
@@ -292,7 +292,6 @@ pub struct FeatureOverrides {
#[derive(Debug, Clone, Copy, Default)]
pub struct FeatureConfigSource<'a> {
pub features: Option<&'a FeaturesToml>,
pub include_apply_patch_tool: Option<bool>,
pub experimental_use_unified_exec_tool: Option<bool>,
}
@@ -424,6 +423,9 @@ impl Features {
"remote_control" => {
continue;
}
"apply_patch_freeform" => {
continue;
}
"image_detail_original" => {
continue;
}
@@ -465,7 +467,6 @@ impl Features {
for source in [base, profile] {
LegacyFeatureToggles {
include_apply_patch_tool: source.include_apply_patch_tool,
experimental_use_unified_exec_tool: source.experimental_use_unified_exec_tool,
}
.apply(&mut features);
@@ -822,8 +823,8 @@ pub const FEATURES: &[FeatureSpec] = &[
FeatureSpec {
id: Feature::ApplyPatchFreeform,
key: "apply_patch_freeform",
stage: Stage::Stable,
default_enabled: true,
stage: Stage::Removed,
default_enabled: false,
},
FeatureSpec {
id: Feature::ApplyPatchStreamingEvents,
+30 -5
View File
@@ -66,6 +66,16 @@ fn image_detail_original_is_removed_and_disabled_by_default() {
assert_eq!(Feature::ImageDetailOriginal.default_enabled(), false);
}
#[test]
fn apply_patch_freeform_is_removed_and_disabled_by_default() {
assert_eq!(Feature::ApplyPatchFreeform.stage(), Stage::Removed);
assert_eq!(Feature::ApplyPatchFreeform.default_enabled(), false);
assert_eq!(
feature_for_key("apply_patch_freeform"),
Some(Feature::ApplyPatchFreeform)
);
}
#[test]
fn code_mode_only_requires_code_mode() {
let mut features = Features::with_defaults();
@@ -403,7 +413,6 @@ fn from_sources_applies_base_profile_and_overrides() {
},
FeatureConfigSource {
features: Some(&profile_features),
include_apply_patch_tool: Some(true),
..Default::default()
},
FeatureOverrides {
@@ -414,7 +423,7 @@ fn from_sources_applies_base_profile_and_overrides() {
assert_eq!(features.enabled(Feature::Plugins), true);
assert_eq!(features.enabled(Feature::CodeModeOnly), true);
assert_eq!(features.enabled(Feature::CodeMode), true);
assert_eq!(features.enabled(Feature::ApplyPatchFreeform), true);
assert_eq!(features.enabled(Feature::ApplyPatchFreeform), false);
assert_eq!(features.enabled(Feature::WebSearchRequest), false);
}
@@ -472,6 +481,23 @@ fn from_sources_ignores_removed_js_repl_feature_keys() {
assert_eq!(features, Features::with_defaults());
}
#[test]
fn from_sources_ignores_removed_apply_patch_freeform_feature_key() {
let features_toml =
FeaturesToml::from(BTreeMap::from([("apply_patch_freeform".to_string(), true)]));
let features = Features::from_sources(
FeatureConfigSource {
features: Some(&features_toml),
..Default::default()
},
FeatureConfigSource::default(),
FeatureOverrides::default(),
);
assert_eq!(features, Features::with_defaults());
}
#[test]
fn multi_agent_v2_feature_config_deserializes_boolean_toggle() {
let features: FeaturesToml = toml::from_str(
@@ -587,14 +613,13 @@ fn materialize_resolved_enabled_writes_all_features_and_preserves_custom_config(
proxy_url: Some("http://127.0.0.1:43128".to_string()),
..Default::default()
})),
entries: BTreeMap::from([("include_apply_patch_tool".to_string(), true)]),
entries: BTreeMap::new(),
..Default::default()
};
features_toml.materialize_resolved_enabled(&features);
let entries = features_toml.entries();
assert_eq!(entries.get("include_apply_patch_tool"), None);
for spec in crate::FEATURES {
assert_eq!(
entries.get(spec.key),
@@ -627,7 +652,7 @@ fn materialize_resolved_enabled_writes_all_features_and_preserves_custom_config(
FeatureConfigSource::default(),
FeatureOverrides::default(),
);
assert_eq!(replayed.enabled(Feature::ApplyPatchFreeform), true);
assert_eq!(replayed.enabled(Feature::ApplyPatchFreeform), false);
}
#[test]