langchain_rust/tools/
tool.rs

1use std::error::Error;
2use std::string::String;
3
4use async_trait::async_trait;
5use serde_json::{json, Value};
6
7#[async_trait]
8pub trait Tool: Send + Sync {
9    /// Returns the name of the tool.
10    fn name(&self) -> String;
11
12    /// Provides a description of what the tool does and when to use it.
13    fn description(&self) -> String;
14    /// This are the parametters for OpenAi-like function call.
15    /// You should return a jsnon like this one
16    /// ```json
17    /// {
18    ///     "type": "object",
19    ///     "properties": {
20    ///         "command": {
21    ///             "type": "string",
22    ///             "description": "The raw command you want executed"
23    ///                 }
24    ///     },
25    ///     "required": ["command"]
26    /// }
27    ///
28    /// If there s no implementation the defaul will be the self.description()
29    ///```
30    fn parameters(&self) -> Value {
31        json!({
32            "type": "object",
33                "properties": {
34                "input": {
35                    "type": "string",
36                    "description":self.description()
37                }
38            },
39            "required": ["input"]
40        })
41    }
42
43    /// Processes an input string and executes the tool's functionality, returning a `Result`.
44    ///
45    /// This function utilizes `parse_input` to parse the input and then calls `run`.
46    /// Its used by the Agent
47    async fn call(&self, input: &str) -> Result<String, Box<dyn Error>> {
48        let input = self.parse_input(input).await;
49        self.run(input).await
50    }
51
52    /// Executes the core functionality of the tool.
53    ///
54    /// Example implementation:
55    /// ```rust,ignore
56    /// async fn run(&self, input: Value) -> Result<String, Box<dyn Error>> {
57    ///     let input_str = input.as_str().ok_or("Input should be a string")?;
58    ///     self.simple_search(input_str).await
59    /// }
60    /// ```
61    async fn run(&self, input: Value) -> Result<String, Box<dyn Error>>;
62
63    /// Parses the input string, which could be a JSON value or a raw string, depending on the LLM model.
64    ///
65    /// Implement this function to extract the parameters needed for your tool. If a simple
66    /// string is sufficient, the default implementation can be used.
67    async fn parse_input(&self, input: &str) -> Value {
68        log::info!("Using default implementation: {}", input);
69        match serde_json::from_str::<Value>(input) {
70            Ok(input) => {
71                if input["input"].is_string() {
72                    Value::String(input["input"].as_str().unwrap().to_string())
73                } else {
74                    Value::String(input.to_string())
75                }
76            }
77            Err(_) => Value::String(input.to_string()),
78        }
79    }
80}