3.3 KiB
Tool Runtime
The tool runtime provides the execution layer that sits on top of the
domain Tool model. It is responsible for registering, discovering,
activating, executing, and deactivating tools at runtime.
Modules
| Module | Purpose |
|---|---|
cleveragents.tool.runtime |
Data models: ToolSpec, ToolResult, ToolError |
cleveragents.tool.registry |
In-memory ToolRegistry with thread-safe operations |
cleveragents.tool.runner |
ToolRunner implementing the four-stage lifecycle |
Tool Lifecycle
Every tool execution follows a strict four-stage lifecycle:
discover -> activate -> execute -> deactivate
1. Discover
ToolRunner.discover(registry?) queries the registry for all available
tools. An alternate registry may be passed for dynamic discovery.
2. Activate
ToolRunner.activate(tool_name) validates that the tool exists and marks
it as ready for execution. Raises ToolError with type
ActivationError if the tool is not found.
3. Execute
ToolRunner.execute(tool_name, inputs) runs the tool handler with the
provided inputs. Key guarantees:
- JSON-serialisable IO: Both inputs and outputs are validated to be
JSON-serialisable. Non-serialisable data causes a
ToolResultwithsuccess=False. - Error normalisation: Any exception raised by the handler is caught
and returned as a
ToolResult(success=False, error=...). The caller never sees raw exceptions from tool handlers. - Duration tracking: Wall-clock execution time is recorded in
ToolResult.duration_ms.
4. Deactivate
ToolRunner.deactivate(tool_name) cleans up after execution. Returns
True if the tool was active, False otherwise.
Capability Flags
ToolSpec.capabilities carries a ToolCapability instance (from the
domain model) with the following flags:
| Flag | Description |
|---|---|
read_only |
Tool only reads; never writes |
writes |
Tool can write to resources |
checkpointable |
Tool supports checkpoint/rollback |
idempotent |
Safe to re-run without side effects |
unsafe |
Requires extra safety checks |
human_approval_required |
Needs explicit human approval |
A read_only tool cannot have writes=True or checkpointable=True.
Error Semantics
ToolResult
| Field | Type | Description |
|---|---|---|
success |
bool |
Whether execution succeeded |
output |
dict |
JSON-serialisable output payload |
error |
str | None |
Error message on failure |
duration_ms |
float |
Execution wall-clock time (ms) |
metadata |
dict |
Arbitrary execution metadata |
ToolError
ToolError is an exception class for structured tool failures:
| Attribute | Type | Description |
|---|---|---|
tool_name |
str |
Namespaced tool name |
error_type |
str |
Category (e.g. RegistrationError) |
details |
str |
Human-readable explanation |
Registry
ToolRegistry is an in-memory, thread-safe registry:
register(spec)-- adds a tool; raisesToolErroron name collision.get(name)-- lookup by namespaced name; returnsNoneif not found.list_tools(namespace?, tool_type?)-- list with optional filters.remove(name)-- unregister; returnsbool.
All mutating operations are protected by threading.RLock.