Add docs/api/ with per-module API documentation for core, a2a, actor, skills, tool, mcp, resource, and config packages. Add docs/architecture.md with a developer-oriented system overview including component map, layer diagram, plan lifecycle, and key design decisions. Update mkdocs.yml nav to expose both new sections. ISSUES CLOSED: #N/A
5.9 KiB
cleveragents.tool — Tool System
The tool package provides the four-stage tool lifecycle (activate →
validate → execute → deactivate), the tool registry, call router,
container executor, and the tool-calling actor runtime.
See ADR-011 and ADR-037 for design rationale.
Core Types
ToolSpec
class ToolSpec(BaseModel):
name: str
description: str
input_schema: dict[str, Any] # JSON Schema
output_schema: dict[str, Any] | None = None
read_only: bool = False
checkpointable: bool = True
source: str = "builtin" # "builtin" | "mcp" | "lsp" | "skill"
Declarative specification for a tool. Used for registration and schema validation.
ToolResult
class ToolResult(BaseModel):
success: bool
output: Any
error: ToolError | None = None
trace: ToolExecutionTrace | None = None
ToolError
class ToolError(BaseModel):
code: str
message: str
details: dict[str, Any] = {}
Registry
ToolRegistry
from cleveragents.tool import ToolRegistry
registry = ToolRegistry()
registry.register(tool_spec, executor_fn)
spec = registry.get("bash")
Central registry for all tools. Supports namespace-qualified names and
source tagging (builtin, mcp, lsp, skill).
Lifecycle
ToolRuntime
Manages the four-stage lifecycle for a single tool invocation:
- Activate — acquire resources, check permissions, apply safety profile
- Validate — JSON Schema validation of inputs
- Execute — call the tool executor
- Deactivate — release resources, record trace
ToolLifecycleCache
Per-plan cache of activated tool instances to avoid redundant activation overhead.
ToolDescriptor
Rich descriptor combining ToolSpec with runtime metadata (activation
state, cost estimate, sandbox requirements).
ToolInstance
A single activated instance of a tool, bound to a specific plan and execution context.
Lifecycle Errors
| Exception | Description |
|---|---|
ToolActivationError |
Tool failed to activate |
ToolDeactivationError |
Tool failed to deactivate cleanly |
ToolNotActivatedError |
Tool called before activation |
ToolExecutionError |
Tool execution failed |
ToolRuntimeError |
Internal runtime error |
ToolAccessDeniedError |
Permission check failed |
ToolSafetyViolationError |
Safety profile violation |
ToolSandboxRequiredError |
Tool requires sandbox but none available |
ToolCheckpointRequiredError |
Checkpoint required before execution |
ToolHumanApprovalRequiredError |
Human approval gate triggered |
ToolCostLimitExceededError |
Budget limit exceeded |
ToolRetryLimitExceededError |
Max retries exhausted |
ToolCancelledError |
Tool cancelled via CancellationToken |
Execution Context
ToolExecutionContext
class ToolExecutionContext:
plan_id: str
session_id: str
actor_name: str
bound_resources: list[BoundResource]
cancellation_token: CancellationToken
read_only: bool
CancellationToken
token = CancellationToken()
token.cancel() # signal cancellation
token.is_cancelled # check state
ToolExecutionTrace
Immutable record of a tool execution: inputs, outputs, duration, sandbox used, cost incurred.
Router
ToolCallRouter
Translates between provider-specific tool call formats (OpenAI, Anthropic,
Google) and the internal ToolCallRequest format.
from cleveragents.tool import ToolCallRouter, detect_provider_format
router = ToolCallRouter(registry)
format = detect_provider_format(raw_response)
request = normalize_tool_call(raw_call, format)
result = await router.route(request, context)
ProviderFormat
Enum: OPENAI, ANTHROPIC, GOOGLE, UNKNOWN.
Helper Functions
| Function | Description |
|---|---|
detect_provider_format(response) |
Detect provider from response shape |
normalize_tool_call(call, fmt) |
Normalize to ToolCallRequest |
normalize_tool_schema_for_provider(spec, fmt) |
Adapt schema for provider |
generate_tool_call_id() |
Generate a unique call ID |
classify_tool_error(exc) |
Map exception to ToolCallErrorCategory |
Container Executor
ContainerToolExecutor
Executes tools inside an isolated container (Docker/Podman).
from cleveragents.tool import ContainerToolExecutor, ContainerConfig
config = ContainerConfig(image="python:3.12-slim", timeout=30)
executor = ContainerToolExecutor(config)
result = await executor.execute("bash", {"command": "echo hello"})
ContainerConfig
| Field | Type | Description |
|---|---|---|
image |
str |
Container image |
timeout |
int |
Execution timeout in seconds |
memory_limit |
str | None |
Memory limit (e.g. "512m") |
network |
str |
Network mode ("none", "bridge") |
Schema Validation
validate_tool_input(spec, inputs) → None
Validates inputs against spec.input_schema. Raises
ToolSchemaValidationError on failure.
validate_tool_output(spec, output) → None
Validates tool output against spec.output_schema (if defined).
Tool-Calling Actor Runtime
ToolCallingRuntime
Drives the LLM ↔ tool call loop for execution actors.
from cleveragents.tool import ToolCallingRuntime
runtime = ToolCallingRuntime(llm_caller, tool_registry)
result: ToolCallRunResult = await runtime.run(messages, context)
LLMCaller
Protocol for calling an LLM. Implement this to plug in a custom provider.
MaxIterationsExceededError
Raised when the tool-call loop exceeds the configured maximum iterations.
Path Mapper
PathMapper
Maps host paths to container/sandbox paths and back. Used by the sandbox and MCP adapter for path rewriting.