Remove Agents Panel and utility panes (#49038)

Richard Feldman created

Remove the `AgentsPanel` (from the `agent_ui_v2` crate) and the utility
pane infrastructure from the codebase.

The Agents Panel was a separate panel gated behind the `agent-v2`
feature flag that was redundant with the existing Agent Panel. Utility
panes were a layout concept (secondary panes next to the editor,
separate from dock panels) whose only consumer was `AgentThreadPane` in
the Agents Panel.

### Changes
- Deleted the entire `agent_ui_v2` crate (`agents_panel.rs`,
`agent_thread_pane.rs`)
- Deleted `workspace/src/utility_pane.rs`
- Removed `UtilityPane`, `UtilityPaneHandle`, `UtilityPanePosition`,
`MinimizePane`, `ClosePane` from `workspace/src/dock.rs`
- Removed all utility pane fields, methods, and render blocks from
`workspace.rs`
- Removed all aside toggle code from `pane.rs` and `pane_group.rs`
- Removed `agents_panel_dock` setting from agent settings and
`default.json`
- Removed all `agent_ui_v2` references from `main.rs`, `zed.rs`, and
Cargo.toml files
- Cleaned up test code in `tool_permissions.rs` and `agent_ui.rs`

Closes AI-17

(No release notes because this was all feature-flagged.)

Release Notes:

- N/A

Change summary

Cargo.lock                                  |  27 -
Cargo.toml                                  |   2 
assets/settings/default.json                |   2 
crates/agent/src/tool_permissions.rs        |   3 
crates/agent_settings/src/agent_settings.rs |   4 
crates/agent_ui/src/agent_ui.rs             |   6 
crates/agent_ui_v2/Cargo.toml               |  42 --
crates/agent_ui_v2/LICENSE-GPL              |   1 
crates/agent_ui_v2/src/agent_thread_pane.rs | 284 -------------
crates/agent_ui_v2/src/agent_ui_v2.rs       |   3 
crates/agent_ui_v2/src/agents_panel.rs      | 481 -----------------------
crates/settings_content/src/agent.rs        |   6 
crates/ui/src/components/tab_bar.rs         |  48 -
crates/workspace/src/dock.rs                |  66 ---
crates/workspace/src/pane.rs                | 163 -------
crates/workspace/src/pane_group.rs          |  30 -
crates/workspace/src/utility_pane.rs        | 282 -------------
crates/workspace/src/workspace.rs           | 166 -------
crates/zed/Cargo.toml                       |   2 
crates/zed/src/main.rs                      |   2 
crates/zed/src/zed.rs                       |  46 --
crates/zed_actions/src/lib.rs               |   2 
22 files changed, 39 insertions(+), 1,629 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -433,32 +433,6 @@ dependencies = [
  "zed_actions",
 ]
 
-[[package]]
-name = "agent_ui_v2"
-version = "0.1.0"
-dependencies = [
- "acp_thread",
- "agent",
- "agent-client-protocol",
- "agent_servers",
- "agent_settings",
- "agent_ui",
- "anyhow",
- "db",
- "feature_flags",
- "fs",
- "gpui",
- "log",
- "project",
- "prompt_store",
- "serde",
- "serde_json",
- "settings",
- "ui",
- "util",
- "workspace",
-]
-
 [[package]]
 name = "ahash"
 version = "0.7.8"
@@ -21047,7 +21021,6 @@ dependencies = [
  "agent_servers",
  "agent_settings",
  "agent_ui",
- "agent_ui_v2",
  "anyhow",
  "ashpd",
  "askpass",

Cargo.toml 🔗

@@ -9,7 +9,6 @@ members = [
     "crates/agent_servers",
     "crates/agent_settings",
     "crates/agent_ui",
-    "crates/agent_ui_v2",
     "crates/ai_onboarding",
     "crates/anthropic",
     "crates/askpass",
@@ -255,7 +254,6 @@ action_log = { path = "crates/action_log" }
 agent = { path = "crates/agent" }
 activity_indicator = { path = "crates/activity_indicator" }
 agent_ui = { path = "crates/agent_ui" }
-agent_ui_v2 = { path = "crates/agent_ui_v2" }
 agent_settings = { path = "crates/agent_settings" }
 agent_servers = { path = "crates/agent_servers" }
 ai_onboarding = { path = "crates/ai_onboarding" }

assets/settings/default.json 🔗

@@ -931,8 +931,6 @@
     "button": true,
     // Where to dock the agent panel. Can be 'left', 'right' or 'bottom'.
     "dock": "right",
-    // Where to dock the agents panel. Can be 'left' or 'right'.
-    "agents_panel_dock": "left",
     // Default width when the agent panel is docked to the left or right.
     "default_width": 640,
     // Default height when the agent panel is docked to the bottom.

crates/agent/src/tool_permissions.rs 🔗

@@ -528,7 +528,7 @@ mod tests {
     use crate::tools::{DeletePathTool, EditFileTool, FetchTool, TerminalTool};
     use agent_settings::{AgentProfileId, CompiledRegex, InvalidRegexPattern, ToolRules};
     use gpui::px;
-    use settings::{DefaultAgentView, DockPosition, DockSide, NotifyWhenAgentWaiting};
+    use settings::{DefaultAgentView, DockPosition, NotifyWhenAgentWaiting};
     use std::sync::Arc;
 
     fn test_agent_settings(tool_permissions: ToolPermissions) -> AgentSettings {
@@ -536,7 +536,6 @@ mod tests {
             enabled: true,
             button: true,
             dock: DockPosition::Right,
-            agents_panel_dock: DockSide::Left,
             default_width: px(300.),
             default_height: px(600.),
             default_model: None,

crates/agent_settings/src/agent_settings.rs 🔗

@@ -11,7 +11,7 @@ use project::DisableAiSettings;
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 use settings::{
-    DefaultAgentView, DockPosition, DockSide, LanguageModelParameters, LanguageModelSelection,
+    DefaultAgentView, DockPosition, LanguageModelParameters, LanguageModelSelection,
     NotifyWhenAgentWaiting, RegisterSetting, Settings, ToolPermissionMode,
 };
 
@@ -26,7 +26,6 @@ pub struct AgentSettings {
     pub enabled: bool,
     pub button: bool,
     pub dock: DockPosition,
-    pub agents_panel_dock: DockSide,
     pub default_width: Pixels,
     pub default_height: Pixels,
     pub default_model: Option<LanguageModelSelection>,
@@ -407,7 +406,6 @@ impl Settings for AgentSettings {
             enabled: agent.enabled.unwrap(),
             button: agent.button.unwrap(),
             dock: agent.dock.unwrap(),
-            agents_panel_dock: agent.agents_panel_dock.unwrap(),
             default_width: px(agent.default_width.unwrap()),
             default_height: px(agent.default_height.unwrap()),
             default_model: Some(agent.default_model.unwrap()),

crates/agent_ui/src/agent_ui.rs 🔗

@@ -431,9 +431,6 @@ 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.hide_action_types(&[TypeId::of::<zed_actions::agent::ToggleAgentPane>()]);
-            }
         }
 
         if agent_v2_enabled {
@@ -539,7 +536,7 @@ mod tests {
     use gpui::{BorrowAppContext, TestAppContext, px};
     use project::DisableAiSettings;
     use settings::{
-        DefaultAgentView, DockPosition, DockSide, NotifyWhenAgentWaiting, Settings, SettingsStore,
+        DefaultAgentView, DockPosition, NotifyWhenAgentWaiting, Settings, SettingsStore,
     };
 
     #[gpui::test]
@@ -558,7 +555,6 @@ mod tests {
             enabled: true,
             button: true,
             dock: DockPosition::Right,
-            agents_panel_dock: DockSide::Left,
             default_width: px(300.),
             default_height: px(600.),
             default_model: None,

crates/agent_ui_v2/Cargo.toml 🔗

@@ -1,42 +0,0 @@
-[package]
-name = "agent_ui_v2"
-version = "0.1.0"
-edition.workspace = true
-publish.workspace = true
-license = "GPL-3.0-or-later"
-
-[lints]
-workspace = true
-
-[lib]
-path = "src/agent_ui_v2.rs"
-doctest = false
-
-[features]
-test-support = ["agent/test-support"]
-
-
-[dependencies]
-agent.workspace = true
-acp_thread.workspace = true
-agent-client-protocol.workspace = true
-agent_servers.workspace = true
-agent_settings.workspace = true
-agent_ui.workspace = true
-anyhow.workspace = true
-db.workspace = true
-feature_flags.workspace = true
-fs.workspace = true
-gpui.workspace = true
-log.workspace = true
-project.workspace = true
-prompt_store.workspace = true
-serde.workspace = true
-serde_json.workspace = true
-settings.workspace = true
-ui.workspace = true
-util.workspace = true
-workspace.workspace = true
-
-[dev-dependencies]
-agent = { workspace = true, features = ["test-support"] }

crates/agent_ui_v2/src/agent_thread_pane.rs 🔗

@@ -1,284 +0,0 @@
-use acp_thread::AgentSessionInfo;
-use agent::{NativeAgentServer, ThreadStore};
-use agent_client_protocol as acp;
-use agent_servers::AgentServer;
-use agent_settings::AgentSettings;
-use agent_ui::acp::{AcpServerView, AcpThreadHistory};
-use fs::Fs;
-use gpui::{
-    Entity, EventEmitter, Focusable, Pixels, SharedString, Subscription, WeakEntity, prelude::*,
-};
-use project::Project;
-use prompt_store::PromptStore;
-use serde::{Deserialize, Serialize};
-use settings::DockSide;
-use settings::Settings as _;
-use std::rc::Rc;
-use std::sync::Arc;
-use ui::{Tab, Tooltip, prelude::*};
-use workspace::{
-    Workspace,
-    dock::{ClosePane, MinimizePane, UtilityPane, UtilityPanePosition},
-    utility_pane::UtilityPaneSlot,
-};
-
-pub const DEFAULT_UTILITY_PANE_WIDTH: Pixels = gpui::px(400.0);
-
-#[derive(Serialize, Deserialize, Debug, Clone)]
-pub enum SerializedHistoryEntryId {
-    AcpThread(String),
-}
-
-impl From<acp::SessionId> for SerializedHistoryEntryId {
-    fn from(id: acp::SessionId) -> Self {
-        SerializedHistoryEntryId::AcpThread(id.0.to_string())
-    }
-}
-
-#[derive(Serialize, Deserialize, Debug)]
-pub struct SerializedAgentThreadPane {
-    pub expanded: bool,
-    pub width: Option<Pixels>,
-    pub thread_id: Option<SerializedHistoryEntryId>,
-}
-
-pub enum AgentsUtilityPaneEvent {
-    StateChanged,
-}
-
-impl EventEmitter<AgentsUtilityPaneEvent> for AgentThreadPane {}
-impl EventEmitter<MinimizePane> for AgentThreadPane {}
-impl EventEmitter<ClosePane> for AgentThreadPane {}
-
-struct ActiveThreadView {
-    view: Entity<AcpServerView>,
-    thread_id: acp::SessionId,
-    _notify: Subscription,
-}
-
-pub struct AgentThreadPane {
-    focus_handle: gpui::FocusHandle,
-    expanded: bool,
-    width: Option<Pixels>,
-    thread_view: Option<ActiveThreadView>,
-    workspace: WeakEntity<Workspace>,
-    history: Entity<AcpThreadHistory>,
-}
-
-impl AgentThreadPane {
-    pub fn new(
-        workspace: WeakEntity<Workspace>,
-        history: Entity<AcpThreadHistory>,
-        cx: &mut ui::Context<Self>,
-    ) -> Self {
-        let focus_handle = cx.focus_handle();
-        Self {
-            focus_handle,
-            expanded: false,
-            width: None,
-            thread_view: None,
-            workspace,
-            history,
-        }
-    }
-
-    pub fn thread_id(&self) -> Option<acp::SessionId> {
-        self.thread_view.as_ref().map(|tv| tv.thread_id.clone())
-    }
-
-    pub fn serialize(&self) -> SerializedAgentThreadPane {
-        SerializedAgentThreadPane {
-            expanded: self.expanded,
-            width: self.width,
-            thread_id: self.thread_id().map(SerializedHistoryEntryId::from),
-        }
-    }
-
-    pub fn open_thread(
-        &mut self,
-        entry: AgentSessionInfo,
-        fs: Arc<dyn Fs>,
-        workspace: WeakEntity<Workspace>,
-        project: Entity<Project>,
-        thread_store: Entity<ThreadStore>,
-        prompt_store: Option<Entity<PromptStore>>,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        let thread_id = entry.session_id.clone();
-        let resume_thread = Some(entry);
-
-        let agent: Rc<dyn AgentServer> = Rc::new(NativeAgentServer::new(fs, thread_store.clone()));
-
-        let history = self.history.clone();
-        let thread_view = cx.new(|cx| {
-            AcpServerView::new(
-                agent,
-                resume_thread,
-                None,
-                workspace,
-                project,
-                Some(thread_store),
-                prompt_store,
-                history,
-                window,
-                cx,
-            )
-        });
-
-        let notify = cx.observe(&thread_view, |_, _, cx| {
-            cx.notify();
-        });
-
-        self.thread_view = Some(ActiveThreadView {
-            view: thread_view,
-            thread_id,
-            _notify: notify,
-        });
-
-        cx.notify();
-    }
-
-    fn title(&self, cx: &App) -> SharedString {
-        if let Some(active_thread_view) = &self.thread_view {
-            let thread_view = active_thread_view.view.read(cx);
-            if let Some(ready) = thread_view.active_thread() {
-                let title = ready.read(cx).thread.read(cx).title();
-                if !title.is_empty() {
-                    return title;
-                }
-            }
-            thread_view.title(cx)
-        } else {
-            "Thread".into()
-        }
-    }
-
-    fn render_header(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let position = self.position(window, cx);
-        let slot = match position {
-            UtilityPanePosition::Left => UtilityPaneSlot::Left,
-            UtilityPanePosition::Right => UtilityPaneSlot::Right,
-        };
-
-        let workspace = self.workspace.clone();
-        let toggle_icon = self.toggle_icon(cx);
-        let title = self.title(cx);
-
-        let pane_toggle_button = |workspace: WeakEntity<Workspace>| {
-            IconButton::new("toggle_utility_pane", toggle_icon)
-                .icon_size(IconSize::Small)
-                .tooltip(Tooltip::text("Toggle Agent Pane"))
-                .on_click(move |_, window, cx| {
-                    workspace
-                        .update(cx, |workspace, cx| {
-                            workspace.toggle_utility_pane(slot, window, cx)
-                        })
-                        .ok();
-                })
-        };
-
-        h_flex()
-            .id("utility-pane-header")
-            .w_full()
-            .h(Tab::container_height(cx))
-            .px_1p5()
-            .gap(DynamicSpacing::Base06.rems(cx))
-            .when(slot == UtilityPaneSlot::Right, |this| {
-                this.flex_row_reverse()
-            })
-            .flex_none()
-            .border_b_1()
-            .border_color(cx.theme().colors().border)
-            .child(pane_toggle_button(workspace))
-            .child(
-                h_flex()
-                    .size_full()
-                    .min_w_0()
-                    .gap_1()
-                    .map(|this| {
-                        if slot == UtilityPaneSlot::Right {
-                            this.flex_row_reverse().justify_start()
-                        } else {
-                            this.justify_between()
-                        }
-                    })
-                    .child(Label::new(title).truncate())
-                    .child(
-                        IconButton::new("close_btn", IconName::Close)
-                            .icon_size(IconSize::Small)
-                            .tooltip(Tooltip::text("Close Agent Pane"))
-                            .on_click(cx.listener(|this, _: &gpui::ClickEvent, _window, cx| {
-                                cx.emit(ClosePane);
-                                this.thread_view = None;
-                                cx.notify()
-                            })),
-                    ),
-            )
-    }
-}
-
-impl Focusable for AgentThreadPane {
-    fn focus_handle(&self, cx: &ui::App) -> gpui::FocusHandle {
-        if let Some(thread_view) = &self.thread_view {
-            thread_view.view.focus_handle(cx)
-        } else {
-            self.focus_handle.clone()
-        }
-    }
-}
-
-impl UtilityPane for AgentThreadPane {
-    fn position(&self, _window: &Window, cx: &App) -> UtilityPanePosition {
-        match AgentSettings::get_global(cx).agents_panel_dock {
-            DockSide::Left => UtilityPanePosition::Left,
-            DockSide::Right => UtilityPanePosition::Right,
-        }
-    }
-
-    fn toggle_icon(&self, _cx: &App) -> IconName {
-        IconName::Thread
-    }
-
-    fn expanded(&self, _cx: &App) -> bool {
-        self.expanded
-    }
-
-    fn set_expanded(&mut self, expanded: bool, cx: &mut Context<Self>) {
-        self.expanded = expanded;
-        cx.emit(AgentsUtilityPaneEvent::StateChanged);
-        cx.notify();
-    }
-
-    fn width(&self, _cx: &App) -> Pixels {
-        self.width.unwrap_or(DEFAULT_UTILITY_PANE_WIDTH)
-    }
-
-    fn set_width(&mut self, width: Option<Pixels>, cx: &mut Context<Self>) {
-        self.width = width;
-        cx.emit(AgentsUtilityPaneEvent::StateChanged);
-        cx.notify();
-    }
-}
-
-impl Render for AgentThreadPane {
-    fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let content = if let Some(thread_view) = &self.thread_view {
-            div().size_full().child(thread_view.view.clone())
-        } else {
-            div()
-                .size_full()
-                .flex()
-                .items_center()
-                .justify_center()
-                .child(Label::new("Select a thread to view details").size(LabelSize::Default))
-        };
-
-        div()
-            .size_full()
-            .flex()
-            .flex_col()
-            .child(self.render_header(window, cx))
-            .child(content)
-    }
-}

crates/agent_ui_v2/src/agents_panel.rs 🔗

@@ -1,481 +0,0 @@
-use acp_thread::AgentSessionInfo;
-use agent::{NativeAgentServer, ThreadStore};
-use agent_client_protocol as acp;
-use agent_servers::{AgentServer, AgentServerDelegate};
-use agent_settings::AgentSettings;
-use anyhow::Result;
-use db::kvp::KEY_VALUE_STORE;
-use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt};
-use fs::Fs;
-use gpui::{
-    Action, AsyncWindowContext, Entity, EventEmitter, Focusable, Pixels, Subscription, Task,
-    WeakEntity, actions, prelude::*,
-};
-use project::Project;
-use prompt_store::PromptStore;
-use serde::{Deserialize, Serialize};
-use settings::{Settings as _, update_settings_file};
-use std::sync::Arc;
-use ui::{App, Context, IconName, IntoElement, ParentElement, Render, Styled, Window};
-use util::ResultExt;
-use workspace::{
-    Panel, Workspace,
-    dock::{ClosePane, DockPosition, PanelEvent, UtilityPane},
-    utility_pane::{UtilityPaneSlot, utility_slot_for_dock_position},
-};
-
-use crate::agent_thread_pane::{
-    AgentThreadPane, AgentsUtilityPaneEvent, SerializedAgentThreadPane, SerializedHistoryEntryId,
-};
-use agent_ui::acp::{AcpThreadHistory, ThreadHistoryEvent};
-
-const AGENTS_PANEL_KEY: &str = "agents_panel";
-
-#[derive(Serialize, Deserialize, Debug)]
-struct SerializedAgentsPanel {
-    width: Option<Pixels>,
-    pane: Option<SerializedAgentThreadPane>,
-}
-
-actions!(
-    agents,
-    [
-        /// Toggle the visibility of the agents panel.
-        ToggleAgentsPanel
-    ]
-);
-
-pub fn init(cx: &mut App) {
-    cx.observe_new(|workspace: &mut Workspace, _, _| {
-        workspace.register_action(|workspace, _: &ToggleAgentsPanel, window, cx| {
-            workspace.toggle_panel_focus::<AgentsPanel>(window, cx);
-        });
-    })
-    .detach();
-}
-
-pub struct AgentsPanel {
-    focus_handle: gpui::FocusHandle,
-    workspace: WeakEntity<Workspace>,
-    project: Entity<Project>,
-    agent_thread_pane: Option<Entity<AgentThreadPane>>,
-    history: Entity<AcpThreadHistory>,
-    thread_store: Entity<ThreadStore>,
-    prompt_store: Option<Entity<PromptStore>>,
-    fs: Arc<dyn Fs>,
-    width: Option<Pixels>,
-    pending_restore: Option<SerializedAgentThreadPane>,
-    pending_serialization: Task<Option<()>>,
-    _subscriptions: Vec<Subscription>,
-}
-
-impl AgentsPanel {
-    pub fn load(
-        workspace: WeakEntity<Workspace>,
-        cx: AsyncWindowContext,
-    ) -> Task<Result<Entity<Self>, anyhow::Error>> {
-        cx.spawn(async move |cx| {
-            let serialized_panel = cx
-                .background_spawn(async move {
-                    KEY_VALUE_STORE
-                        .read_kvp(AGENTS_PANEL_KEY)
-                        .ok()
-                        .flatten()
-                        .and_then(|panel| {
-                            serde_json::from_str::<SerializedAgentsPanel>(&panel).ok()
-                        })
-                })
-                .await;
-
-            let (fs, project) = workspace.update(cx, |workspace, _| {
-                let fs = workspace.app_state().fs.clone();
-                let project = workspace.project().clone();
-                (fs, project)
-            })?;
-
-            let prompt_store = workspace
-                .update(cx, |_, cx| PromptStore::global(cx))?
-                .await
-                .log_err();
-
-            workspace.update_in(cx, |_, window, cx| {
-                cx.new(|cx| {
-                    let mut panel =
-                        Self::new(workspace.clone(), fs, project, prompt_store, window, cx);
-                    if let Some(serialized_panel) = serialized_panel {
-                        panel.width = serialized_panel.width;
-                        if let Some(serialized_pane) = serialized_panel.pane {
-                            panel.restore_utility_pane(serialized_pane, window, cx);
-                        }
-                    }
-                    panel
-                })
-            })
-        })
-    }
-
-    fn new(
-        workspace: WeakEntity<Workspace>,
-        fs: Arc<dyn Fs>,
-        project: Entity<Project>,
-        prompt_store: Option<Entity<PromptStore>>,
-        window: &mut Window,
-        cx: &mut ui::Context<Self>,
-    ) -> Self {
-        let focus_handle = cx.focus_handle();
-
-        let thread_store = ThreadStore::global(cx);
-        let history = cx.new(|cx| AcpThreadHistory::new(None, window, cx));
-
-        let history_handle = history.clone();
-        let connect_project = project.clone();
-        let connect_thread_store = thread_store.clone();
-        let connect_fs = fs.clone();
-        cx.spawn(async move |_, cx| {
-            let connect_task = cx.update(|cx| {
-                let delegate = AgentServerDelegate::new(
-                    connect_project.read(cx).agent_server_store().clone(),
-                    connect_project.clone(),
-                    None,
-                    None,
-                );
-                let server = NativeAgentServer::new(connect_fs, connect_thread_store);
-                server.connect(None, delegate, cx)
-            });
-            let connection = match connect_task.await {
-                Ok((connection, _)) => connection,
-                Err(error) => {
-                    log::error!("Failed to connect native agent for history: {error:#}");
-                    return;
-                }
-            };
-
-            cx.update(|cx| {
-                if connection.supports_session_history(cx)
-                    && let Some(session_list) = connection.session_list(cx)
-                {
-                    history_handle.update(cx, |history, cx| {
-                        history.set_session_list(Some(session_list), cx);
-                    });
-                }
-            });
-        })
-        .detach();
-
-        let this = cx.weak_entity();
-        let subscriptions = vec![
-            cx.subscribe_in(&history, window, Self::handle_history_event),
-            cx.observe_in(&history, window, Self::handle_history_updated),
-            cx.on_flags_ready(move |_, cx| {
-                this.update(cx, |_, cx| {
-                    cx.notify();
-                })
-                .ok();
-            }),
-        ];
-
-        Self {
-            focus_handle,
-            workspace,
-            project,
-            agent_thread_pane: None,
-            history,
-            thread_store,
-            prompt_store,
-            fs,
-            width: None,
-            pending_restore: None,
-            pending_serialization: Task::ready(None),
-            _subscriptions: subscriptions,
-        }
-    }
-
-    fn restore_utility_pane(
-        &mut self,
-        serialized_pane: SerializedAgentThreadPane,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        let Some(thread_id) = &serialized_pane.thread_id else {
-            return;
-        };
-
-        let SerializedHistoryEntryId::AcpThread(id) = thread_id;
-        let session_id = acp::SessionId::new(id.clone());
-        if let Some(entry) = self.history.read(cx).session_for_id(&session_id) {
-            self.open_thread(
-                entry,
-                serialized_pane.expanded,
-                serialized_pane.width,
-                window,
-                cx,
-            );
-        } else {
-            self.pending_restore = Some(serialized_pane);
-        }
-    }
-
-    fn handle_utility_pane_event(
-        &mut self,
-        _utility_pane: Entity<AgentThreadPane>,
-        event: &AgentsUtilityPaneEvent,
-        cx: &mut Context<Self>,
-    ) {
-        match event {
-            AgentsUtilityPaneEvent::StateChanged => {
-                self.serialize(cx);
-                cx.notify();
-            }
-        }
-    }
-
-    fn handle_close_pane_event(
-        &mut self,
-        _utility_pane: Entity<AgentThreadPane>,
-        _event: &ClosePane,
-        cx: &mut Context<Self>,
-    ) {
-        self.agent_thread_pane = None;
-        self.serialize(cx);
-        cx.notify();
-    }
-
-    fn handle_history_updated(
-        &mut self,
-        _history: Entity<AcpThreadHistory>,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        self.maybe_restore_pending(window, cx);
-    }
-
-    fn handle_history_event(
-        &mut self,
-        _history: &Entity<AcpThreadHistory>,
-        event: &ThreadHistoryEvent,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        match event {
-            ThreadHistoryEvent::Open(entry) => {
-                self.open_thread(entry.clone(), true, None, window, cx);
-            }
-        }
-    }
-
-    fn maybe_restore_pending(&mut self, window: &mut Window, cx: &mut Context<Self>) {
-        if self.agent_thread_pane.is_some() {
-            self.pending_restore = None;
-            return;
-        }
-
-        let Some(pending) = self.pending_restore.as_ref() else {
-            return;
-        };
-        let Some(thread_id) = &pending.thread_id else {
-            self.pending_restore = None;
-            return;
-        };
-
-        let SerializedHistoryEntryId::AcpThread(id) = thread_id;
-        let session_id = acp::SessionId::new(id.clone());
-        let Some(entry) = self.history.read(cx).session_for_id(&session_id) else {
-            return;
-        };
-
-        let pending = self.pending_restore.take().expect("pending restore");
-        self.open_thread(entry, pending.expanded, pending.width, window, cx);
-    }
-
-    fn open_thread(
-        &mut self,
-        entry: AgentSessionInfo,
-        expanded: bool,
-        width: Option<Pixels>,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        let entry_id = entry.session_id.clone();
-        self.pending_restore = None;
-
-        if let Some(existing_pane) = &self.agent_thread_pane {
-            if existing_pane.read(cx).thread_id() == Some(entry_id) {
-                existing_pane.update(cx, |pane, cx| {
-                    pane.set_expanded(true, cx);
-                });
-                return;
-            }
-        }
-
-        let fs = self.fs.clone();
-        let workspace = self.workspace.clone();
-        let project = self.project.clone();
-        let thread_store = self.thread_store.clone();
-        let prompt_store = self.prompt_store.clone();
-        let history = self.history.clone();
-
-        let agent_thread_pane = cx.new(|cx| {
-            let mut pane = AgentThreadPane::new(workspace.clone(), history, cx);
-            pane.open_thread(
-                entry,
-                fs,
-                workspace.clone(),
-                project,
-                thread_store,
-                prompt_store,
-                window,
-                cx,
-            );
-            if let Some(width) = width {
-                pane.set_width(Some(width), cx);
-            }
-            pane.set_expanded(expanded, cx);
-            pane
-        });
-
-        let state_subscription = cx.subscribe(&agent_thread_pane, Self::handle_utility_pane_event);
-        let close_subscription = cx.subscribe(&agent_thread_pane, Self::handle_close_pane_event);
-
-        self._subscriptions.push(state_subscription);
-        self._subscriptions.push(close_subscription);
-
-        let slot = self.utility_slot(window, cx);
-        let panel_id = cx.entity_id();
-
-        if let Some(workspace) = self.workspace.upgrade() {
-            workspace.update(cx, |workspace, cx| {
-                workspace.register_utility_pane(slot, panel_id, agent_thread_pane.clone(), cx);
-            });
-        }
-
-        self.agent_thread_pane = Some(agent_thread_pane);
-        self.serialize(cx);
-        cx.notify();
-    }
-
-    fn utility_slot(&self, window: &Window, cx: &App) -> UtilityPaneSlot {
-        let position = self.position(window, cx);
-        utility_slot_for_dock_position(position)
-    }
-
-    fn re_register_utility_pane(&mut self, window: &mut Window, cx: &mut Context<Self>) {
-        if let Some(pane) = &self.agent_thread_pane {
-            let slot = self.utility_slot(window, cx);
-            let panel_id = cx.entity_id();
-            let pane = pane.clone();
-
-            if let Some(workspace) = self.workspace.upgrade() {
-                workspace.update(cx, |workspace, cx| {
-                    workspace.register_utility_pane(slot, panel_id, pane, cx);
-                });
-            }
-        }
-    }
-
-    fn serialize(&mut self, cx: &mut Context<Self>) {
-        let width = self.width;
-        let pane = self
-            .agent_thread_pane
-            .as_ref()
-            .map(|pane| pane.read(cx).serialize());
-
-        self.pending_serialization = cx.background_spawn(async move {
-            KEY_VALUE_STORE
-                .write_kvp(
-                    AGENTS_PANEL_KEY.into(),
-                    serde_json::to_string(&SerializedAgentsPanel { width, pane }).unwrap(),
-                )
-                .await
-                .log_err()
-        });
-    }
-}
-
-impl EventEmitter<PanelEvent> for AgentsPanel {}
-
-impl Focusable for AgentsPanel {
-    fn focus_handle(&self, _cx: &ui::App) -> gpui::FocusHandle {
-        self.focus_handle.clone()
-    }
-}
-
-impl Panel for AgentsPanel {
-    fn persistent_name() -> &'static str {
-        "AgentsPanel"
-    }
-
-    fn panel_key() -> &'static str {
-        AGENTS_PANEL_KEY
-    }
-
-    fn position(&self, _window: &Window, cx: &App) -> DockPosition {
-        match AgentSettings::get_global(cx).agents_panel_dock {
-            settings::DockSide::Left => DockPosition::Left,
-            settings::DockSide::Right => DockPosition::Right,
-        }
-    }
-
-    fn position_is_valid(&self, position: DockPosition) -> bool {
-        position != DockPosition::Bottom
-    }
-
-    fn set_position(
-        &mut self,
-        position: DockPosition,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        update_settings_file(self.fs.clone(), cx, move |settings, _| {
-            settings.agent.get_or_insert_default().agents_panel_dock = Some(match position {
-                DockPosition::Left => settings::DockSide::Left,
-                DockPosition::Right | DockPosition::Bottom => settings::DockSide::Right,
-            });
-        });
-        self.re_register_utility_pane(window, cx);
-    }
-
-    fn size(&self, window: &Window, cx: &App) -> Pixels {
-        let settings = AgentSettings::get_global(cx);
-        match self.position(window, cx) {
-            DockPosition::Left | DockPosition::Right => {
-                self.width.unwrap_or(settings.default_width)
-            }
-            DockPosition::Bottom => self.width.unwrap_or(settings.default_height),
-        }
-    }
-
-    fn set_size(&mut self, size: Option<Pixels>, window: &mut Window, cx: &mut Context<Self>) {
-        match self.position(window, cx) {
-            DockPosition::Left | DockPosition::Right => self.width = size,
-            DockPosition::Bottom => {}
-        }
-        self.serialize(cx);
-        cx.notify();
-    }
-
-    fn icon(&self, _window: &Window, cx: &App) -> Option<IconName> {
-        (self.enabled(cx) && AgentSettings::get_global(cx).button).then_some(IconName::ZedAgentTwo)
-    }
-
-    fn icon_tooltip(&self, _window: &Window, _cx: &App) -> Option<&'static str> {
-        Some("Agents Panel")
-    }
-
-    fn toggle_action(&self) -> Box<dyn Action> {
-        Box::new(ToggleAgentsPanel)
-    }
-
-    fn activation_priority(&self) -> u32 {
-        4
-    }
-
-    fn enabled(&self, cx: &App) -> bool {
-        AgentSettings::get_global(cx).enabled(cx) && cx.has_flag::<AgentV2FeatureFlag>()
-    }
-}
-
-impl Render for AgentsPanel {
-    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
-        gpui::div().size_full().child(self.history.clone())
-    }
-}

crates/settings_content/src/agent.rs 🔗

@@ -7,7 +7,7 @@ use std::{borrow::Cow, path::PathBuf};
 
 use crate::ExtendingVec;
 
-use crate::{DockPosition, DockSide};
+use crate::DockPosition;
 
 #[with_fallible_options]
 #[derive(Clone, PartialEq, Serialize, Deserialize, JsonSchema, MergeFrom, Debug, Default)]
@@ -24,10 +24,6 @@ pub struct AgentSettingsContent {
     ///
     /// Default: right
     pub dock: Option<DockPosition>,
-    /// Where to dock the utility pane (the thread view pane).
-    ///
-    /// Default: left
-    pub agents_panel_dock: Option<DockSide>,
     /// Default width in pixels when the agent panel is docked to the left or right.
     ///
     /// Default: 640

crates/ui/src/components/tab_bar.rs 🔗

@@ -10,7 +10,6 @@ pub struct TabBar {
     start_children: SmallVec<[AnyElement; 2]>,
     children: SmallVec<[AnyElement; 2]>,
     end_children: SmallVec<[AnyElement; 2]>,
-    pre_end_children: SmallVec<[AnyElement; 2]>,
     scroll_handle: Option<ScrollHandle>,
 }
 
@@ -21,7 +20,6 @@ impl TabBar {
             start_children: SmallVec::new(),
             children: SmallVec::new(),
             end_children: SmallVec::new(),
-            pre_end_children: SmallVec::new(),
             scroll_handle: None,
         }
     }
@@ -72,15 +70,6 @@ impl TabBar {
         self
     }
 
-    pub fn pre_end_child(mut self, end_child: impl IntoElement) -> Self
-    where
-        Self: Sized,
-    {
-        self.pre_end_children
-            .push(end_child.into_element().into_any());
-        self
-    }
-
     pub fn end_children(mut self, end_children: impl IntoIterator<Item = impl IntoElement>) -> Self
     where
         Self: Sized,
@@ -148,32 +137,17 @@ impl RenderOnce for TabBar {
                             .children(self.children),
                     ),
             )
-            .when(
-                !self.end_children.is_empty() || !self.pre_end_children.is_empty(),
-                |this| {
-                    this.child(
-                        h_flex()
-                            .flex_none()
-                            .gap(DynamicSpacing::Base04.rems(cx))
-                            .px(DynamicSpacing::Base06.rems(cx))
-                            .children(self.pre_end_children)
-                            .border_color(cx.theme().colors().border)
-                            .border_b_1()
-                            .when(!self.end_children.is_empty(), |div| {
-                                div.child(
-                                    h_flex()
-                                        .h_full()
-                                        .flex_none()
-                                        .pl(DynamicSpacing::Base04.rems(cx))
-                                        .gap(DynamicSpacing::Base04.rems(cx))
-                                        .border_l_1()
-                                        .border_color(cx.theme().colors().border)
-                                        .children(self.end_children),
-                                )
-                            }),
-                    )
-                },
-            )
+            .when(!self.end_children.is_empty(), |this| {
+                this.child(
+                    h_flex()
+                        .flex_none()
+                        .gap(DynamicSpacing::Base04.rems(cx))
+                        .px(DynamicSpacing::Base06.rems(cx))
+                        .border_color(cx.theme().colors().border)
+                        .border_b_1()
+                        .children(self.end_children),
+                )
+            })
     }
 }
 

crates/workspace/src/dock.rs 🔗

@@ -27,72 +27,6 @@ pub enum PanelEvent {
 
 pub use proto::PanelId;
 
-pub struct MinimizePane;
-pub struct ClosePane;
-
-pub trait UtilityPane: EventEmitter<MinimizePane> + EventEmitter<ClosePane> + Render {
-    fn position(&self, window: &Window, cx: &App) -> UtilityPanePosition;
-    /// The icon to render in the adjacent pane's tab bar for toggling this utility pane
-    fn toggle_icon(&self, cx: &App) -> IconName;
-    fn expanded(&self, cx: &App) -> bool;
-    fn set_expanded(&mut self, expanded: bool, cx: &mut Context<Self>);
-    fn width(&self, cx: &App) -> Pixels;
-    fn set_width(&mut self, width: Option<Pixels>, cx: &mut Context<Self>);
-}
-
-pub trait UtilityPaneHandle: 'static + Send + Sync {
-    fn position(&self, window: &Window, cx: &App) -> UtilityPanePosition;
-    fn toggle_icon(&self, cx: &App) -> IconName;
-    fn expanded(&self, cx: &App) -> bool;
-    fn set_expanded(&self, expanded: bool, cx: &mut App);
-    fn width(&self, cx: &App) -> Pixels;
-    fn set_width(&self, width: Option<Pixels>, cx: &mut App);
-    fn to_any(&self) -> AnyView;
-    fn box_clone(&self) -> Box<dyn UtilityPaneHandle>;
-}
-
-impl<T> UtilityPaneHandle for Entity<T>
-where
-    T: UtilityPane,
-{
-    fn position(&self, window: &Window, cx: &App) -> UtilityPanePosition {
-        self.read(cx).position(window, cx)
-    }
-
-    fn toggle_icon(&self, cx: &App) -> IconName {
-        self.read(cx).toggle_icon(cx)
-    }
-
-    fn expanded(&self, cx: &App) -> bool {
-        self.read(cx).expanded(cx)
-    }
-
-    fn set_expanded(&self, expanded: bool, cx: &mut App) {
-        self.update(cx, |this, cx| this.set_expanded(expanded, cx))
-    }
-
-    fn width(&self, cx: &App) -> Pixels {
-        self.read(cx).width(cx)
-    }
-
-    fn set_width(&self, width: Option<Pixels>, cx: &mut App) {
-        self.update(cx, |this, cx| this.set_width(width, cx))
-    }
-
-    fn to_any(&self) -> AnyView {
-        self.clone().into()
-    }
-
-    fn box_clone(&self) -> Box<dyn UtilityPaneHandle> {
-        Box::new(self.clone())
-    }
-}
-
-pub enum UtilityPanePosition {
-    Left,
-    Right,
-}
-
 pub trait Panel: Focusable + EventEmitter<PanelEvent> + Render + Sized {
     fn persistent_name() -> &'static str;
     fn panel_key() -> &'static str;

crates/workspace/src/pane.rs 🔗

@@ -11,12 +11,10 @@ use crate::{
     move_item,
     notifications::NotifyResultExt,
     toolbar::Toolbar,
-    utility_pane::UtilityPaneSlot,
     workspace_settings::{AutosaveSetting, TabBarSettings, WorkspaceSettings},
 };
 use anyhow::Result;
 use collections::{BTreeSet, HashMap, HashSet, VecDeque};
-use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt};
 use futures::{StreamExt, stream::FuturesUnordered};
 use gpui::{
     Action, AnyElement, App, AsyncWindowContext, ClickEvent, ClipboardItem, Context, Corner, Div,
@@ -425,8 +423,6 @@ pub struct Pane {
     welcome_page: Option<Entity<crate::welcome::WelcomePage>>,
 
     pub in_center_group: bool,
-    pub is_upper_left: bool,
-    pub is_upper_right: bool,
 }
 
 pub struct ActivationHistoryEntry {
@@ -595,8 +591,6 @@ impl Pane {
             project_item_restoration_data: HashMap::default(),
             welcome_page: None,
             in_center_group: false,
-            is_upper_left: false,
-            is_upper_right: false,
         }
     }
 
@@ -3280,12 +3274,11 @@ impl Pane {
     }
 
     fn render_tab_bar(&mut self, window: &mut Window, cx: &mut Context<Pane>) -> AnyElement {
-        let Some(workspace) = self.workspace.upgrade() else {
+        if self.workspace.upgrade().is_none() {
             return gpui::Empty.into_any();
-        };
+        }
 
         let focus_handle = self.focus_handle.clone();
-        let is_pane_focused = self.has_focus(window, cx);
 
         let navigate_backward = IconButton::new("navigate_backward", IconName::ArrowLeft)
             .icon_size(IconSize::Small)
@@ -3310,70 +3303,6 @@ impl Pane {
                 }
             });
 
-        let open_aside_left = {
-            let workspace = workspace.read(cx);
-            workspace.utility_pane(UtilityPaneSlot::Left).map(|pane| {
-                let toggle_icon = pane.toggle_icon(cx);
-                let workspace_handle = self.workspace.clone();
-
-                h_flex()
-                    .h_full()
-                    .pr_1p5()
-                    .border_r_1()
-                    .border_color(cx.theme().colors().border)
-                    .child(
-                        IconButton::new("open_aside_left", toggle_icon)
-                            .icon_size(IconSize::Small)
-                            .tooltip(Tooltip::text("Toggle Agent Pane")) // TODO: Probably want to make this generic
-                            .on_click(move |_, window, cx| {
-                                workspace_handle
-                                    .update(cx, |workspace, cx| {
-                                        workspace.toggle_utility_pane(
-                                            UtilityPaneSlot::Left,
-                                            window,
-                                            cx,
-                                        )
-                                    })
-                                    .ok();
-                            }),
-                    )
-                    .into_any_element()
-            })
-        };
-
-        let open_aside_right = {
-            let workspace = workspace.read(cx);
-            workspace.utility_pane(UtilityPaneSlot::Right).map(|pane| {
-                let toggle_icon = pane.toggle_icon(cx);
-                let workspace_handle = self.workspace.clone();
-
-                h_flex()
-                    .h_full()
-                    .when(is_pane_focused, |this| {
-                        this.pl(DynamicSpacing::Base04.rems(cx))
-                            .border_l_1()
-                            .border_color(cx.theme().colors().border)
-                    })
-                    .child(
-                        IconButton::new("open_aside_right", toggle_icon)
-                            .icon_size(IconSize::Small)
-                            .tooltip(Tooltip::text("Toggle Agent Pane")) // TODO: Probably want to make this generic
-                            .on_click(move |_, window, cx| {
-                                workspace_handle
-                                    .update(cx, |workspace, cx| {
-                                        workspace.toggle_utility_pane(
-                                            UtilityPaneSlot::Right,
-                                            window,
-                                            cx,
-                                        )
-                                    })
-                                    .ok();
-                            }),
-                    )
-                    .into_any_element()
-            })
-        };
-
         let navigate_forward = IconButton::new("navigate_forward", IconName::ArrowRight)
             .icon_size(IconSize::Small)
             .on_click({
@@ -3421,34 +3350,6 @@ impl Pane {
         let unpinned_tabs = tab_items.split_off(self.pinned_tab_count);
         let pinned_tabs = tab_items;
 
-        let render_aside_toggle_left = cx.has_flag::<AgentV2FeatureFlag>()
-            && self
-                .is_upper_left
-                .then(|| {
-                    self.workspace.upgrade().and_then(|entity| {
-                        let workspace = entity.read(cx);
-                        workspace
-                            .utility_pane(UtilityPaneSlot::Left)
-                            .map(|pane| !pane.expanded(cx))
-                    })
-                })
-                .flatten()
-                .unwrap_or(false);
-
-        let render_aside_toggle_right = cx.has_flag::<AgentV2FeatureFlag>()
-            && self
-                .is_upper_right
-                .then(|| {
-                    self.workspace.upgrade().and_then(|entity| {
-                        let workspace = entity.read(cx);
-                        workspace
-                            .utility_pane(UtilityPaneSlot::Right)
-                            .map(|pane| !pane.expanded(cx))
-                    })
-                })
-                .flatten()
-                .unwrap_or(false);
-
         let tab_bar_settings = TabBarSettings::get_global(cx);
         let use_separate_rows = tab_bar_settings.show_pinned_tabs_in_separate_row;
 
@@ -3459,10 +3360,6 @@ impl Pane {
                 tab_count,
                 navigate_backward,
                 navigate_forward,
-                open_aside_left,
-                open_aside_right,
-                render_aside_toggle_left,
-                render_aside_toggle_right,
                 window,
                 cx,
             )
@@ -3473,10 +3370,6 @@ impl Pane {
                 tab_count,
                 navigate_backward,
                 navigate_forward,
-                open_aside_left,
-                open_aside_right,
-                render_aside_toggle_left,
-                render_aside_toggle_right,
                 window,
                 cx,
             )
@@ -3488,21 +3381,10 @@ impl Pane {
         tab_bar: TabBar,
         navigate_backward: IconButton,
         navigate_forward: IconButton,
-        open_aside_left: Option<AnyElement>,
-        render_aside_toggle_left: bool,
         window: &mut Window,
         cx: &mut Context<Pane>,
     ) -> TabBar {
         tab_bar
-            .map(|tab_bar| {
-                if let Some(open_aside_left) = open_aside_left
-                    && render_aside_toggle_left
-                {
-                    tab_bar.start_child(open_aside_left)
-                } else {
-                    tab_bar
-                }
-            })
             .when(
                 self.display_nav_history_buttons.unwrap_or_default(),
                 |tab_bar| {
@@ -3524,22 +3406,6 @@ impl Pane {
             })
     }
 
-    fn configure_tab_bar_end(
-        tab_bar: TabBar,
-        open_aside_right: Option<AnyElement>,
-        render_aside_toggle_right: bool,
-    ) -> TabBar {
-        tab_bar.map(|tab_bar| {
-            if let Some(open_aside_right) = open_aside_right
-                && render_aside_toggle_right
-            {
-                tab_bar.end_child(open_aside_right)
-            } else {
-                tab_bar
-            }
-        })
-    }
-
     fn render_single_row_tab_bar(
         &mut self,
         pinned_tabs: Vec<AnyElement>,
@@ -3547,10 +3413,6 @@ impl Pane {
         tab_count: usize,
         navigate_backward: IconButton,
         navigate_forward: IconButton,
-        open_aside_left: Option<AnyElement>,
-        open_aside_right: Option<AnyElement>,
-        render_aside_toggle_left: bool,
-        render_aside_toggle_right: bool,
         window: &mut Window,
         cx: &mut Context<Pane>,
     ) -> AnyElement {
@@ -3559,8 +3421,6 @@ impl Pane {
                 TabBar::new("tab_bar"),
                 navigate_backward,
                 navigate_forward,
-                open_aside_left,
-                render_aside_toggle_left,
                 window,
                 cx,
             )
@@ -3581,8 +3441,7 @@ impl Pane {
                     })
             }))
             .child(self.render_unpinned_tabs_container(unpinned_tabs, tab_count, cx));
-        Self::configure_tab_bar_end(tab_bar, open_aside_right, render_aside_toggle_right)
-            .into_any_element()
+        tab_bar.into_any_element()
     }
 
     fn render_two_row_tab_bar(
@@ -3592,10 +3451,6 @@ impl Pane {
         tab_count: usize,
         navigate_backward: IconButton,
         navigate_forward: IconButton,
-        open_aside_left: Option<AnyElement>,
-        open_aside_right: Option<AnyElement>,
-        render_aside_toggle_left: bool,
-        render_aside_toggle_right: bool,
         window: &mut Window,
         cx: &mut Context<Pane>,
     ) -> AnyElement {
@@ -3604,8 +3459,6 @@ impl Pane {
                 TabBar::new("pinned_tab_bar"),
                 navigate_backward,
                 navigate_forward,
-                open_aside_left,
-                render_aside_toggle_left,
                 window,
                 cx,
             )
@@ -3617,12 +3470,6 @@ impl Pane {
                     .w_full()
                     .children(pinned_tabs),
             );
-        let pinned_tab_bar = Self::configure_tab_bar_end(
-            pinned_tab_bar,
-            open_aside_right,
-            render_aside_toggle_right,
-        );
-
         v_flex()
             .w_full()
             .flex_none()
@@ -7561,8 +7408,8 @@ mod tests {
         let scroll_bounds = tab_bar_scroll_handle.bounds();
         let scroll_offset = tab_bar_scroll_handle.offset();
         assert!(tab_bounds.right() <= scroll_bounds.right());
-        // -43.0 is the magic number for this setup
-        assert_eq!(scroll_offset.x, px(-43.0));
+        // -38.5 is the magic number for this setup
+        assert_eq!(scroll_offset.x, px(-38.5));
         assert!(
             !tab_bounds.intersects(&new_tab_button_bounds),
             "Tab should not overlap with the new tab button, if this is failing check if there's been a redesign!"

crates/workspace/src/pane_group.rs 🔗

@@ -206,7 +206,7 @@ impl PaneGroup {
     }
 
     pub fn mark_positions(&mut self, cx: &mut App) {
-        self.root.mark_positions(self.is_center, true, true, cx);
+        self.root.mark_positions(self.is_center, cx);
     }
 
     pub fn render(
@@ -278,37 +278,15 @@ pub enum Member {
 }
 
 impl Member {
-    pub fn mark_positions(
-        &mut self,
-        in_center_group: bool,
-        is_upper_left: bool,
-        is_upper_right: bool,
-        cx: &mut App,
-    ) {
+    pub fn mark_positions(&mut self, in_center_group: bool, cx: &mut App) {
         match self {
             Member::Axis(pane_axis) => {
-                let len = pane_axis.members.len();
-                for (idx, member) in pane_axis.members.iter_mut().enumerate() {
-                    let member_upper_left = match pane_axis.axis {
-                        Axis::Vertical => is_upper_left && idx == 0,
-                        Axis::Horizontal => is_upper_left && idx == 0,
-                    };
-                    let member_upper_right = match pane_axis.axis {
-                        Axis::Vertical => is_upper_right && idx == 0,
-                        Axis::Horizontal => is_upper_right && idx == len - 1,
-                    };
-                    member.mark_positions(
-                        in_center_group,
-                        member_upper_left,
-                        member_upper_right,
-                        cx,
-                    );
+                for member in pane_axis.members.iter_mut() {
+                    member.mark_positions(in_center_group, cx);
                 }
             }
             Member::Pane(entity) => entity.update(cx, |pane, _| {
                 pane.in_center_group = in_center_group;
-                pane.is_upper_left = is_upper_left;
-                pane.is_upper_right = is_upper_right;
             }),
         }
     }

crates/workspace/src/utility_pane.rs 🔗

@@ -1,282 +0,0 @@
-use gpui::{
-    AppContext as _, EntityId, MouseButton, Pixels, Render, StatefulInteractiveElement,
-    Subscription, WeakEntity, deferred, px,
-};
-use ui::{
-    ActiveTheme as _, Context, FluentBuilder as _, InteractiveElement as _, IntoElement,
-    ParentElement as _, RenderOnce, Styled as _, Window, div,
-};
-
-use crate::{
-    DockPosition, Workspace,
-    dock::{ClosePane, MinimizePane, UtilityPane, UtilityPaneHandle},
-};
-
-pub(crate) const UTILITY_PANE_RESIZE_HANDLE_SIZE: Pixels = px(6.0);
-pub(crate) const UTILITY_PANE_MIN_WIDTH: Pixels = px(20.0);
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum UtilityPaneSlot {
-    Left,
-    Right,
-}
-
-struct UtilityPaneSlotState {
-    panel_id: EntityId,
-    utility_pane: Box<dyn UtilityPaneHandle>,
-    _subscriptions: Vec<Subscription>,
-}
-
-#[derive(Default)]
-pub struct UtilityPaneState {
-    left_slot: Option<UtilityPaneSlotState>,
-    right_slot: Option<UtilityPaneSlotState>,
-}
-
-#[derive(Clone)]
-pub struct DraggedUtilityPane(pub UtilityPaneSlot);
-
-impl Render for DraggedUtilityPane {
-    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
-        gpui::Empty
-    }
-}
-
-pub fn utility_slot_for_dock_position(position: DockPosition) -> UtilityPaneSlot {
-    match position {
-        DockPosition::Left => UtilityPaneSlot::Left,
-        DockPosition::Right => UtilityPaneSlot::Right,
-        DockPosition::Bottom => UtilityPaneSlot::Left,
-    }
-}
-
-impl Workspace {
-    pub fn utility_pane(&self, slot: UtilityPaneSlot) -> Option<&dyn UtilityPaneHandle> {
-        match slot {
-            UtilityPaneSlot::Left => self
-                .utility_panes
-                .left_slot
-                .as_ref()
-                .map(|s| s.utility_pane.as_ref()),
-            UtilityPaneSlot::Right => self
-                .utility_panes
-                .right_slot
-                .as_ref()
-                .map(|s| s.utility_pane.as_ref()),
-        }
-    }
-
-    pub fn toggle_utility_pane(
-        &mut self,
-        slot: UtilityPaneSlot,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        if let Some(handle) = self.utility_pane(slot) {
-            let current = handle.expanded(cx);
-            handle.set_expanded(!current, cx);
-        }
-        cx.notify();
-        self.serialize_workspace(window, cx);
-    }
-
-    pub fn register_utility_pane<T: UtilityPane>(
-        &mut self,
-        slot: UtilityPaneSlot,
-        panel_id: EntityId,
-        handle: gpui::Entity<T>,
-        cx: &mut Context<Self>,
-    ) {
-        let minimize_subscription =
-            cx.subscribe(&handle, move |this, _, _event: &MinimizePane, cx| {
-                if let Some(handle) = this.utility_pane(slot) {
-                    handle.set_expanded(false, cx);
-                }
-                cx.notify();
-            });
-
-        let close_subscription = cx.subscribe(&handle, move |this, _, _event: &ClosePane, cx| {
-            this.clear_utility_pane(slot, cx);
-        });
-
-        let subscriptions = vec![minimize_subscription, close_subscription];
-        let boxed_handle: Box<dyn UtilityPaneHandle> = Box::new(handle);
-
-        match slot {
-            UtilityPaneSlot::Left => {
-                self.utility_panes.left_slot = Some(UtilityPaneSlotState {
-                    panel_id,
-                    utility_pane: boxed_handle,
-                    _subscriptions: subscriptions,
-                });
-            }
-            UtilityPaneSlot::Right => {
-                self.utility_panes.right_slot = Some(UtilityPaneSlotState {
-                    panel_id,
-                    utility_pane: boxed_handle,
-                    _subscriptions: subscriptions,
-                });
-            }
-        }
-        cx.notify();
-    }
-
-    pub fn clear_utility_pane(&mut self, slot: UtilityPaneSlot, cx: &mut Context<Self>) {
-        match slot {
-            UtilityPaneSlot::Left => {
-                self.utility_panes.left_slot = None;
-            }
-            UtilityPaneSlot::Right => {
-                self.utility_panes.right_slot = None;
-            }
-        }
-        cx.notify();
-    }
-
-    pub fn clear_utility_pane_if_provider(
-        &mut self,
-        slot: UtilityPaneSlot,
-        provider_panel_id: EntityId,
-        cx: &mut Context<Self>,
-    ) {
-        let should_clear = match slot {
-            UtilityPaneSlot::Left => self
-                .utility_panes
-                .left_slot
-                .as_ref()
-                .is_some_and(|slot| slot.panel_id == provider_panel_id),
-            UtilityPaneSlot::Right => self
-                .utility_panes
-                .right_slot
-                .as_ref()
-                .is_some_and(|slot| slot.panel_id == provider_panel_id),
-        };
-
-        if should_clear {
-            self.clear_utility_pane(slot, cx);
-        }
-    }
-
-    pub fn resize_utility_pane(
-        &mut self,
-        slot: UtilityPaneSlot,
-        new_width: Pixels,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        if let Some(handle) = self.utility_pane(slot) {
-            let max_width = self.max_utility_pane_width(window, cx);
-            let width = new_width.max(UTILITY_PANE_MIN_WIDTH).min(max_width);
-            handle.set_width(Some(width), cx);
-            cx.notify();
-            self.serialize_workspace(window, cx);
-        }
-    }
-
-    pub fn reset_utility_pane_width(
-        &mut self,
-        slot: UtilityPaneSlot,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        if let Some(handle) = self.utility_pane(slot) {
-            handle.set_width(None, cx);
-            cx.notify();
-            self.serialize_workspace(window, cx);
-        }
-    }
-}
-
-#[derive(IntoElement)]
-pub struct UtilityPaneFrame {
-    workspace: WeakEntity<Workspace>,
-    slot: UtilityPaneSlot,
-    handle: Box<dyn UtilityPaneHandle>,
-}
-
-impl UtilityPaneFrame {
-    pub fn new(
-        slot: UtilityPaneSlot,
-        handle: Box<dyn UtilityPaneHandle>,
-        cx: &mut Context<Workspace>,
-    ) -> Self {
-        let workspace = cx.weak_entity();
-        Self {
-            workspace,
-            slot,
-            handle,
-        }
-    }
-}
-
-impl RenderOnce for UtilityPaneFrame {
-    fn render(self, _window: &mut Window, cx: &mut ui::App) -> impl IntoElement {
-        let workspace = self.workspace.clone();
-        let slot = self.slot;
-        let width = self.handle.width(cx);
-
-        let create_resize_handle = || {
-            let workspace_handle = workspace.clone();
-            let handle = div()
-                .id(match slot {
-                    UtilityPaneSlot::Left => "utility-pane-resize-handle-left",
-                    UtilityPaneSlot::Right => "utility-pane-resize-handle-right",
-                })
-                .on_drag(DraggedUtilityPane(slot), move |pane, _, _, cx| {
-                    cx.stop_propagation();
-                    cx.new(|_| pane.clone())
-                })
-                .on_mouse_down(MouseButton::Left, move |_, _, cx| {
-                    cx.stop_propagation();
-                })
-                .on_mouse_up(
-                    MouseButton::Left,
-                    move |e: &gpui::MouseUpEvent, window, cx| {
-                        if e.click_count == 2 {
-                            workspace_handle
-                                .update(cx, |workspace, cx| {
-                                    workspace.reset_utility_pane_width(slot, window, cx);
-                                })
-                                .ok();
-                            cx.stop_propagation();
-                        }
-                    },
-                )
-                .occlude();
-
-            match slot {
-                UtilityPaneSlot::Left => deferred(
-                    handle
-                        .absolute()
-                        .right(-UTILITY_PANE_RESIZE_HANDLE_SIZE / 2.)
-                        .top(px(0.))
-                        .h_full()
-                        .w(UTILITY_PANE_RESIZE_HANDLE_SIZE)
-                        .cursor_col_resize(),
-                ),
-                UtilityPaneSlot::Right => deferred(
-                    handle
-                        .absolute()
-                        .left(-UTILITY_PANE_RESIZE_HANDLE_SIZE / 2.)
-                        .top(px(0.))
-                        .h_full()
-                        .w(UTILITY_PANE_RESIZE_HANDLE_SIZE)
-                        .cursor_col_resize(),
-                ),
-            }
-        };
-
-        div()
-            .h_full()
-            .bg(cx.theme().colors().tab_bar_background)
-            .w(width)
-            .border_color(cx.theme().colors().border)
-            .when(self.slot == UtilityPaneSlot::Left, |this| this.border_r_1())
-            .when(self.slot == UtilityPaneSlot::Right, |this| {
-                this.border_l_1()
-            })
-            .child(create_resize_handle())
-            .child(self.handle.to_any())
-            .into_any_element()
-    }
-}

crates/workspace/src/workspace.rs 🔗

@@ -17,7 +17,6 @@ pub mod tasks;
 mod theme_preview;
 mod toast_layer;
 mod toolbar;
-pub mod utility_pane;
 pub mod welcome;
 mod workspace_settings;
 
@@ -39,7 +38,6 @@ use client::{
 };
 use collections::{HashMap, HashSet, hash_map};
 use dock::{Dock, DockPosition, PanelButtons, PanelHandle, RESIZE_HANDLE_SIZE};
-use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt};
 use futures::{
     Future, FutureExt, StreamExt,
     channel::{
@@ -143,18 +141,13 @@ pub use workspace_settings::{
 };
 use zed_actions::{Spawn, feedback::FileBugReport};
 
-use crate::{
-    item::ItemBufferKind,
-    notifications::NotificationId,
-    utility_pane::{UTILITY_PANE_MIN_WIDTH, utility_slot_for_dock_position},
-};
+use crate::{item::ItemBufferKind, notifications::NotificationId};
 use crate::{
     persistence::{
         SerializedAxis,
         model::{DockData, DockStructure, SerializedItem, SerializedPane, SerializedPaneGroup},
     },
     security_modal::SecurityModal,
-    utility_pane::{DraggedUtilityPane, UtilityPaneFrame, UtilityPaneSlot, UtilityPaneState},
 };
 
 pub const SERIALIZATION_THROTTLE_TIME: Duration = Duration::from_millis(200);
@@ -1266,7 +1259,6 @@ pub struct Workspace {
     scheduled_tasks: Vec<Task<()>>,
     last_open_dock_positions: Vec<DockPosition>,
     removing: bool,
-    utility_panes: UtilityPaneState,
 }
 
 impl EventEmitter<Event> for Workspace {}
@@ -1695,7 +1687,6 @@ impl Workspace {
             scheduled_tasks: Vec::new(),
             last_open_dock_positions: Vec::new(),
             removing: false,
-            utility_panes: UtilityPaneState::default(),
         }
     }
 
@@ -2022,18 +2013,8 @@ impl Workspace {
         window: &mut Window,
         cx: &mut Context<Self>,
     ) {
-        let mut found_in_dock = None;
         for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
-            let found = dock.update(cx, |dock, cx| dock.remove_panel(panel, window, cx));
-
-            if found {
-                found_in_dock = Some(dock.clone());
-            }
-        }
-        if let Some(found_in_dock) = found_in_dock {
-            let position = found_in_dock.read(cx).position();
-            let slot = utility_slot_for_dock_position(position);
-            self.clear_utility_pane_if_provider(slot, Entity::entity_id(panel), cx);
+            dock.update(cx, |dock, cx| dock.remove_panel(panel, window, cx));
         }
     }
 
@@ -6903,7 +6884,6 @@ impl Workspace {
                 left_dock.resize_active_panel(Some(size), window, cx);
             }
         });
-        self.clamp_utility_pane_widths(window, cx);
     }
 
     fn resize_right_dock(&mut self, new_size: Pixels, window: &mut Window, cx: &mut App) {
@@ -6926,7 +6906,6 @@ impl Workspace {
                 right_dock.resize_active_panel(Some(size), window, cx);
             }
         });
-        self.clamp_utility_pane_widths(window, cx);
     }
 
     fn resize_bottom_dock(&mut self, new_size: Pixels, window: &mut Window, cx: &mut App) {
@@ -6941,42 +6920,6 @@ impl Workspace {
                 bottom_dock.resize_active_panel(Some(size), window, cx);
             }
         });
-        self.clamp_utility_pane_widths(window, cx);
-    }
-
-    fn max_utility_pane_width(&self, window: &Window, cx: &App) -> Pixels {
-        let left_dock_width = self
-            .left_dock
-            .read(cx)
-            .active_panel_size(window, cx)
-            .unwrap_or(px(0.0));
-        let right_dock_width = self
-            .right_dock
-            .read(cx)
-            .active_panel_size(window, cx)
-            .unwrap_or(px(0.0));
-        let center_pane_width = self.bounds.size.width - left_dock_width - right_dock_width;
-        center_pane_width - px(10.0)
-    }
-
-    fn clamp_utility_pane_widths(&mut self, window: &mut Window, cx: &mut App) {
-        let max_width = self.max_utility_pane_width(window, cx);
-
-        // Clamp left slot utility pane if it exists
-        if let Some(handle) = self.utility_pane(UtilityPaneSlot::Left) {
-            let current_width = handle.width(cx);
-            if current_width > max_width {
-                handle.set_width(Some(max_width.max(UTILITY_PANE_MIN_WIDTH)), cx);
-            }
-        }
-
-        // Clamp right slot utility pane if it exists
-        if let Some(handle) = self.utility_pane(UtilityPaneSlot::Right) {
-            let current_width = handle.width(cx);
-            if current_width > max_width {
-                handle.set_width(Some(max_width.max(UTILITY_PANE_MIN_WIDTH)), cx);
-            }
-        }
     }
 
     fn toggle_edit_predictions_all_files(
@@ -7483,34 +7426,7 @@ impl Render for Workspace {
                                             }
                                         },
                                     ))
-                                    .on_drag_move(cx.listener(
-                                        move |workspace,
-                                              e: &DragMoveEvent<DraggedUtilityPane>,
-                                              window,
-                                              cx| {
-                                            let slot = e.drag(cx).0;
-                                            match slot {
-                                                UtilityPaneSlot::Left => {
-                                                    let left_dock_width = workspace.left_dock.read(cx)
-                                                        .active_panel_size(window, cx)
-                                                        .unwrap_or(gpui::px(0.0));
-                                                    let new_width = e.event.position.x
-                                                        - workspace.bounds.left()
-                                                        - left_dock_width;
-                                                    workspace.resize_utility_pane(slot, new_width, window, cx);
-                                                }
-                                                UtilityPaneSlot::Right => {
-                                                    let right_dock_width = workspace.right_dock.read(cx)
-                                                        .active_panel_size(window, cx)
-                                                        .unwrap_or(gpui::px(0.0));
-                                                    let new_width = workspace.bounds.right()
-                                                        - e.event.position.x
-                                                        - right_dock_width;
-                                                    workspace.resize_utility_pane(slot, new_width, window, cx);
-                                                }
-                                            }
-                                        },
-                                    ))
+
                                 })
                                 .child({
                                     match bottom_dock_layout {
@@ -7530,15 +7446,7 @@ impl Render for Workspace {
                                                         window,
                                                         cx,
                                                     ))
-                                                    .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                        this.when_some(self.utility_pane(UtilityPaneSlot::Left), |this, pane| {
-                                                            this.when(pane.expanded(cx), |this| {
-                                                                this.child(
-                                                                    UtilityPaneFrame::new(UtilityPaneSlot::Left, pane.box_clone(), cx)
-                                                                )
-                                                            })
-                                                        })
-                                                    })
+
                                                     .child(
                                                         div()
                                                             .flex()
@@ -7580,15 +7488,7 @@ impl Render for Workspace {
                                                                     ),
                                                             ),
                                                     )
-                                                    .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                        this.when_some(self.utility_pane(UtilityPaneSlot::Right), |this, pane| {
-                                                            this.when(pane.expanded(cx), |this| {
-                                                                this.child(
-                                                                    UtilityPaneFrame::new(UtilityPaneSlot::Right, pane.box_clone(), cx)
-                                                                )
-                                                            })
-                                                        })
-                                                    })
+
                                                     .children(self.render_dock(
                                                         DockPosition::Right,
                                                         &self.right_dock,
@@ -7619,15 +7519,7 @@ impl Render for Workspace {
                                                             .flex_row()
                                                             .flex_1()
                                                             .children(self.render_dock(DockPosition::Left, &self.left_dock, window, cx))
-                                                            .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                                this.when_some(self.utility_pane(UtilityPaneSlot::Left), |this, pane| {
-                                                                    this.when(pane.expanded(cx), |this| {
-                                                                        this.child(
-                                                                            UtilityPaneFrame::new(UtilityPaneSlot::Left, pane.box_clone(), cx)
-                                                                        )
-                                                                    })
-                                                                })
-                                                            })
+
                                                             .child(
                                                                 div()
                                                                     .flex()
@@ -7655,13 +7547,7 @@ impl Render for Workspace {
                                                                             .when_some(paddings.1, |this, p| this.child(p.border_l_1())),
                                                                     )
                                                             )
-                                                            .when_some(self.utility_pane(UtilityPaneSlot::Right), |this, pane| {
-                                                                this.when(pane.expanded(cx), |this| {
-                                                                    this.child(
-                                                                        UtilityPaneFrame::new(UtilityPaneSlot::Right, pane.box_clone(), cx)
-                                                                    )
-                                                                })
-                                                            })
+
                                                     )
                                                     .child(
                                                         div()
@@ -7686,15 +7572,7 @@ impl Render for Workspace {
                                                 window,
                                                 cx,
                                             ))
-                                            .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                this.when_some(self.utility_pane(UtilityPaneSlot::Left), |this, pane| {
-                                                    this.when(pane.expanded(cx), |this| {
-                                                        this.child(
-                                                            UtilityPaneFrame::new(UtilityPaneSlot::Left, pane.box_clone(), cx)
-                                                        )
-                                                    })
-                                                })
-                                            })
+
                                             .child(
                                                 div()
                                                     .flex()
@@ -7733,15 +7611,7 @@ impl Render for Workspace {
                                                                             .when_some(paddings.1, |this, p| this.child(p.border_l_1())),
                                                                     )
                                                             )
-                                                            .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                                this.when_some(self.utility_pane(UtilityPaneSlot::Right), |this, pane| {
-                                                                    this.when(pane.expanded(cx), |this| {
-                                                                        this.child(
-                                                                            UtilityPaneFrame::new(UtilityPaneSlot::Right, pane.box_clone(), cx)
-                                                                        )
-                                                                    })
-                                                                })
-                                                            })
+
                                                             .children(self.render_dock(DockPosition::Right, &self.right_dock, window, cx))
                                                     )
                                                     .child(
@@ -7761,13 +7631,7 @@ impl Render for Workspace {
                                                 window,
                                                 cx,
                                             ))
-                                            .when_some(self.utility_pane(UtilityPaneSlot::Left), |this, pane| {
-                                                this.when(pane.expanded(cx), |this| {
-                                                    this.child(
-                                                        UtilityPaneFrame::new(UtilityPaneSlot::Left, pane.box_clone(), cx)
-                                                    )
-                                                })
-                                            })
+
                                             .child(
                                                 div()
                                                     .flex()
@@ -7805,15 +7669,7 @@ impl Render for Workspace {
                                                         cx,
                                                     )),
                                             )
-                                            .when(cx.has_flag::<AgentV2FeatureFlag>(), |this| {
-                                                this.when_some(self.utility_pane(UtilityPaneSlot::Right), |this, pane| {
-                                                    this.when(pane.expanded(cx), |this| {
-                                                        this.child(
-                                                            UtilityPaneFrame::new(UtilityPaneSlot::Right, pane.box_clone(), cx)
-                                                        )
-                                                    })
-                                                })
-                                            })
+
                                             .children(self.render_dock(
                                                 DockPosition::Right,
                                                 &self.right_dock,

crates/zed/Cargo.toml 🔗

@@ -69,7 +69,6 @@ agent.workspace = true
 agent-client-protocol.workspace = true
 agent_settings.workspace = true
 agent_ui.workspace = true
-agent_ui_v2.workspace = true
 anyhow.workspace = true
 askpass.workspace = true
 assets.workspace = true
@@ -257,7 +256,6 @@ title_bar = { workspace = true, features = ["test-support"] }
 workspace = { workspace = true, features = ["test-support"] }
 image.workspace = true
 agent_ui = { workspace = true, features = ["test-support"] }
-agent_ui_v2 = { workspace = true, features = ["test-support"] }
 search = { workspace = true, features = ["test-support"] }
 repl = { workspace = true, features = ["test-support"] }
 

crates/zed/src/main.rs 🔗

@@ -634,7 +634,7 @@ fn main() {
             false,
             cx,
         );
-        agent_ui_v2::agents_panel::init(cx);
+
         repl::init(app_state.fs.clone(), cx);
         recent_projects::init(cx);
         dev_container::init(cx);

crates/zed/src/zed.rs 🔗

@@ -14,7 +14,6 @@ pub mod visual_tests;
 pub(crate) mod windows_only_instance;
 
 use agent_ui::{AgentDiffToolbar, AgentPanelDelegate};
-use agent_ui_v2::agents_panel::AgentsPanel;
 use anyhow::Context as _;
 pub use app_menus::*;
 use assets::Assets;
@@ -87,7 +86,7 @@ use vim_mode_setting::VimModeSetting;
 use workspace::notifications::{
     NotificationId, SuppressEvent, dismiss_app_notification, show_app_notification,
 };
-use workspace::utility_pane::utility_slot_for_dock_position;
+
 use workspace::{
     AppState, MultiWorkspace, NewFile, NewWindow, OpenLog, Panel, Toast, Workspace,
     WorkspaceSettings, create_and_open_local_file,
@@ -657,8 +656,7 @@ fn initialize_panels(
             add_panel_when_ready(channels_panel, workspace_handle.clone(), cx.clone()),
             add_panel_when_ready(notification_panel, workspace_handle.clone(), cx.clone()),
             add_panel_when_ready(debug_panel, workspace_handle.clone(), cx.clone()),
-            initialize_agent_panel(workspace_handle.clone(), prompt_builder, cx.clone()).map(|r| r.log_err()),
-            initialize_agents_panel(workspace_handle, cx.clone()).map(|r| r.log_err())
+            initialize_agent_panel(workspace_handle, prompt_builder, cx.clone()).map(|r| r.log_err()),
         );
 
         anyhow::Ok(())
@@ -748,31 +746,6 @@ async fn initialize_agent_panel(
     anyhow::Ok(())
 }
 
-async fn initialize_agents_panel(
-    workspace_handle: WeakEntity<Workspace>,
-    mut cx: AsyncWindowContext,
-) -> anyhow::Result<()> {
-    workspace_handle
-        .update_in(&mut cx, |workspace, window, cx| {
-            setup_or_teardown_ai_panel(workspace, window, cx, |workspace, cx| {
-                AgentsPanel::load(workspace, cx)
-            })
-        })?
-        .await?;
-
-    workspace_handle.update_in(&mut cx, |_workspace, window, cx| {
-        cx.observe_global_in::<SettingsStore>(window, move |workspace, window, cx| {
-            setup_or_teardown_ai_panel(workspace, window, cx, |workspace, cx| {
-                AgentsPanel::load(workspace, cx)
-            })
-            .detach_and_log_err(cx);
-        })
-        .detach();
-    })?;
-
-    anyhow::Ok(())
-}
-
 fn register_actions(
     app_state: Arc<AppState>,
     workspace: &mut Workspace,
@@ -1067,18 +1040,6 @@ fn register_actions(
                 workspace.toggle_panel_focus::<TerminalPanel>(window, cx);
             },
         )
-        .register_action(
-            |workspace: &mut Workspace,
-             _: &zed_actions::agent::ToggleAgentPane,
-             window: &mut Window,
-             cx: &mut Context<Workspace>| {
-                if let Some(panel) = workspace.panel::<AgentsPanel>(cx) {
-                    let position = panel.read(cx).position(window, cx);
-                    let slot = utility_slot_for_dock_position(position);
-                    workspace.toggle_utility_pane(slot, window, cx);
-                }
-            },
-        )
         .register_action({
             let app_state = Arc::downgrade(&app_state);
             move |_, _: &NewWindow, _, cx| {
@@ -4826,7 +4787,6 @@ mod tests {
                 "action",
                 "activity_indicator",
                 "agent",
-                "agents",
                 "app_menu",
                 "assistant",
                 "assistant2",
@@ -5071,7 +5031,7 @@ mod tests {
                 false,
                 cx,
             );
-            agent_ui_v2::agents_panel::init(cx);
+
             repl::init(app_state.fs.clone(), cx);
             repl::notebook::init(cx);
             tasks_ui::init(cx);

crates/zed_actions/src/lib.rs 🔗

@@ -450,8 +450,6 @@ pub mod agent {
             AddSelectionToThread,
             /// Resets the agent panel zoom levels (agent UI and buffer font sizes).
             ResetAgentZoom,
-            /// Toggles the utility/agent pane open/closed state.
-            ToggleAgentPane,
             /// Pastes clipboard content without any formatting.
             PasteRaw,
         ]