assistant2: Add an option to enable/disable all tools (#26544)

Marshall Bowers created

This PR adds an option to enable or disable all tools in the tool
selector.

<img width="1297" alt="Screenshot 2025-03-12 at 10 40 28 AM"
src="https://github.com/user-attachments/assets/9125bdfb-5b54-461c-a065-2882a8585a67"
/>

Release Notes:

- N/A

Change summary

crates/assistant2/src/tool_selector.rs        | 18 ++++++++++
crates/assistant_tool/src/tool_working_set.rs | 36 ++++++++++++++++++--
2 files changed, 50 insertions(+), 4 deletions(-)

Detailed changes

crates/assistant2/src/tool_selector.rs 🔗

@@ -22,6 +22,24 @@ impl ToolSelector {
         ContextMenu::build(window, cx, |mut menu, _window, cx| {
             let tools_by_source = self.tools.tools_by_source(cx);
 
+            let all_tools_enabled = self.tools.are_all_tools_enabled();
+            menu = menu.header("Tools").toggleable_entry(
+                "All Tools",
+                all_tools_enabled,
+                IconPosition::End,
+                None,
+                {
+                    let tools = self.tools.clone();
+                    move |_window, cx| {
+                        if all_tools_enabled {
+                            tools.disable_all_tools(cx);
+                        } else {
+                            tools.enable_all_tools();
+                        }
+                    }
+                },
+            );
+
             for (source, tools) in tools_by_source {
                 let mut tools = tools
                     .into_iter()

crates/assistant_tool/src/tool_working_set.rs 🔗

@@ -26,11 +26,11 @@ struct WorkingSetState {
 impl Default for WorkingSetState {
     fn default() -> Self {
         Self {
-            context_server_tools_by_id: Default::default(),
-            context_server_tools_by_name: Default::default(),
-            disabled_tools_by_source: Default::default(),
+            context_server_tools_by_id: HashMap::default(),
+            context_server_tools_by_name: HashMap::default(),
+            disabled_tools_by_source: HashMap::default(),
             is_scripting_tool_disabled: true,
-            next_tool_id: Default::default(),
+            next_tool_id: ToolId::default(),
         }
     }
 }
@@ -58,6 +58,34 @@ impl ToolWorkingSet {
         tools
     }
 
+    pub fn are_all_tools_enabled(&self) -> bool {
+        let state = self.state.lock();
+
+        state.disabled_tools_by_source.is_empty() && !state.is_scripting_tool_disabled
+    }
+
+    pub fn enable_all_tools(&self) {
+        let mut state = self.state.lock();
+
+        state.disabled_tools_by_source.clear();
+        state.is_scripting_tool_disabled = false;
+    }
+
+    pub fn disable_all_tools(&self, cx: &App) {
+        let tools = self.tools_by_source(cx);
+
+        for (source, tools) in tools {
+            let tool_names = tools
+                .into_iter()
+                .map(|tool| tool.name().into())
+                .collect::<Vec<_>>();
+
+            self.disable(source, &tool_names);
+        }
+
+        self.disable_scripting_tool();
+    }
+
     pub fn enabled_tools(&self, cx: &App) -> Vec<Arc<dyn Tool>> {
         let all_tools = self.tools(cx);