Yoke

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(),
});
OptionWhat it does
storageA StorageBackend (default: in-memory)
busAn EventBus (default: in-memory pub/sub)
inferenceAn InferenceStack, or add one later with .withInference(stack)
observabilityA list of ObservabilityConnectors for tracing and logs
pluginsA 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 typed ctx.agents.<x> / ctx.tools.<x> properties. If a name widens to string, 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.stopped
  • agent.spawned / agent.message.received / agent.replied / agent.failed
  • actor.started / actor.stopped / actor.failed
  • tool.called / tool.failed
  • event.defined

See events for the full list and payload shapes.

On this page