Remove `AgentV2FeatureFlag` (#54430)

Bennet Bo Fenner created

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- N/A

Change summary

Cargo.lock                              |  1 
crates/agent_ui/src/agent_panel.rs      |  7 --
crates/agent_ui/src/agent_ui.rs         | 39 +--------------
crates/feature_flags/src/flags.rs       | 12 ----
crates/settings_ui/src/page_data.rs     | 65 +++++++++++---------------
crates/workspace/Cargo.toml             |  1 
crates/workspace/src/multi_workspace.rs |  4 -
crates/zed/src/zed/open_listener.rs     |  6 --
8 files changed, 33 insertions(+), 102 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -21778,7 +21778,6 @@ dependencies = [
  "postage",
  "pretty_assertions",
  "project",
- "release_channel",
  "remote",
  "schemars",
  "serde",

crates/agent_ui/src/agent_panel.rs 🔗

@@ -67,7 +67,6 @@ use language::LanguageRegistry;
 use language_model::LanguageModelRegistry;
 use project::{Project, ProjectPath, Worktree};
 use prompt_store::{PromptStore, UserPromptId};
-use release_channel::ReleaseChannel;
 use rules_library::{RulesLibrary, open_rules_library};
 use settings::TerminalDockPosition;
 use settings::{Settings, update_settings_file};
@@ -89,9 +88,6 @@ const AGENT_PANEL_KEY: &str = "agent_panel";
 const MIN_PANEL_WIDTH: Pixels = px(300.);
 const LAST_USED_AGENT_KEY: &str = "agent_panel__last_used_external_agent";
 
-fn agent_v2_enabled(cx: &App) -> bool {
-    !matches!(ReleaseChannel::try_global(cx), Some(ReleaseChannel::Stable))
-}
 /// Maximum number of idle threads kept in the agent panel's retained list.
 /// Set as a GPUI global to override; otherwise defaults to 5.
 pub struct MaxIdleRetainedThreads(pub usize);
@@ -3213,7 +3209,6 @@ impl AgentPanel {
             selected_agent.into_any_element()
         };
 
-        let agent_v2_enabled = agent_v2_enabled(cx);
         let is_empty_state = !self.active_thread_has_messages(cx);
 
         let is_in_history_or_config = self.is_overlay_open();
@@ -3235,7 +3230,7 @@ impl AgentPanel {
                 }))
         };
 
-        let use_v2_empty_toolbar = agent_v2_enabled && is_empty_state && !is_in_history_or_config;
+        let use_v2_empty_toolbar = is_empty_state && !is_in_history_or_config;
 
         let max_content_width = AgentSettings::get_global(cx).max_content_width;
 

crates/agent_ui/src/agent_ui.rs 🔗

@@ -43,7 +43,7 @@ use agent_settings::{AgentProfileId, AgentSettings};
 use command_palette_hooks::CommandPaletteFilter;
 use feature_flags::FeatureFlagAppExt as _;
 use fs::Fs;
-use gpui::{Action, App, Context, Entity, SharedString, UpdateGlobal as _, Window, actions};
+use gpui::{Action, App, Context, Entity, SharedString, Window, actions};
 use language::{
     LanguageRegistry,
     language_settings::{AllLanguageSettings, EditPredictionProvider},
@@ -53,10 +53,9 @@ use language_model::{
 };
 use project::{AgentId, DisableAiSettings};
 use prompt_store::PromptBuilder;
-use release_channel::ReleaseChannel;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
-use settings::{DockPosition, DockSide, LanguageModelSelection, Settings as _, SettingsStore};
+use settings::{LanguageModelSelection, Settings as _, SettingsStore};
 use std::any::TypeId;
 use workspace::Workspace;
 
@@ -500,34 +499,7 @@ pub fn init(
     })
     .detach();
 
-    let agent_v2_enabled = agent_v2_enabled(cx);
-    if agent_v2_enabled {
-        maybe_backfill_editor_layout(fs, is_new_install, cx);
-    }
-
-    SettingsStore::update_global(cx, |store, cx| {
-        store.update_default_settings(cx, |defaults| {
-            if agent_v2_enabled {
-                defaults.agent.get_or_insert_default().dock = Some(DockPosition::Left);
-                defaults.project_panel.get_or_insert_default().dock = Some(DockSide::Right);
-                defaults.outline_panel.get_or_insert_default().dock = Some(DockSide::Right);
-                defaults.collaboration_panel.get_or_insert_default().dock =
-                    Some(DockPosition::Right);
-                defaults.git_panel.get_or_insert_default().dock = Some(DockPosition::Right);
-            } else {
-                defaults.agent.get_or_insert_default().dock = Some(DockPosition::Right);
-                defaults.project_panel.get_or_insert_default().dock = Some(DockSide::Left);
-                defaults.outline_panel.get_or_insert_default().dock = Some(DockSide::Left);
-                defaults.collaboration_panel.get_or_insert_default().dock =
-                    Some(DockPosition::Left);
-                defaults.git_panel.get_or_insert_default().dock = Some(DockPosition::Left);
-            }
-        });
-    });
-}
-
-fn agent_v2_enabled(cx: &App) -> bool {
-    !matches!(ReleaseChannel::try_global(cx), Some(ReleaseChannel::Stable))
+    maybe_backfill_editor_layout(fs, is_new_install, cx);
 }
 
 fn maybe_backfill_editor_layout(fs: Arc<dyn Fs>, is_new_install: bool, cx: &mut App) {
@@ -555,7 +527,6 @@ fn maybe_backfill_editor_layout(fs: Arc<dyn Fs>, is_new_install: bool, cx: &mut
 fn update_command_palette_filter(cx: &mut App) {
     let disable_ai = DisableAiSettings::get_global(cx).disable_ai;
     let agent_enabled = AgentSettings::get_global(cx).enabled;
-    let agent_v2_enabled = agent_v2_enabled(cx);
 
     let edit_prediction_provider = AllLanguageSettings::get_global(cx)
         .edit_predictions
@@ -623,12 +594,8 @@ fn update_command_palette_filter(cx: &mut App) {
 
             filter.show_namespace("zed_predict_onboarding");
             filter.show_action_types(&[TypeId::of::<zed_actions::OpenZedPredictOnboarding>()]);
-        }
 
-        if agent_v2_enabled {
             filter.show_namespace("multi_workspace");
-        } else {
-            filter.hide_namespace("multi_workspace");
         }
     });
 }

crates/feature_flags/src/flags.rs 🔗

@@ -16,18 +16,6 @@ impl FeatureFlag for PanicFeatureFlag {
 }
 register_feature_flag!(PanicFeatureFlag);
 
-pub struct AgentV2FeatureFlag;
-
-impl FeatureFlag for AgentV2FeatureFlag {
-    const NAME: &'static str = "agent-v2";
-    type Value = PresenceFlag;
-
-    fn enabled_for_staff() -> bool {
-        true
-    }
-}
-register_feature_flag!(AgentV2FeatureFlag);
-
 /// A feature flag for granting access to beta ACP features.
 ///
 /// We reuse this feature flag for new betas, so don't delete it if it is not currently in use.

crates/settings_ui/src/page_data.rs 🔗

@@ -1,6 +1,5 @@
 use gpui::{Action as _, App};
 use itertools::Itertools as _;
-use release_channel::ReleaseChannel;
 use settings::{
     AudioInputDeviceName, AudioOutputDeviceName, LanguageSettingsContent, SemanticTokens,
     SettingsContent,
@@ -106,8 +105,8 @@ fn developer_page() -> SettingsPage {
 }
 
 fn general_page(cx: &App) -> SettingsPage {
-    fn general_settings_section(cx: &App) -> Vec<SettingsPageItem> {
-        let mut items = vec![
+    fn general_settings_section(_cx: &App) -> Vec<SettingsPageItem> {
+        vec![
             SettingsPageItem::SectionHeader("General Settings"),
             SettingsPageItem::SettingItem(SettingItem {
                 files: PROJECT,
@@ -225,11 +224,7 @@ fn general_page(cx: &App) -> SettingsPage {
                 metadata: None,
                 files: USER,
             }),
-        ];
-
-        use feature_flags::FeatureFlagAppExt;
-        if cx.has_flag::<feature_flags::AgentV2FeatureFlag>() {
-            items.push(SettingsPageItem::SettingItem(SettingItem {
+            SettingsPageItem::SettingItem(SettingItem {
                 title: "CLI Default Open Behavior",
                 description: "How `zed <path>` opens directories when no flag is specified.",
                 field: Box::new(SettingField {
@@ -249,10 +244,8 @@ fn general_page(cx: &App) -> SettingsPage {
                     ..Default::default()
                 })),
                 files: USER,
-            }));
-        }
-
-        items
+            }),
+        ]
     }
     fn security_section() -> [SettingsPageItem; 2] {
         [
@@ -7373,7 +7366,7 @@ fn ai_page(cx: &App) -> SettingsPage {
         ]
     }
 
-    fn agent_configuration_section(cx: &App) -> Box<[SettingsPageItem]> {
+    fn agent_configuration_section(_cx: &App) -> Box<[SettingsPageItem]> {
         let mut items = vec![
             SettingsPageItem::SectionHeader("Agent Configuration"),
             SettingsPageItem::SubPageLink(SubPageLink {
@@ -7387,30 +7380,28 @@ fn ai_page(cx: &App) -> SettingsPage {
             }),
         ];
 
-        if !matches!(ReleaseChannel::try_global(cx), Some(ReleaseChannel::Stable)) {
-            items.push(SettingsPageItem::SettingItem(SettingItem {
-                title: "New Thread Location",
-                description: "Whether to start a new thread in the current local project or in a new Git worktree.",
-                field: Box::new(SettingField {
-                    json_path: Some("agent.new_thread_location"),
-                    pick: |settings_content| {
-                        settings_content
-                            .agent
-                            .as_ref()?
-                            .new_thread_location
-                            .as_ref()
-                    },
-                    write: |settings_content, value| {
-                        settings_content
-                            .agent
-                            .get_or_insert_default()
-                            .new_thread_location = value;
-                    },
-                }),
-                metadata: None,
-                files: USER,
-            }));
-        }
+        items.push(SettingsPageItem::SettingItem(SettingItem {
+            title: "New Thread Location",
+            description: "Whether to start a new thread in the current local project or in a new Git worktree.",
+            field: Box::new(SettingField {
+                json_path: Some("agent.new_thread_location"),
+                pick: |settings_content| {
+                    settings_content
+                        .agent
+                        .as_ref()?
+                        .new_thread_location
+                        .as_ref()
+                },
+                write: |settings_content, value| {
+                    settings_content
+                        .agent
+                        .get_or_insert_default()
+                        .new_thread_location = value;
+                },
+            }),
+            metadata: None,
+            files: USER,
+        }));
 
         items.extend([
             SettingsPageItem::SettingItem(SettingItem {

crates/workspace/Cargo.toml 🔗

@@ -50,7 +50,6 @@ node_runtime.workspace = true
 parking_lot.workspace = true
 postage.workspace = true
 project.workspace = true
-release_channel.workspace = true
 remote.workspace = true
 schemars.workspace = true
 serde.workspace = true

crates/workspace/src/multi_workspace.rs 🔗

@@ -8,7 +8,6 @@ use gpui::{
 };
 pub use project::ProjectGroupKey;
 use project::{DisableAiSettings, Project};
-use release_channel::ReleaseChannel;
 use remote::RemoteConnectionOptions;
 use settings::Settings;
 pub use settings::SidebarSide;
@@ -397,8 +396,7 @@ impl MultiWorkspace {
     }
 
     pub fn multi_workspace_enabled(&self, cx: &App) -> bool {
-        !matches!(ReleaseChannel::try_global(cx), Some(ReleaseChannel::Stable))
-            && !DisableAiSettings::get_global(cx).disable_ai
+        !DisableAiSettings::get_global(cx).disable_ai
     }
 
     pub fn toggle_sidebar(&mut self, window: &mut Window, cx: &mut Context<Self>) {

crates/zed/src/zed/open_listener.rs 🔗

@@ -12,7 +12,6 @@ use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender};
 use futures::channel::{mpsc, oneshot};
 use futures::future;
 
-use feature_flags::FeatureFlagAppExt as _;
 use futures::{FutureExt, StreamExt};
 use git_ui::{file_diff_view::FileDiffView, multi_diff_view::MultiDiffView};
 use gpui::{App, AsyncApp, Global, WindowHandle};
@@ -558,11 +557,6 @@ async fn resolve_open_behavior(
     requests: &mut mpsc::UnboundedReceiver<CliRequest>,
     cx: &mut AsyncApp,
 ) -> Option<settings::CliDefaultOpenBehavior> {
-    let cli_prompt_enabled = cx.update(|cx| cx.has_flag::<feature_flags::AgentV2FeatureFlag>());
-    if !cli_prompt_enabled {
-        return Some(settings::CliDefaultOpenBehavior::NewWindow);
-    }
-
     let has_existing_windows = cx.update(|cx| {
         cx.windows()
             .iter()