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.
| Field | Description |
|---|---|
name | Shown in logs and errors, and stored with persisted state. Required. |
description | Optional. |
inputs | A Standard Schema (Zod 4, Valibot, ArkType) for with:. |
persisted | A Standard Schema for the state hosted by Blaise. A plug that declares it needs an id in setup. |
resumable | Default true. false means onSession cannot handle resume runs. Blaise still decides whether a session pauses: the runner warns and pauses when asked. |
onLoad | Builds ctx.state once per run. |
onMigrate | Converts persisted state that no longer validates. |
onSession | Wraps one start or resume run. |
onTeardown | Wraps the destruction of the environment. |
onMessage | Wraps 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 withPauseInfo: areason(idle,completed,closed,cancelled,timeoutorfailed),mayResume, and anerrorwhen the reason isfailed. Failures of inner plugs arrive asfailed, so pause code needs notry/finally.- Throwing fails the run. Before
next(), inner plugs never run. After it, the remaining pause code of outer plugs still runs. ctx.agentis writable beforenext()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 thatnext()resolves.- Branch on
ctx.run.kindonly wherestartandresumediffer. UsemayResumeto 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
| Field | Description |
|---|---|
inputs | with: after evaluation and validation. |
state | Per-run state returned by onLoad. In memory. |
persisted | value, set(value) and clear(): state hosted by Blaise, per session and plug id. |
session | id, executionId, agent.name. |
run | kind (start, resume, teardown) and number. |
plug | id and index. |
setup | Outputs of earlier plugs, by id. |
agent | The agent process draft: command, args, env, cwd. |
runnerEnv | The runner's own environment. Never contains Blaise tokens. |
log | debug, info, warn, error. |
signal | Aborted when the session is shutting down. |
host | Where the agent runs. Bound to this plug. |
runner | Always 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.