Skip to content

Commit 56384af

Browse files
committed
feat: Add configurable auto-approve for delegate tool to support non-interactive sessions
- Add chat.delegateAutoApprove setting for global auto-approval - Add chat.delegateAutoApproveAgents setting for per-agent auto-approval - Update delegate approval flow to consult settings before prompting - Fix bug where user declining approval was silently ignored - Document new settings in experiments.md Fixes request for non-interactive delegate support in automation workflows.
1 parent a0eb7b2 commit 56384af

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

crates/chat-cli/src/cli/chat/tools/delegate.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::cli::{
3636
Agent,
3737
DEFAULT_AGENT_NAME,
3838
};
39+
use crate::database::settings::Setting;
3940
use crate::os::Os;
4041
use crate::theme::StyledText;
4142
use crate::util::env_var::get_all_env_vars;
@@ -159,8 +160,8 @@ pub async fn launch_agent(os: &Os, agent: &str, agents: &Agents, task: &str) ->
159160
// Show warning for default agent but no approval needed
160161
display_default_agent_warning()?;
161162
} else {
162-
// Show agent info and require approval for specific agents
163-
request_user_approval(agent, agents, task).await?;
163+
// Show agent info and require approval for specific agents (unless auto-approved by settings)
164+
request_user_approval(os, agent, agents, task).await?;
164165
}
165166

166167
spawn_agent_process(os, agent, task).await?;
@@ -550,14 +551,32 @@ pub async fn validate_agent_availability(_os: &Os, _agent: &str) -> Result<()> {
550551
Ok(())
551552
}
552553

553-
pub async fn request_user_approval(agent: &str, agents: &Agents, task: &str) -> Result<()> {
554+
pub async fn request_user_approval(os: &Os, agent: &str, agents: &Agents, task: &str) -> Result<()> {
555+
// Check global auto-approve setting
556+
if os.database.settings.get_bool(Setting::DelegateAutoApprove).unwrap_or(false) {
557+
return Ok(());
558+
}
559+
560+
// Check per-agent auto-approve list (comma-separated)
561+
if let Some(list) = os.database.settings.get_string(Setting::DelegateAutoApproveAgents) {
562+
let allowed: Vec<&str> = list.split(',').map(|s| s.trim()).filter(|s| !s.is_empty()).collect();
563+
if allowed.iter().any(|&a| a == agent) {
564+
return Ok(());
565+
}
566+
}
567+
554568
let config = agents
555569
.agents
556570
.get(agent)
557571
.ok_or(eyre::eyre!("No agent by the name {agent} found"))?
558572
.into();
559573
display_agent_info(agent, task, &config)?;
560-
get_user_confirmation()?;
574+
575+
// Respect user explicit approval; if user declines, abort launch
576+
let approved = get_user_confirmation()?;
577+
if !approved {
578+
return Err(eyre::eyre!("User declined to delegate to agent '{agent}'"));
579+
}
561580

562581
Ok(())
563582
}

crates/chat-cli/src/database/settings.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ pub enum Setting {
5050
TangentModeKey,
5151
#[strum(message = "Key binding for delegate command (single character)")]
5252
DelegateModeKey,
53+
#[strum(message = "Auto-approve delegate launches (boolean)")]
54+
DelegateAutoApprove,
55+
#[strum(message = "Comma-separated list of agents to auto-approve (string)")]
56+
DelegateAutoApproveAgents,
5357

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

116122
Self::IntrospectTangentMode => "introspect.tangentMode",
117123
Self::ChatGreetingEnabled => "chat.greeting.enabled",
@@ -163,6 +169,9 @@ impl TryFrom<&str> for Setting {
163169
"chat.autocompletionKey" => Ok(Self::AutocompletionKey),
164170
"chat.enableTangentMode" => Ok(Self::EnabledTangentMode),
165171
"chat.tangentModeKey" => Ok(Self::TangentModeKey),
172+
"chat.delegateModeKey" => Ok(Self::DelegateModeKey),
173+
"chat.delegateAutoApprove" => Ok(Self::DelegateAutoApprove),
174+
"chat.delegateAutoApproveAgents" => Ok(Self::DelegateAutoApproveAgents),
166175

167176
"introspect.tangentMode" => Ok(Self::IntrospectTangentMode),
168177
"chat.greeting.enabled" => Ok(Self::ChatGreetingEnabled),

docs/experiments.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ Task execution details are stored in `.amazonq/.subagents/` in your current dire
151151

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

155157
**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.
156158

0 commit comments

Comments
 (0)