Runtime
AgentRuntime is Clanker's execution boundary. stream() is the source of truth; run() consumes that stream and returns the terminal result.
Agent definitions
An agent declares:
- identity and instructions (
text,path, ortemplate); - an optional input and output JSON Schema;
- requirements such as workspace, approval, or capabilities;
- tools, hooks, and a provider binding.
Definitions are validated before provider work begins. Invalid definitions, contexts, inputs, and outputs produce explicit validation events and failed results.
Run lifecycle
Every run has a stable ID and a normalized event stream. The runtime owns:
- instruction and schema resolution;
- input/output validation;
- monotonically sequenced events;
- cooperative cancellation and enforced deadlines;
- approvals and deny-by-default behavior;
- runtime-tool dispatch;
- terminal completion, failure, and cancellation results.
Provider-specific events are mapped into the same lifecycle, while native provider features remain visible through the capability matrix.
Tools and child agents
Runtime tools execute inside Clanker rather than inside a provider adapter. Built-ins include:
call_agent— resolve an agent from the registry and run it through the same primitive, with correlation, depth limits, cycle detection, and inherited context;create_agent_draft— validate and emit a serializable proposal without registering or executing it.
Codex receives declared runtime tools through a per-run loopback MCP bridge. Undeclared tools are not advertised or invocable.
Hooks and steering
Hooks are deterministic in-band lifecycle side effects. They can observe run events, fail according to an explicit policy, and return RunDirectives after a turn. Directives can continue with another prompt or linger while waiting for an operator message delivered through runtime.emit().
Use hooks when the run must wait for the side effect. Use bus rules for durable, cross-run reactions.
Composition
Clanker provides three small composition primitives:
defineChainpasses each step's output into the next step;defineRouterselects one agent for the input;defineTeamcoordinates several agents through a shared team state.
Agents can also call other registered agents directly through call_agent. All four paths retain the normal runtime lifecycle instead of introducing a second execution model.