BlaiseBlaise
Documentation
Runner and PlugsExplanation

How plugs wrap a session

The chain of handlers, the run lifecycle, the message proxy and where each message is recorded.

One chain, three handlers

Plugs nest in the order of setup: the first plug wraps all the others. Each handler receives a next function that runs everything inside it, and the code around that call is where the plug does its work.

Before next() a plug attaches: it creates or re-attaches what it needs and shapes the agent's command, directory and environment. After next() it pauses. A run always ends in a pause, whatever the reason, so a plug writes its pause code once, as the code after await next(). next() never rejects: a failure of an inner plug arrives as a pause with the reason failed.

When the session cannot resume, the chain runs again for teardown, in the same process: only plugs with an onTeardown take part, outermost first, and each destroys what it created after its inner plugs have.

Runs

A session is a series of runs. A start run creates the environment; a resume run, after a pause, re-attaches to it; a teardown run only destroys it. A plug asks ctx.run.kind only where the runs differ: often "create unless it exists" covers both start and resume.

Messages

The agent talks to the runner in the Agent Client Protocol, as JSON-RPC over the agent's stdio. The runner sits on that stream as a proxy, so every method, including the ones the SDK does not know, passes through one mechanism that does not care whether the stream is a local pipe or a remote channel.

Messages whose method the ACP SDK types reach onMessage, in both directions. Messages to the agent flow through plug 1 first; messages from the agent flow through the last plug first, so the outermost plug has the last word on what reaches Blaise.

A message is recorded where it leaves the chain: what the agent sees (including text a plug injected) and what Blaise receives (after redaction). A request that a plug answers itself is recorded too, tagged with the plug's name. History replayed when a session is loaded again is shown to the plugs but not recorded a second time.

Hosts

Plugs act on the agent's machine through ctx.host, not through Node's fs and child_process. A plug can pass a different host to next({ host }), and every plug after it, and the agent, then runs there. Hosts connect when first used, and the runner closes the host when the next() that introduced it resolves. The file system of every host has the node:vfs interface, and the local host is the real file system, so a plug is written once for a laptop and for a container.

Isolation

Each session runs in a process of its own. All plug code runs in that process, on the runner's machine, including the handlers of plugs listed below one that switches the host: only their effects happen on the host.

On this page