agent: Add the `single_file_review` setting to the UI (#29859)

Danilo Leal created

Release Notes:

- agent: Add the `single_file_review` setting to the UI

Change summary

crates/agent/src/assistant_configuration.rs         | 116 ++++++++++----
crates/assistant_settings/src/assistant_settings.rs |   8 +
2 files changed, 88 insertions(+), 36 deletions(-)

Detailed changes

crates/agent/src/assistant_configuration.rs 🔗

@@ -214,47 +214,91 @@ impl AssistantConfiguration {
     fn render_command_permission(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
         let always_allow_tool_actions = AssistantSettings::get_global(cx).always_allow_tool_actions;
 
-        const HEADING: &str = "Allow running editing tools without asking for confirmation";
-
-        v_flex()
-            .p(DynamicSpacing::Base16.rems(cx))
-            .pr(DynamicSpacing::Base20.rems(cx))
-            .gap_2()
-            .flex_1()
-            .child(Headline::new("General Settings"))
+        h_flex()
+            .gap_4()
+            .justify_between()
+            .flex_wrap()
             .child(
-                h_flex()
-                    .gap_4()
-                    .justify_between()
-                    .flex_wrap()
+                v_flex()
+                    .gap_0p5()
+                    .max_w_5_6()
+                    .child(Label::new("Allow running editing tools without asking for confirmation"))
                     .child(
-                        v_flex()
-                            .gap_0p5()
-                            .max_w_5_6()
-                            .child(Label::new(HEADING))
-                            .child(Label::new("When enabled, the agent can perform potentially destructive actions without asking for your confirmation.").color(Color::Muted)),
-                    )
+                        Label::new(
+                            "The agent can perform potentially destructive actions without asking for your confirmation.",
+                        )
+                        .color(Color::Muted),
+                    ),
+            )
+            .child(
+                Switch::new(
+                    "always-allow-tool-actions-switch",
+                    always_allow_tool_actions.into(),
+                )
+                .color(SwitchColor::Accent)
+                .on_click({
+                    let fs = self.fs.clone();
+                    move |state, _window, cx| {
+                        let allow = state == &ToggleState::Selected;
+                        update_settings_file::<AssistantSettings>(
+                            fs.clone(),
+                            cx,
+                            move |settings, _| {
+                                settings.set_always_allow_tool_actions(allow);
+                            },
+                        );
+                    }
+                }),
+            )
+    }
+
+    fn render_single_file_review(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
+        let single_file_review = AssistantSettings::get_global(cx).single_file_review;
+
+        h_flex()
+            .gap_4()
+            .justify_between()
+            .flex_wrap()
+            .child(
+                v_flex()
+                    .gap_0p5()
+                    .max_w_5_6()
+                    .child(Label::new("Enable single-file agent reviews"))
                     .child(
-                        Switch::new(
-                            "always-allow-tool-actions-switch",
-                            always_allow_tool_actions.into(),
+                        Label::new(
+                            "Agent edits are also displayed in single-file editors for review.",
                         )
-                        .color(SwitchColor::Accent)
-                        .on_click({
-                            let fs = self.fs.clone();
-                            move |state, _window, cx| {
-                                let allow = state == &ToggleState::Selected;
-                                update_settings_file::<AssistantSettings>(
-                                    fs.clone(),
-                                    cx,
-                                    move |settings, _| {
-                                        settings.set_always_allow_tool_actions(allow);
-                                    },
-                                );
-                            }
-                        }),
+                        .color(Color::Muted),
                     ),
             )
+            .child(
+                Switch::new("single-file-review-switch", single_file_review.into())
+                    .color(SwitchColor::Accent)
+                    .on_click({
+                        let fs = self.fs.clone();
+                        move |state, _window, cx| {
+                            let allow = state == &ToggleState::Selected;
+                            update_settings_file::<AssistantSettings>(
+                                fs.clone(),
+                                cx,
+                                move |settings, _| {
+                                    settings.set_single_file_review(allow);
+                                },
+                            );
+                        }
+                    }),
+            )
+    }
+
+    fn render_general_settings_section(&mut self, cx: &mut Context<Self>) -> impl IntoElement {
+        v_flex()
+            .p(DynamicSpacing::Base16.rems(cx))
+            .pr(DynamicSpacing::Base20.rems(cx))
+            .gap_2p5()
+            .flex_1()
+            .child(Headline::new("General Settings"))
+            .child(self.render_command_permission(cx))
+            .child(self.render_single_file_review(cx))
     }
 
     fn render_context_servers_section(
@@ -549,7 +593,7 @@ impl Render for AssistantConfiguration {
                     .track_scroll(&self.scroll_handle)
                     .size_full()
                     .overflow_y_scroll()
-                    .child(self.render_command_permission(cx))
+                    .child(self.render_general_settings_section(cx))
                     .child(Divider::horizontal().color(DividerColor::Border))
                     .child(self.render_context_servers_section(window, cx))
                     .child(Divider::horizontal().color(DividerColor::Border))

crates/assistant_settings/src/assistant_settings.rs 🔗

@@ -433,6 +433,14 @@ impl AssistantSettingsContent {
         .ok();
     }
 
+    pub fn set_single_file_review(&mut self, allow: bool) {
+        self.v2_setting(|setting| {
+            setting.single_file_review = Some(allow);
+            Ok(())
+        })
+        .ok();
+    }
+
     pub fn set_profile(&mut self, profile_id: AgentProfileId) {
         self.v2_setting(|setting| {
             setting.default_profile = Some(profile_id);