llm_chain_tools/tools/
bash.rs1use crate::description::{Describe, Format, ToolDescription};
2use crate::tool::{gen_invoke_function, Tool};
3use serde::{Deserialize, Serialize};
4use std::process::Command;
5
6pub struct BashTool {}
8
9impl BashTool {
10 pub fn new() -> Self {
11 BashTool {}
12 }
13}
14
15impl Default for BashTool {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21#[derive(Serialize, Deserialize)]
22pub struct BashToolInput {
23 cmd: String,
24}
25
26#[derive(Serialize, Deserialize)]
27pub struct BashToolOutput {
28 stderr: String,
29 stdout: String,
30 status: isize,
31}
32
33impl Describe for BashToolInput {
34 fn describe() -> Format {
35 vec![("cmd", "The command to execute in the bash shell.").into()].into()
36 }
37}
38
39impl Describe for BashToolOutput {
40 fn describe() -> Format {
41 vec![
42 ("result", "Exit code 0 == success").into(),
43 ("stderr", "The stderr output of the command").into(),
44 ("stdout", "The stdout output of the command").into(),
45 ]
46 .into()
47 }
48}
49
50impl BashTool {
51 fn invoke_typed(&self, input: &BashToolInput) -> Result<BashToolOutput, String> {
52 let output = Command::new("bash")
53 .arg("-c")
54 .arg(&input.cmd)
55 .output()
56 .map_err(|_e| "failed to execute process")?;
57 Ok(BashToolOutput {
58 status: output.status.code().unwrap() as isize,
59 stderr: String::from_utf8(output.stderr).unwrap(),
60 stdout: String::from_utf8(output.stdout).unwrap(),
61 })
62 }
63}
64
65impl Tool for BashTool {
66 gen_invoke_function!();
67 fn description(&self) -> ToolDescription {
68 ToolDescription::new(
69 "BashTool",
70 "A tool that executes a bash command.",
71 "Use this to execute local commands to solve your goals",
72 BashToolInput::describe(),
73 BashToolOutput::describe(),
74 )
75 }
76}