Skip to content

Commit 91778c6

Browse files
authored
Minor agentic tool type changes (#636)
* fix things * make small changes to tool type
1 parent a18f479 commit 91778c6

File tree

6 files changed

+46
-57
lines changed

6 files changed

+46
-57
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ Hi, I'm <g>Amazon Q</g>. I can answer questions about your workspace and tooling
433433
if let Some(ref id) = self.current_user_input_id {
434434
event_builder.user_input_id = Some(id.clone());
435435
}
436-
match Tool::from_tool_use(tool_use) {
436+
match Tool::try_from(tool_use) {
437437
Ok(mut tool) => {
438438
match tool.validate(&self.ctx).await {
439439
Ok(()) => {
@@ -486,7 +486,7 @@ Hi, I'm <g>Amazon Q</g>. I can answer questions about your workspace and tooling
486486
queue!(self.output, style::Print(format!(" {} ", tool.display_name())))?;
487487
queue!(self.output, cursor::MoveToNextLine(1))?;
488488
queue!(self.output, style::SetAttribute(Attribute::NormalIntensity))?;
489-
tool.show_readable_intention(self.output)?;
489+
tool.queue_description(self.output)?;
490490
queue!(self.output, style::Print("\n"))?;
491491
queue!(self.output, cursor::MoveToNextLine(1))?;
492492
}

crates/q_cli/src/cli/chat/tools/execute_bash.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ pub struct ExecuteBash {
2525
}
2626

2727
impl ExecuteBash {
28-
pub fn display_name() -> String {
29-
"Execute Bash".to_owned()
30-
}
31-
3228
pub async fn invoke(&self, mut updates: impl Write) -> Result<InvokeOutput> {
3329
queue!(
3430
updates,
@@ -60,17 +56,18 @@ impl ExecuteBash {
6056
})
6157
}
6258

63-
pub fn show_readable_intention(&self, updates: &mut impl Write) -> Result<()> {
59+
pub fn queue_description(&self, updates: &mut impl Write) -> Result<()> {
6460
Ok(queue!(
6561
updates,
66-
style::Print("Command: "),
62+
style::Print("I will run the following command using your bash environment:\n"),
6763
style::SetForegroundColor(Color::Green),
6864
style::Print(&self.command),
6965
style::ResetColor,
7066
)?)
7167
}
7268

7369
pub async fn validate(&mut self, _ctx: &Context) -> Result<()> {
70+
// TODO: probably some small amount of PATH checking
7471
Ok(())
7572
}
7673
}

crates/q_cli/src/cli/chat/tools/fs_read.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ impl FsRead {
4343
}
4444
}
4545

46-
pub fn display_name() -> String {
47-
"File System Read".to_owned()
48-
}
49-
5046
pub async fn invoke(&self, ctx: &Context, updates: &mut impl Write) -> Result<InvokeOutput> {
5147
// Required for testing scenarios: since the path is passed directly as a command argument,
5248
// we need to pass it through the Context first.
@@ -164,7 +160,7 @@ impl FsRead {
164160
}
165161
}
166162

167-
pub fn show_readable_intention(&self, updates: &mut impl Write) -> Result<()> {
163+
pub fn queue_description(&self, updates: &mut impl Write) -> Result<()> {
168164
let is_file = self.ty.expect("Tool needs to have been validated");
169165

170166
if is_file {

crates/q_cli/src/cli/chat/tools/fs_write.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ pub enum FsWrite {
3939
}
4040

4141
impl FsWrite {
42-
pub fn display_name() -> String {
43-
"File System Write".to_owned()
44-
}
45-
4642
pub async fn invoke(&self, ctx: &Context, updates: &mut impl Write) -> Result<InvokeOutput> {
4743
let fs = ctx.fs();
4844
let cwd = ctx.env().current_dir()?;
@@ -114,7 +110,7 @@ impl FsWrite {
114110
}
115111
}
116112

117-
pub fn show_readable_intention(&self, updates: &mut impl Write) -> Result<()> {
113+
pub fn queue_description(&self, updates: &mut impl Write) -> Result<()> {
118114
match self {
119115
FsWrite::Create { path, file_text } => Ok(queue!(
120116
updates,

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

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,39 +35,13 @@ pub enum Tool {
3535
}
3636

3737
impl Tool {
38-
pub fn from_tool_use(tool_use: ToolUse) -> Result<Self, ToolResult> {
39-
let map_err = |parse_error| ToolResult {
40-
tool_use_id: tool_use.id.clone(),
41-
content: vec![ToolResultContentBlock::Text(format!(
42-
"failed to deserialize with the following error: {parse_error}"
43-
))],
44-
status: ToolResultStatus::Error,
45-
};
46-
47-
Ok(match tool_use.name.as_str() {
48-
"fs_read" => Self::FsRead(serde_json::from_value::<FsRead>(tool_use.args).map_err(map_err)?),
49-
"fs_write" => Self::FsWrite(serde_json::from_value::<FsWrite>(tool_use.args).map_err(map_err)?),
50-
"execute_bash" => Self::ExecuteBash(serde_json::from_value::<ExecuteBash>(tool_use.args).map_err(map_err)?),
51-
"use_aws" => Self::UseAws(serde_json::from_value::<UseAws>(tool_use.args).map_err(map_err)?),
52-
unknown => {
53-
return Err(ToolResult {
54-
tool_use_id: tool_use.id,
55-
content: vec![ToolResultContentBlock::Text(format!(
56-
"The tool, \"{unknown}\" is not supported by the client"
57-
))],
58-
status: ToolResultStatus::Error,
59-
});
60-
},
61-
})
62-
}
63-
6438
/// The display name of a tool
65-
pub fn display_name(&self) -> String {
39+
pub fn display_name(&self) -> &'static str {
6640
match self {
67-
Tool::FsRead(_) => FsRead::display_name(),
68-
Tool::FsWrite(_) => FsWrite::display_name(),
69-
Tool::ExecuteBash(_) => ExecuteBash::display_name(),
70-
Tool::UseAws(_) => UseAws::display_name(),
41+
Tool::FsRead(_) => "Read from filesystem",
42+
Tool::FsWrite(_) => "Write to filesystem",
43+
Tool::ExecuteBash(_) => "Execute shell command",
44+
Tool::UseAws(_) => "Read AWS resources",
7145
}
7246
}
7347

@@ -82,11 +56,11 @@ impl Tool {
8256
}
8357

8458
/// Queues up a tool's intention in a human readable format
85-
pub fn show_readable_intention(&self, updates: &mut impl Write) -> Result<()> {
59+
pub fn queue_description(&self, updates: &mut impl Write) -> Result<()> {
8660
match self {
87-
Tool::FsRead(fs_read) => fs_read.show_readable_intention(updates),
88-
Tool::FsWrite(fs_write) => fs_write.show_readable_intention(updates),
89-
Tool::ExecuteBash(execute_bash) => execute_bash.show_readable_intention(updates),
61+
Tool::FsRead(fs_read) => fs_read.queue_description(updates),
62+
Tool::FsWrite(fs_write) => fs_write.queue_description(updates),
63+
Tool::ExecuteBash(execute_bash) => execute_bash.queue_description(updates),
9064
Tool::UseAws(use_aws) => use_aws.show_readable_intention(updates),
9165
}
9266
}
@@ -102,6 +76,36 @@ impl Tool {
10276
}
10377
}
10478

79+
impl TryFrom<ToolUse> for Tool {
80+
type Error = ToolResult;
81+
82+
fn try_from(value: ToolUse) -> std::result::Result<Self, Self::Error> {
83+
let map_err = |parse_error| ToolResult {
84+
tool_use_id: value.id.clone(),
85+
content: vec![ToolResultContentBlock::Text(format!(
86+
"failed to deserialize with the following error: {parse_error}"
87+
))],
88+
status: ToolResultStatus::Error,
89+
};
90+
91+
Ok(match value.name.as_str() {
92+
"fs_read" => Self::FsRead(serde_json::from_value::<FsRead>(value.args).map_err(map_err)?),
93+
"fs_write" => Self::FsWrite(serde_json::from_value::<FsWrite>(value.args).map_err(map_err)?),
94+
"execute_bash" => Self::ExecuteBash(serde_json::from_value::<ExecuteBash>(value.args).map_err(map_err)?),
95+
"use_aws" => Self::UseAws(serde_json::from_value::<UseAws>(value.args).map_err(map_err)?),
96+
unknown => {
97+
return Err(ToolResult {
98+
tool_use_id: value.id,
99+
content: vec![ToolResultContentBlock::Text(format!(
100+
"The tool, \"{unknown}\" is not supported by the client"
101+
))],
102+
status: ToolResultStatus::Error,
103+
});
104+
},
105+
})
106+
}
107+
}
108+
105109
/// A tool specification to be sent to the model as part of a conversation. Maps to
106110
/// [BedrockToolSpecification].
107111
#[derive(Debug, Clone, Deserialize)]

crates/q_cli/src/cli/chat/tools/use_aws.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ impl UseAws {
5757
Err(AwsToolError::ForbiddenOperation(operation_name.clone()))
5858
}
5959

60-
pub fn display_name() -> String {
61-
"Use AWS Readonly".to_owned()
62-
}
63-
6460
pub async fn invoke(&self, _ctx: &Context, _updates: impl Write) -> Result<InvokeOutput> {
6561
let mut command = tokio::process::Command::new("aws");
6662
command.envs(std::env::vars()).arg("--region").arg(&self.region);

0 commit comments

Comments
 (0)