Skip to content

Commit 91b976c

Browse files
committed
fix requires_acceptance for subcommands
1 parent e5e1ee5 commit 91b976c

File tree

4 files changed

+58
-53
lines changed

4 files changed

+58
-53
lines changed

crates/chat-cli/src/cli/chat/command.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,20 @@ impl Command {
10901090
}
10911091
}
10921092

1093-
/// Parse a command from components (for use by internal_command tool)
1093+
/// Parse a command from components
1094+
///
1095+
/// This method formats a command string from its components and parses it into a Command enum.
1096+
///
1097+
/// # Arguments
1098+
///
1099+
/// * `command` - The base command name
1100+
/// * `subcommand` - Optional subcommand
1101+
/// * `args` - Optional arguments
1102+
/// * `flags` - Optional flags
1103+
///
1104+
/// # Returns
1105+
///
1106+
/// * `Result<Self>` - The parsed Command enum
10941107
pub fn parse_from_components(
10951108
command: &str,
10961109
subcommand: Option<&String>,

crates/chat-cli/src/cli/chat/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,8 +1339,8 @@ impl ChatContext {
13391339
if let Some(index) = pending_tool_index {
13401340
let tool_use = &mut tool_uses[index];
13411341

1342-
let is_trust = ["t", "T"].contains(&prompt.as_str());
1343-
if ["y", "Y"].contains(&prompt.as_str()) || is_trust {
1342+
let is_trust = ["t", "T"].contains(&prompt);
1343+
if ["y", "Y"].contains(&prompt) || is_trust {
13441344
if is_trust {
13451345
self.tool_permissions.trust_tool(&tool_use.name);
13461346
}

crates/chat-cli/src/cli/chat/tools/internal_command/tool.rs

Lines changed: 39 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -19,46 +19,38 @@ use crate::platform::Context;
1919

2020
impl InternalCommand {
2121
/// Validate that the command exists
22-
pub fn validate(&self) -> Result<()> {
23-
// Format a command string
24-
let cmd_str = if !self.command.starts_with('/') {
25-
format!("/{}", self.command)
26-
} else {
27-
self.command.clone()
28-
};
29-
30-
// Try to parse the command using the Command::parse method
31-
match Command::parse(&cmd_str) {
22+
pub async fn validate(&self) -> Result<()> {
23+
// Parse the command using the existing parse_from_components method
24+
match Command::parse_from_components(
25+
&self.command,
26+
self.subcommand.as_ref(),
27+
self.args.as_ref(),
28+
self.flags.as_ref(),
29+
) {
3230
Ok(_) => Ok(()),
3331
Err(e) => Err(eyre::eyre!("Unknown command: {} - {}", self.command, e)),
3432
}
3533
}
3634

3735
/// Check if the command requires user acceptance
3836
pub fn requires_acceptance(&self) -> bool {
39-
// Format a command string
40-
let cmd_str = if !self.command.starts_with('/') {
41-
format!("/{}", self.command)
42-
} else {
43-
self.command.clone()
44-
};
45-
46-
// Try to parse the command
47-
if let Ok(command) = Command::parse(&cmd_str) {
48-
// Get the handler for this command using to_handler()
49-
let handler = command.to_handler();
50-
51-
// Convert args to string slices for the handler
52-
let args: Vec<&str> = match &self.subcommand {
53-
Some(subcommand) => vec![subcommand.as_str()],
54-
None => vec![],
55-
};
37+
// Parse the command using the existing parse_from_components method
38+
match Command::parse_from_components(
39+
&self.command,
40+
self.subcommand.as_ref(),
41+
self.args.as_ref(),
42+
self.flags.as_ref(),
43+
) {
44+
Ok(command) => {
45+
// Get the handler directly from the command
46+
// This will automatically use the subcommand's handler when appropriate
47+
let handler = command.to_handler();
5648

57-
return handler.requires_confirmation(&args);
49+
// Pass empty args since the handler already knows what command it's for
50+
handler.requires_confirmation(&[])
51+
},
52+
Err(_) => true, // Default to requiring confirmation for unparsable commands
5853
}
59-
60-
// For commands not recognized, default to requiring confirmation
61-
true
6254
}
6355

6456
/// Format the command string with subcommand and arguments
@@ -98,22 +90,23 @@ impl InternalCommand {
9890

9991
/// Get a description for the command
10092
pub fn get_command_description(&self) -> String {
101-
// Format a simple command string
102-
let cmd_str = if !self.command.starts_with('/') {
103-
format!("/{}", self.command)
104-
} else {
105-
self.command.clone()
106-
};
107-
108-
// Try to parse the command
109-
if let Ok(command) = Command::parse(&cmd_str) {
110-
// Get the handler for this command using to_handler()
111-
let handler = command.to_handler();
112-
return handler.description().to_string();
93+
// Parse the command using the existing parse_from_components method
94+
match Command::parse_from_components(
95+
&self.command,
96+
self.subcommand.as_ref(),
97+
self.args.as_ref(),
98+
self.flags.as_ref(),
99+
) {
100+
Ok(command) => {
101+
// Get the handler for this command using to_handler()
102+
let handler = command.to_handler();
103+
handler.description().to_string()
104+
},
105+
Err(_) => {
106+
// For commands not recognized, return a generic description
107+
"Execute a command in the Q chat system".to_string()
108+
},
113109
}
114-
115-
// For commands not recognized, return a generic description
116-
"Execute a command in the Q chat system".to_string()
117110
}
118111

119112
/// Queue description for the command execution

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,7 @@ impl Tool {
136136
Tool::UseAws(use_aws) => use_aws.validate(ctx).await,
137137
Tool::Custom(custom_tool) => custom_tool.validate(ctx).await,
138138
Tool::GhIssue(gh_issue) => gh_issue.validate(ctx).await,
139-
Tool::InternalCommand(internal_command) => internal_command
140-
.validate()
141-
.map_err(|e| eyre::eyre!("Tool validation failed: {:?}", e)),
139+
Tool::InternalCommand(internal_command) => internal_command.validate().await,
142140
Tool::Thinking(think) => think.validate(ctx).await,
143141
}
144142
}
@@ -165,6 +163,7 @@ impl TryFrom<AssistantToolUse> for Tool {
165163
"internal_command" => {
166164
Self::InternalCommand(serde_json::from_value::<InternalCommand>(value.args).map_err(map_err)?)
167165
},
166+
"thinking" => Self::Thinking(serde_json::from_value::<Thinking>(value.args).map_err(map_err)?),
168167
unknown => {
169168
return Err(ToolUseResult {
170169
tool_use_id: value.id,
@@ -344,7 +343,7 @@ impl std::fmt::Display for OutputKind {
344343
match self {
345344
Self::Text(text) => write!(f, "{}", text),
346345
Self::Json(json) => write!(f, "{}", json),
347-
Self::Images(_) => todo!(),
346+
Self::Images(_) => write!(f, ""),
348347
}
349348
}
350349
}

0 commit comments

Comments
 (0)