Skip to main content

agent_code_lib/tools/
sleep_tool.rs

1//! Sleep tool: pause execution for a specified duration.
2//!
3//! Useful for polling loops, waiting for external processes,
4//! or rate-limiting operations.
5
6use async_trait::async_trait;
7use serde_json::json;
8use std::time::Duration;
9
10use super::{Tool, ToolContext, ToolResult};
11use crate::error::ToolError;
12
13/// Maximum sleep duration: 5 minutes.
14const MAX_SLEEP_MS: u64 = 300_000;
15
16pub struct SleepTool;
17
18#[async_trait]
19impl Tool for SleepTool {
20    fn name(&self) -> &'static str {
21        "Sleep"
22    }
23
24    fn description(&self) -> &'static str {
25        "Pause execution for a specified number of milliseconds (max 5 minutes)."
26    }
27
28    fn input_schema(&self) -> serde_json::Value {
29        json!({
30            "type": "object",
31            "required": ["duration_ms"],
32            "properties": {
33                "duration_ms": {
34                    "type": "integer",
35                    "description": "Duration to sleep in milliseconds (max 300000)"
36                }
37            }
38        })
39    }
40
41    fn is_read_only(&self) -> bool {
42        true
43    }
44
45    fn is_concurrency_safe(&self) -> bool {
46        true
47    }
48
49    async fn call(
50        &self,
51        input: serde_json::Value,
52        ctx: &ToolContext,
53    ) -> Result<ToolResult, ToolError> {
54        let ms = input
55            .get("duration_ms")
56            .and_then(|v| v.as_u64())
57            .ok_or_else(|| ToolError::InvalidInput("'duration_ms' is required".into()))?;
58
59        let ms = ms.min(MAX_SLEEP_MS);
60
61        tokio::select! {
62            _ = tokio::time::sleep(Duration::from_millis(ms)) => {
63                Ok(ToolResult::success(format!("Slept for {ms}ms")))
64            }
65            _ = ctx.cancel.cancelled() => {
66                Err(ToolError::Cancelled)
67            }
68        }
69    }
70}