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