Skip to content

Commit d04ac86

Browse files
authored
Don't construct an agent panel when disable_ai is set (#39689)
Follow-up to #39649, possible fix for #39669 This implements an alternate strategy for showing/hiding the agent panel in response to `disable_ai`. We don't load the panel at all if AI is disabled at startup, and when the value of `disable_ai` changes, we load the panel or destroy it as needed. Release Notes: - N/A
1 parent f9a2724 commit d04ac86

File tree

3 files changed

+64
-61
lines changed

3 files changed

+64
-61
lines changed

crates/agent_ui/src/agent_panel.rs

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ use editor::{Anchor, AnchorRangeExt as _, Editor, EditorEvent, MultiBuffer};
4848
use fs::Fs;
4949
use gpui::{
5050
Action, AnyElement, App, AsyncWindowContext, Corner, DismissEvent, Entity, EventEmitter,
51-
ExternalPaths, FocusHandle, Focusable, KeyContext, Pixels, ReadGlobal as _, Subscription, Task,
52-
UpdateGlobal, WeakEntity, prelude::*,
51+
ExternalPaths, FocusHandle, Focusable, KeyContext, Pixels, Subscription, Task, UpdateGlobal,
52+
WeakEntity, prelude::*,
5353
};
5454
use language::LanguageRegistry;
5555
use language_model::{ConfigurationError, LanguageModelRegistry};
56-
use project::{DisableAiSettings, Project, ProjectPath, Worktree};
56+
use project::{Project, ProjectPath, Worktree};
5757
use prompt_store::{PromptBuilder, PromptStore, UserPromptId};
5858
use rules_library::{RulesLibrary, open_rules_library};
5959
use search::{BufferSearchBar, buffer_search};
@@ -520,13 +520,6 @@ impl AgentPanel {
520520
)
521521
});
522522

523-
if SettingsStore::global(cx)
524-
.get::<DisableAiSettings>(None)
525-
.disable_ai
526-
{
527-
return panel;
528-
}
529-
530523
panel.as_mut(cx).loading = true;
531524
if let Some(serialized_panel) = serialized_panel {
532525
panel.update(cx, |panel, cx| {
@@ -678,43 +671,6 @@ impl AgentPanel {
678671
)
679672
});
680673

681-
let mut old_disable_ai = false;
682-
cx.observe_global_in::<SettingsStore>(window, move |panel, window, cx| {
683-
let disable_ai = DisableAiSettings::get_global(cx).disable_ai;
684-
if old_disable_ai != disable_ai {
685-
let agent_panel_id = cx.entity_id();
686-
let agent_panel_visible = panel
687-
.workspace
688-
.update(cx, |workspace, cx| {
689-
let agent_dock_position = panel.position(window, cx);
690-
let agent_dock = workspace.dock_at_position(agent_dock_position);
691-
let agent_panel_focused = agent_dock
692-
.read(cx)
693-
.active_panel()
694-
.is_some_and(|panel| panel.panel_id() == agent_panel_id);
695-
696-
let active_panel_visible = agent_dock
697-
.read(cx)
698-
.visible_panel()
699-
.is_some_and(|panel| panel.panel_id() == agent_panel_id);
700-
701-
if agent_panel_focused {
702-
cx.dispatch_action(&ToggleFocus);
703-
}
704-
705-
active_panel_visible
706-
})
707-
.unwrap_or_default();
708-
709-
if agent_panel_visible {
710-
cx.emit(PanelEvent::Close);
711-
}
712-
713-
old_disable_ai = disable_ai;
714-
}
715-
})
716-
.detach();
717-
718674
Self {
719675
active_view,
720676
workspace,

crates/workspace/src/workspace.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,19 @@ impl Workspace {
17481748
});
17491749
}
17501750

1751+
pub fn remove_panel<T: Panel>(
1752+
&mut self,
1753+
panel: &Entity<T>,
1754+
window: &mut Window,
1755+
cx: &mut Context<Self>,
1756+
) {
1757+
for dock in [&self.left_dock, &self.bottom_dock, &self.right_dock] {
1758+
dock.update(cx, |dock, cx| {
1759+
dock.remove_panel(panel, window, cx);
1760+
})
1761+
}
1762+
}
1763+
17511764
pub fn status_bar(&self) -> &Entity<StatusBar> {
17521765
&self.status_bar
17531766
}

crates/zed/src/zed.rs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use paths::{
4646
local_debug_file_relative_path, local_settings_file_relative_path,
4747
local_tasks_file_relative_path,
4848
};
49-
use project::{DirectoryLister, ProjectItem};
49+
use project::{DirectoryLister, DisableAiSettings, ProjectItem};
5050
use project_panel::ProjectPanel;
5151
use prompt_store::PromptBuilder;
5252
use quick_action_bar::QuickActionBar;
@@ -604,29 +604,63 @@ fn initialize_panels(
604604
workspace.add_panel(debug_panel, window, cx);
605605
})?;
606606

607-
let is_assistant2_enabled = !cfg!(test);
608-
let agent_panel = if is_assistant2_enabled {
609-
let agent_panel =
610-
agent_ui::AgentPanel::load(workspace_handle.clone(), prompt_builder, cx.clone())
611-
.await?;
607+
fn setup_or_teardown_agent_panel(
608+
workspace: &mut Workspace,
609+
prompt_builder: Arc<PromptBuilder>,
610+
window: &mut Window,
611+
cx: &mut Context<Workspace>,
612+
) -> Task<anyhow::Result<()>> {
613+
let disable_ai = SettingsStore::global(cx)
614+
.get::<DisableAiSettings>(None)
615+
.disable_ai
616+
|| cfg!(test);
617+
let existing_panel = workspace.panel::<agent_ui::AgentPanel>(cx);
618+
match (disable_ai, existing_panel) {
619+
(false, None) => cx.spawn_in(window, async move |workspace, cx| {
620+
let panel =
621+
agent_ui::AgentPanel::load(workspace.clone(), prompt_builder, cx.clone())
622+
.await?;
623+
workspace.update_in(cx, |workspace, window, cx| {
624+
let disable_ai = SettingsStore::global(cx)
625+
.get::<DisableAiSettings>(None)
626+
.disable_ai;
627+
let have_panel = workspace.panel::<agent_ui::AgentPanel>(cx).is_some();
628+
if !disable_ai && !have_panel {
629+
workspace.add_panel(panel, window, cx);
630+
}
631+
})
632+
}),
633+
(true, Some(existing_panel)) => {
634+
workspace.remove_panel::<agent_ui::AgentPanel>(&existing_panel, window, cx);
635+
Task::ready(Ok(()))
636+
}
637+
_ => Task::ready(Ok(())),
638+
}
639+
}
612640

613-
Some(agent_panel)
614-
} else {
615-
None
616-
};
641+
workspace_handle
642+
.update_in(cx, |workspace, window, cx| {
643+
setup_or_teardown_agent_panel(workspace, prompt_builder.clone(), window, cx)
644+
})?
645+
.await?;
617646

618647
workspace_handle.update_in(cx, |workspace, window, cx| {
619-
if let Some(agent_panel) = agent_panel {
620-
workspace.add_panel(agent_panel, window, cx);
621-
}
648+
cx.observe_global_in::<SettingsStore>(window, {
649+
let prompt_builder = prompt_builder.clone();
650+
move |workspace, window, cx| {
651+
setup_or_teardown_agent_panel(workspace, prompt_builder.clone(), window, cx)
652+
.detach_and_log_err(cx);
653+
}
654+
})
655+
.detach();
622656

623657
// Register the actions that are shared between `assistant` and `assistant2`.
624658
//
625659
// We need to do this here instead of within the individual `init`
626660
// functions so that we only register the actions once.
627661
//
628662
// Once we ship `assistant2` we can push this back down into `agent::agent_panel::init`.
629-
if is_assistant2_enabled {
663+
if !cfg!(test) {
630664
<dyn AgentPanelDelegate>::set_global(
631665
Arc::new(agent_ui::ConcreteAssistantPanelDelegate),
632666
cx,

0 commit comments

Comments
 (0)