agent: Add setting to control edit card expanded state (#34040)

Danilo Leal created

This PR adds the `expand_edit_card` setting, which controls whether edit
cards in the agent panel are expanded, thus showing or not the full diff
of a given file's AI-driven change. I personally prefer to have these
cards collapsed by default as I am mostly reviewing diffs using either
the review multibuffer or the diffs within the file's buffer itself.
Didn't want to change the default behavior as that was intentionally
chosen, so here we are! :)

Open to feedback about the setting name; I've iterated between a few
options and don't necessarily feel like the current one is the best.

Release Notes:

- agent: Added a setting to control whether edit cards are expanded in
the agent panel, thus showing or hiding the full diff of a file's
changes.

Change summary

assets/settings/default.json                 |  6 ++++
crates/agent_settings/src/agent_settings.rs  |  6 +++++
crates/assistant_tools/src/edit_file_tool.rs | 26 ++++++++++++++++++++-
docs/src/ai/configuration.md                 | 16 +++++++++++++
4 files changed, 51 insertions(+), 3 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -857,7 +857,11 @@
     // its response, or needs user input.
 
     // Default: false
-    "play_sound_when_agent_done": false
+    "play_sound_when_agent_done": false,
+    /// Whether to have edit cards in the agent panel expanded, showing a preview of the full diff.
+    ///
+    /// Default: true
+    "expand_edit_card": true
   },
   // The settings for slash commands.
   "slash_commands": {

crates/agent_settings/src/agent_settings.rs 🔗

@@ -67,6 +67,7 @@ pub struct AgentSettings {
     pub model_parameters: Vec<LanguageModelParameters>,
     pub preferred_completion_mode: CompletionMode,
     pub enable_feedback: bool,
+    pub expand_edit_card: bool,
 }
 
 impl AgentSettings {
@@ -291,6 +292,10 @@ pub struct AgentSettingsContent {
     ///
     /// Default: true
     enable_feedback: Option<bool>,
+    /// Whether to have edit cards in the agent panel expanded, showing a preview of the full diff.
+    ///
+    /// Default: true
+    expand_edit_card: Option<bool>,
 }
 
 #[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
@@ -441,6 +446,7 @@ impl Settings for AgentSettings {
                 value.preferred_completion_mode,
             );
             merge(&mut settings.enable_feedback, value.enable_feedback);
+            merge(&mut settings.expand_edit_card, value.expand_edit_card);
 
             settings
                 .model_parameters

crates/assistant_tools/src/edit_file_tool.rs 🔗

@@ -4,6 +4,7 @@ use crate::{
     schema::json_schema_for,
     ui::{COLLAPSED_LINES, ToolOutputPreview},
 };
+use agent_settings;
 use anyhow::{Context as _, Result, anyhow};
 use assistant_tool::{
     ActionLog, AnyToolCard, Tool, ToolCard, ToolResult, ToolResultContent, ToolResultOutput,
@@ -14,7 +15,7 @@ use editor::{Editor, EditorMode, MinimapVisibility, MultiBuffer, PathKey};
 use futures::StreamExt;
 use gpui::{
     Animation, AnimationExt, AnyWindowHandle, App, AppContext, AsyncApp, Entity, Task,
-    TextStyleRefinement, WeakEntity, pulsating_between, px,
+    TextStyleRefinement, Transformation, WeakEntity, percentage, pulsating_between, px,
 };
 use indoc::formatdoc;
 use language::{
@@ -515,7 +516,9 @@ pub struct EditFileToolCard {
 
 impl EditFileToolCard {
     pub fn new(path: PathBuf, project: Entity<Project>, window: &mut Window, cx: &mut App) -> Self {
+        let expand_edit_card = agent_settings::AgentSettings::get_global(cx).expand_edit_card;
         let multibuffer = cx.new(|_| MultiBuffer::without_headers(Capability::ReadOnly));
+
         let editor = cx.new(|cx| {
             let mut editor = Editor::new(
                 EditorMode::Full {
@@ -556,7 +559,7 @@ impl EditFileToolCard {
             diff_task: None,
             preview_expanded: true,
             error_expanded: None,
-            full_height_expanded: true,
+            full_height_expanded: expand_edit_card,
             total_lines: None,
         }
     }
@@ -755,6 +758,13 @@ impl ToolCard for EditFileToolCard {
             _ => None,
         };
 
+        let running_or_pending = match status {
+            ToolUseStatus::Running | ToolUseStatus::Pending => Some(()),
+            _ => None,
+        };
+
+        let should_show_loading = running_or_pending.is_some() && !self.full_height_expanded;
+
         let path_label_button = h_flex()
             .id(("edit-tool-path-label-button", self.editor.entity_id()))
             .w_full()
@@ -863,6 +873,18 @@ impl ToolCard for EditFileToolCard {
                 header.bg(codeblock_header_bg)
             })
             .child(path_label_button)
+            .when(should_show_loading, |header| {
+                header.pr_1p5().child(
+                    Icon::new(IconName::ArrowCircle)
+                        .size(IconSize::XSmall)
+                        .color(Color::Info)
+                        .with_animation(
+                            "arrow-circle",
+                            Animation::new(Duration::from_secs(2)).repeat(),
+                            |icon, delta| icon.transform(Transformation::rotate(percentage(delta))),
+                        ),
+                )
+            })
             .when_some(error_message, |header, error_message| {
                 header.child(
                     h_flex()

docs/src/ai/configuration.md 🔗

@@ -646,3 +646,19 @@ You can choose between `thread` (the default) and `text_thread`:
   }
 }
 ```
+
+### Edit Card
+
+Use the `expand_edit_card` setting to control whether edit cards show the full diff in the Agent Panel.
+It is set to `true` by default, but if set to false, the card's height is capped to a certain number of lines, requiring a click to be expanded.
+
+```json
+{
+  "agent": {
+    "expand_edit_card": "false"
+  }
+}
+```
+
+This setting is currently only available in Preview.
+It should be up in Stable by the next release.