gent/runtime/tools/
web_fetch.rs

1use super::Tool;
2use async_trait::async_trait;
3use serde_json::{json, Value};
4
5pub struct WebFetchTool {
6    client: reqwest::Client,
7}
8
9impl WebFetchTool {
10    pub fn new() -> Self {
11        Self {
12            client: reqwest::Client::new(),
13        }
14    }
15}
16
17impl Default for WebFetchTool {
18    fn default() -> Self {
19        Self::new()
20    }
21}
22
23#[async_trait]
24impl Tool for WebFetchTool {
25    fn name(&self) -> &str {
26        "web_fetch"
27    }
28
29    fn description(&self) -> &str {
30        "Fetch content from a URL. Returns the response body as text."
31    }
32
33    fn parameters_schema(&self) -> Value {
34        json!({
35            "type": "object",
36            "properties": {
37                "url": {
38                    "type": "string",
39                    "description": "The URL to fetch"
40                }
41            },
42            "required": ["url"]
43        })
44    }
45
46    async fn execute(&self, args: Value) -> Result<String, String> {
47        let url = args
48            .get("url")
49            .and_then(|v| v.as_str())
50            .ok_or_else(|| "Missing required parameter: url".to_string())?;
51
52        let response = self
53            .client
54            .get(url)
55            .send()
56            .await
57            .map_err(|e| format!("Request failed: {}", e))?;
58
59        if !response.status().is_success() {
60            return Err(format!("HTTP error: {}", response.status()));
61        }
62
63        response
64            .text()
65            .await
66            .map_err(|e| format!("Failed to read response: {}", e))
67    }
68}