Tools
A tool is a typed callable with timeout, retry, and effect tracking. Tools are the building blocks that agents use to interact with the outside world.
Declaration
cleat
tool fetch_data(url: string) -> Result[string, string] needs { net } timeout: 10s retry: 2 { let resp: http.Response = http.get(url)? return Ok(resp.body) }
Clauses
| Clause | Required | Description |
|---|---|---|
needs { ... } | no | Effect requirements |
timeout: | yes | Maximum execution time (duration literal) |
retry: | no | Number of retries on failure (default: 0) |
Return type
Tools always return Result[T, E]. This is enforced by the compiler.
Effect enforcement
Callers must declare the tool's effects:
cleat
fn use_tool() -> Result[string, string] needs { net } { return fetch_data("https://api.example.com") // ok: net declared } fn pure_fn() -> Result[string, string] { // fetch_data(...) ← compile error: missing needs effect: net return Ok("") }
Agent integration
When listed in an agent's tool: clause, the agent can call the tool during its LLM loop:
cleat
agent Researcher { model: "claude-sonnet-4-20250514" system: "Use fetch_data to find information." tool: [fetch_data] // agent can call fetch_data needs { llm, net } // must cover fetch_data's needs { net } }
The compiler verifies that the agent's needs covers all its tools' effects.
Testing tools
Use using to mock tools in test blocks:
cleat
test "mock the tool" { using fetch_data = fn(url: string) -> Result[string, string] { return Ok("mock response for ${url}") } let r = fetch_data("any-url") assert(r.IsOk()) }
Timeout and retry
- Timeout: the tool is killed after the specified duration. Returns an error.
- Retry: on failure, the tool body is re-executed up to N times. The last result is returned.
cleat
tool flaky_api(endpoint: string) -> Result[string, string] needs { net } timeout: 5s retry: 3 { let resp: http.Response = http.get(endpoint)? return Ok(resp.body) }