agent: Add setting to control terminal card expanded state (#34061)

Similar to https://github.com/zed-industries/zed/pull/34040, this PR
allows to control via settings whether the terminal card in the agent
panel should be expanded. It is set to true by default.

Release Notes:

- agent: Added a setting to control whether terminal cards are expanded
in the agent panel, thus showing or hiding the full command output.
This commit is contained in:
Danilo Leal 2025-07-08 10:43:35 -03:00 committed by GitHub
parent 5e15c05a9d
commit 3327f90e0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 79 additions and 32 deletions

View file

@ -861,7 +861,11 @@
/// Whether to have edit cards in the agent panel expanded, showing a preview of the full diff. /// Whether to have edit cards in the agent panel expanded, showing a preview of the full diff.
/// ///
/// Default: true /// Default: true
"expand_edit_card": true "expand_edit_card": true,
/// Whether to have terminal cards in the agent panel expanded, showing the whole command output.
///
/// Default: true
"expand_terminal_card": true
}, },
// The settings for slash commands. // The settings for slash commands.
"slash_commands": { "slash_commands": {

View file

@ -68,6 +68,7 @@ pub struct AgentSettings {
pub preferred_completion_mode: CompletionMode, pub preferred_completion_mode: CompletionMode,
pub enable_feedback: bool, pub enable_feedback: bool,
pub expand_edit_card: bool, pub expand_edit_card: bool,
pub expand_terminal_card: bool,
} }
impl AgentSettings { impl AgentSettings {
@ -296,6 +297,10 @@ pub struct AgentSettingsContent {
/// ///
/// Default: true /// Default: true
expand_edit_card: Option<bool>, expand_edit_card: Option<bool>,
/// Whether to have terminal cards in the agent panel expanded, showing the whole command output.
///
/// Default: true
expand_terminal_card: Option<bool>,
} }
#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)] #[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Default)]
@ -447,6 +452,10 @@ impl Settings for AgentSettings {
); );
merge(&mut settings.enable_feedback, value.enable_feedback); merge(&mut settings.enable_feedback, value.enable_feedback);
merge(&mut settings.expand_edit_card, value.expand_edit_card); merge(&mut settings.expand_edit_card, value.expand_edit_card);
merge(
&mut settings.expand_terminal_card,
value.expand_terminal_card,
);
settings settings
.model_parameters .model_parameters

View file

@ -2,12 +2,13 @@ use crate::{
schema::json_schema_for, schema::json_schema_for,
ui::{COLLAPSED_LINES, ToolOutputPreview}, ui::{COLLAPSED_LINES, ToolOutputPreview},
}; };
use agent_settings;
use anyhow::{Context as _, Result, anyhow}; use anyhow::{Context as _, Result, anyhow};
use assistant_tool::{ActionLog, Tool, ToolCard, ToolResult, ToolUseStatus}; use assistant_tool::{ActionLog, Tool, ToolCard, ToolResult, ToolUseStatus};
use futures::{FutureExt as _, future::Shared}; use futures::{FutureExt as _, future::Shared};
use gpui::{ use gpui::{
AnyWindowHandle, App, AppContext, Empty, Entity, EntityId, Task, TextStyleRefinement, Animation, AnimationExt, AnyWindowHandle, App, AppContext, Empty, Entity, EntityId, Task,
WeakEntity, Window, TextStyleRefinement, Transformation, WeakEntity, Window, percentage,
}; };
use language::LineEnding; use language::LineEnding;
use language_model::{LanguageModel, LanguageModelRequest, LanguageModelToolSchemaFormat}; use language_model::{LanguageModel, LanguageModelRequest, LanguageModelToolSchemaFormat};
@ -247,6 +248,7 @@ impl Tool for TerminalTool {
command_markdown.clone(), command_markdown.clone(),
working_dir.clone(), working_dir.clone(),
cx.entity_id(), cx.entity_id(),
cx,
) )
}); });
@ -441,7 +443,10 @@ impl TerminalToolCard {
input_command: Entity<Markdown>, input_command: Entity<Markdown>,
working_dir: Option<PathBuf>, working_dir: Option<PathBuf>,
entity_id: EntityId, entity_id: EntityId,
cx: &mut Context<Self>,
) -> Self { ) -> Self {
let expand_terminal_card =
agent_settings::AgentSettings::get_global(cx).expand_terminal_card;
Self { Self {
input_command, input_command,
working_dir, working_dir,
@ -453,7 +458,7 @@ impl TerminalToolCard {
finished_with_empty_output: false, finished_with_empty_output: false,
original_content_len: 0, original_content_len: 0,
content_line_count: 0, content_line_count: 0,
preview_expanded: true, preview_expanded: expand_terminal_card,
start_instant: Instant::now(), start_instant: Instant::now(),
elapsed_time: None, elapsed_time: None,
} }
@ -518,6 +523,46 @@ impl ToolCard for TerminalToolCard {
.color(Color::Muted), .color(Color::Muted),
), ),
) )
.when(!self.command_finished, |header| {
header.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(tool_failed || command_failed, |header| {
header.child(
div()
.id(("terminal-tool-error-code-indicator", self.entity_id))
.child(
Icon::new(IconName::Close)
.size(IconSize::Small)
.color(Color::Error),
)
.when(command_failed && self.exit_status.is_some(), |this| {
this.tooltip(Tooltip::text(format!(
"Exited with code {}",
self.exit_status
.and_then(|status| status.code())
.unwrap_or(-1),
)))
})
.when(
!command_failed && tool_failed && status.error().is_some(),
|this| {
this.tooltip(Tooltip::text(format!(
"Error: {}",
status.error().unwrap(),
)))
},
),
)
})
.when(self.was_content_truncated, |header| { .when(self.was_content_truncated, |header| {
let tooltip = if self.content_line_count + 10 > terminal::MAX_SCROLL_HISTORY_LINES { let tooltip = if self.content_line_count + 10 > terminal::MAX_SCROLL_HISTORY_LINES {
"Output exceeded terminal max lines and was \ "Output exceeded terminal max lines and was \
@ -555,34 +600,6 @@ impl ToolCard for TerminalToolCard {
.size(LabelSize::Small), .size(LabelSize::Small),
) )
}) })
.when(tool_failed || command_failed, |header| {
header.child(
div()
.id(("terminal-tool-error-code-indicator", self.entity_id))
.child(
Icon::new(IconName::Close)
.size(IconSize::Small)
.color(Color::Error),
)
.when(command_failed && self.exit_status.is_some(), |this| {
this.tooltip(Tooltip::text(format!(
"Exited with code {}",
self.exit_status
.and_then(|status| status.code())
.unwrap_or(-1),
)))
})
.when(
!command_failed && tool_failed && status.error().is_some(),
|this| {
this.tooltip(Tooltip::text(format!(
"Error: {}",
status.error().unwrap(),
)))
},
),
)
})
.when(!self.finished_with_empty_output, |header| { .when(!self.finished_with_empty_output, |header| {
header.child( header.child(
Disclosure::new( Disclosure::new(
@ -634,6 +651,7 @@ impl ToolCard for TerminalToolCard {
div() div()
.pt_2() .pt_2()
.border_t_1() .border_t_1()
.when(tool_failed || command_failed, |card| card.border_dashed())
.border_color(border_color) .border_color(border_color)
.bg(cx.theme().colors().editor_background) .bg(cx.theme().colors().editor_background)
.rounded_b_md() .rounded_b_md()

View file

@ -662,3 +662,19 @@ It is set to `true` by default, but if set to false, the card's height is capped
This setting is currently only available in Preview. This setting is currently only available in Preview.
It should be up in Stable by the next release. It should be up in Stable by the next release.
### Terminal Card
Use the `expand_terminal_card` setting to control whether terminal cards show the command output in the Agent Panel.
It is set to `true` by default, but if set to false, the card will be fully collapsed even while the command is running, requiring a click to be expanded.
```json
{
"agent": {
"expand_terminal_card": "false"
}
}
```
This setting is currently only available in Preview.
It should be up in Stable by the next release.