Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions crates/chat-cli/src/cli/chat/tools/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use crate::cli::{
Agent,
DEFAULT_AGENT_NAME,
};
use crate::database::settings::Setting;
use crate::os::Os;
use crate::theme::StyledText;
use crate::util::env_var::get_all_env_vars;
Expand Down Expand Up @@ -159,8 +160,8 @@ pub async fn launch_agent(os: &Os, agent: &str, agents: &Agents, task: &str) ->
// Show warning for default agent but no approval needed
display_default_agent_warning()?;
} else {
// Show agent info and require approval for specific agents
request_user_approval(agent, agents, task).await?;
// Show agent info and require approval for specific agents (unless auto-approved by settings)
request_user_approval(os, agent, agents, task).await?;
}

spawn_agent_process(os, agent, task).await?;
Expand Down Expand Up @@ -550,14 +551,37 @@ pub async fn validate_agent_availability(_os: &Os, _agent: &str) -> Result<()> {
Ok(())
}

pub async fn request_user_approval(agent: &str, agents: &Agents, task: &str) -> Result<()> {
pub async fn request_user_approval(os: &Os, agent: &str, agents: &Agents, task: &str) -> Result<()> {
// Check global auto-approve setting
if os
.database
.settings
.get_bool(Setting::DelegateAutoApprove)
.unwrap_or(false)
{
return Ok(());
}

// Check per-agent auto-approve list (comma-separated)
if let Some(list) = os.database.settings.get_string(Setting::DelegateAutoApproveAgents) {
let allowed: Vec<&str> = list.split(',').map(|s| s.trim()).filter(|s| !s.is_empty()).collect();
if allowed.contains(&agent) {
return Ok(());
}
}

let config = agents
.agents
.get(agent)
.ok_or(eyre::eyre!("No agent by the name {agent} found"))?
.into();
display_agent_info(agent, task, &config)?;
get_user_confirmation()?;

// Respect user explicit approval; if user declines, abort launch
let approved = get_user_confirmation()?;
if !approved {
return Err(eyre::eyre!("User declined to delegate to agent '{agent}'"));
}

Ok(())
}
Expand Down
9 changes: 9 additions & 0 deletions crates/chat-cli/src/database/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ pub enum Setting {
TangentModeKey,
#[strum(message = "Key binding for delegate command (single character)")]
DelegateModeKey,
#[strum(message = "Auto-approve delegate launches (boolean)")]
DelegateAutoApprove,
#[strum(message = "Comma-separated list of agents to auto-approve (string)")]
DelegateAutoApproveAgents,

#[strum(message = "Auto-enter tangent mode for introspect questions (boolean)")]
IntrospectTangentMode,
Expand Down Expand Up @@ -112,6 +116,8 @@ impl AsRef<str> for Setting {
Self::EnabledTangentMode => "chat.enableTangentMode",
Self::TangentModeKey => "chat.tangentModeKey",
Self::DelegateModeKey => "chat.delegateModeKey",
Self::DelegateAutoApprove => "chat.delegateAutoApprove",
Self::DelegateAutoApproveAgents => "chat.delegateAutoApproveAgents",

Self::IntrospectTangentMode => "introspect.tangentMode",
Self::ChatGreetingEnabled => "chat.greeting.enabled",
Expand Down Expand Up @@ -163,6 +169,9 @@ impl TryFrom<&str> for Setting {
"chat.autocompletionKey" => Ok(Self::AutocompletionKey),
"chat.enableTangentMode" => Ok(Self::EnabledTangentMode),
"chat.tangentModeKey" => Ok(Self::TangentModeKey),
"chat.delegateModeKey" => Ok(Self::DelegateModeKey),
"chat.delegateAutoApprove" => Ok(Self::DelegateAutoApprove),
"chat.delegateAutoApproveAgents" => Ok(Self::DelegateAutoApproveAgents),

"introspect.tangentMode" => Ok(Self::IntrospectTangentMode),
"chat.greeting.enabled" => Ok(Self::ChatGreetingEnabled),
Expand Down
2 changes: 2 additions & 0 deletions docs/experiments.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ Task execution details are stored in `.amazonq/.subagents/` in your current dire

**Settings:**
- `chat.enableDelegate` - Enable/disable delegate feature (boolean)
- `chat.delegateAutoApprove` - Automatically approve delegate launches (boolean, default: false)
- `chat.delegateAutoApproveAgents` - Comma-separated list of agent names to auto-approve (string)

**When enabled:** You can delegate long-running or independent tasks to background agents. You'll be notified when tasks complete, and can ask about results in your main conversation.

Expand Down