BlaiseBlaise
Documentation
Runner and PlugsReference

Plug API

definePlug, the handlers and the context of a plug.

Import from @blaiseagent/runner. A plug module default-exports the result of definePlug.

import { z } from "zod";
import { definePlug } from "@blaiseagent/runner";

export default definePlug({
  name: "acme/greeter",
  inputs: z.object({ who: z.string() }),
  onSession: async (ctx, next) => {
    ctx.log.info(`hello ${ctx.inputs.who}`);
    await next();
  },
});

definePlug(definition)

Returns the definition stamped with the plug API version (PLUG_API_VERSION), and infers the types of ctx.inputs, ctx.state and ctx.persisted.

FieldDescription
nameShown in logs and errors, and stored with persisted state. Required.
descriptionOptional.
inputsA Standard Schema (Zod 4, Valibot, ArkType) for with:.
persistedA Standard Schema for the state hosted by Blaise. A plug that declares it needs an id in setup.
resumableDefault true. false means onSession cannot handle resume runs. Blaise still decides whether a session pauses: the runner warns and pauses when asked.
onLoadBuilds ctx.state once per run.
onMigrateConverts persisted state that no longer validates.
onSessionWraps one start or resume run.
onTeardownWraps the destruction of the environment.
onMessageWraps every ACP message.

Handlers

onSession(ctx, next)

Code before next() attaches, and code after it pauses. Rules:

  • Call next() exactly once. Returning without calling it fails the run, and calling it twice throws.
  • next() never rejects. It resolves with PauseInfo: a reason (idle, completed, closed, cancelled, timeout or failed), mayResume, and an error when the reason is failed. Failures of inner plugs arrive as failed, so pause code needs no try/finally.
  • Throwing fails the run. Before next(), inner plugs never run. After it, the remaining pause code of outer plugs still runs.
  • ctx.agent is writable before next() and frozen after it.
  • next({ host }) runs every inner plug and the agent on another host. Hosts are lazy, and the runner closes the host when that next() resolves.
  • Branch on ctx.run.kind only where start and resume differ. Use mayResume to skip work that only a later resume would use.

onTeardown(ctx, next)

Runs after the pause when the session is over, or in a teardown run for a session that ended while paused. No agent runs. Plugs without it are skipped. Code before next() restores access for inner plugs, and code after it destroys what the plug left behind. next() resolves with TeardownInfo (reason, and error when failed).

onMessage(ctx, message, next)

message is a union discriminated by direction (to_agent, from_agent) and method, derived from the types of the ACP SDK. Narrow on both. Pass the message on with return next(message), modify it, post-process the result, answer without calling next, throw a RequestError to answer a request with a JSON-RPC error, or throw anything else to fail the session. Methods that the SDK does not type pass through without reaching onMessage.

onLoad(ctx) and onMigrate(ctx, stored)

Run once per run, before the other handlers. onLoad returns the value of ctx.state. onMigrate receives the raw stored value when it no longer validates against persisted, and returns the migrated value, which is validated and written back, or undefined to drop it. Without onMigrate, an invalid stored value fails the run.

The context

FieldDescription
inputswith: after evaluation and validation.
statePer-run state returned by onLoad. In memory.
persistedvalue, set(value) and clear(): state hosted by Blaise, per session and plug id.
sessionid, executionId, agent.name.
runkind (start, resume, teardown) and number.
plugid and index.
setupOutputs of earlier plugs, by id.
agentThe agent process draft: command, args, env, cwd.
runnerEnvThe runner's own environment. Never contains Blaise tokens.
logdebug, info, warn, error.
signalAborted when the session is shutting down.
hostWhere the agent runs. Bound to this plug.
runnerAlways the runner's own machine.
setOutput(name, value)Publishes setup.<id>.outputs.<name> to later plugs. Outputs belong to a run.

Persisted state

A small JSON value (a few KB), validated when loaded and encrypted at rest. set writes through to Blaise and resolves when the write is durable, so record a resource id right after creating it. It is for what cannot be derived from the configuration and the session id, and not for long-lived secrets.

Hosts

ctx.host and ctx.runner are Host values: info (kind, OS, home, tmpdir, workspace, persistent), exec(command, options), spawn(spec), an optional forward(spec), and fs, the node:vfs interface. Prefer fs.promises: on remote hosts the synchronous methods block the run on a network round trip. @blaiseagent/runner/host exports the building blocks for plugs that provide a host; see the Host API.

On this page