Runtime
The long-lived process that hosts everything.
The runtime is the heart of Yoke. It hosts agents, actors, tools, the event
bus, and the store — it is the process that "keeps running." One runtime has one
identity (runtime.id), wires the primitives together, and owns their lifecycle.
Creating a runtime
Runtime(options) is a factory, like express():
import { Runtime, MemoryEventBus, MemoryStorageBackend } from "yoke";
const runtime = Runtime({
storage: new MemoryStorageBackend(),
bus: new MemoryEventBus(),
});| Option | What it does |
|---|---|
storage | A StorageBackend (default: in-memory) |
bus | An EventBus (default: in-memory pub/sub) |
inference | An InferenceStack, or add one later with .withInference(stack) |
observability | A list of ObservabilityConnectors for tracing and logs |
plugins | A list of Plugins that provision or extend the runtime |
The registration surface
Everything an actor can reach must be registered. That registration is also the enforcement boundary:
const runtime = Runtime({ /* ... */ })
.agent(agentDef) // register an agent
.toolchain({ name, tools }) // register a named set of tools
.tool(tool) // register a single tool
.event({ type, schema? }) // define a custom event
.withInference(stack) // attach an inference stack
.actor({ name, topics, filter?, act });.agent(def)/.toolchain(tc)/.tool(t)/.event(def)are chainable..actor(def)registers the only things that initiate work.- Agents and tools must declare literal names (
name: "x" as const) to appear as typedctx.agents.<x>/ctx.tools.<x>properties. If a name widens tostring, the entry degrades to an index signature — still callable, but untyped.
Serving the runtime
await runtime.serve({ port }) starts the runtime (actors begin subscribing)
and serves it over HTTP:
const server = await runtime.serve({ port: 3000 });This is the "message in, agent out" moment: a client publishes an event, an actor forwards it to an agent, and the agent replies.
Express-style
Runtime(options) is the "app", .actor(...) are the routes, and
runtime.serve(...) is the "listen". See server for the full HTTP
API.
Contexts
Actors and agents both receive an injected context:
ctx.agents.<name>(instanceId?).sendMessage(message) // call a registered agent
ctx.tools.<name>(args?) // call a registered tool
ctx.emit({ topic, type, payload }) // publish an event
ctx.runtime // the runtime handle
ctx.inference // chat / generateObject / ...Actors initiate through these; agents use them to compose — agents call
other agents via ctx.agents and via agent-as-tool tools.
Standard events
The runtime emits lifecycle events on its own stream:
runtime.started/runtime.stopping/runtime.stoppedagent.spawned/agent.message.received/agent.replied/agent.failedactor.started/actor.stopped/actor.failedtool.called/tool.failedevent.defined
See events for the full list and payload shapes.