Yoke

Plugins

Provide middleware, providers, models, storage, tools, and more.

A plugin can provide anything: middleware at multiple levels, providers, models, storage, tools, toolchains, agents, actors, and event definitions.

const runtime = Runtime({
  plugins: [myPlugin],
});

Middleware

Middleware hooks are (input, next) => Promise<unknown> chains — skip next() to short-circuit. There are four levels:

const tracingPlugin = {
  name: "tracing",
  setup(api) {
    api.middleware.toolCall(async (input, next) => {
      console.time(`tool:${input.tool.name}`);
      try {
        return await next();
      } finally {
        console.timeEnd(`tool:${input.tool.name}`);
      }
    });

    api.middleware.agentTurn(async (input, next) => {
      const start = Date.now();
      const result = await next();
      console.log(`agent turn took ${Date.now() - start}ms`);
      return result;
    });

    api.middleware.emit(async (input, next) => {
      // inspect / annotate events before they're published
      return next();
    });

    api.middleware.inference(async (input, next) => {
      // wrap every inference call
      return next();
    });
  },
};

The four hooks wrap:

HookWraps
toolCalltool calls (runtime level)
agentTurnagent turns
emitevent emission
inferenceinference calls

Provisioning

Plugins provision resources through the API:

const plugin = {
  name: "db",
  setup(api) {
    api.storage(new SqliteStorageBackend("yoke.db"));
    api.providers([openaiProvider({ apiKey: process.env.OPENAI_API_KEY })]);
    api.models([{ id: "gpt-4o", provider: "openai", model: "gpt-4o" }]);
    api.tool(myTool);
    api.toolchain(myToolchain);
    api.agent(myAgent);
    api.actor(myActor);
    api.event({ type: "custom.event", schema: z.object({ ... }) });
  },
};

Providers and models from plugins merge into the runtime's inference stack.

Order

Runtime({ plugins: [...] }) runs setups in order. Later plugins see the resources provisioned by earlier ones.

On this page