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

ClauseRequiredDescription
needs { ... }noEffect requirements
timeout:yesMaximum execution time (duration literal)
retry:noNumber 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

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)
}
Edit this page on GitHub