Runner and PlugsExplanation
Design alternatives
What was considered before plugs, and why each alternative lost.
These are the other designs considered for the runner, and why they were not chosen.
| Alternative | Why not |
|---|---|
| Keep scripting around the spawned command | It cannot see or change the traffic between Blaise and the agent, has no cleanup, and tends to wrap the whole runner, which puts the token next to the agent. |
| Hooks on the typed callbacks of the ACP SDK | They miss methods the SDK does not call back for, such as initialize and extensions, and tie plugs to an agent on a local pipe. The runner proxies the raw message stream instead, so one mechanism sees everything. |
| Fork a process for each run instead of the CLI | Breaks for installed packages and compiled binaries. The CLI starts itself with a hidden run command, which works the same everywhere. |
| Timers on the runner for idle and paused time | Two sources of truth, and a dead runner enforces nothing. See Why time belongs to Blaise. |
| A snapshot of the configuration for each session | Needed to match stored state to plugs after a change. Stateless plugs and state keyed by id do the same without it. |
| A separate package for the authoring API | Two packages with one version line. The authoring API is part of @blaiseagent/runner. |
Conditions in setup entries (if) | Grows the entry syntax. Conditions live in plugs or in separate files that are included. |
| A string interpolation of our own | ${{ }} uses GitHub's expression library, whose syntax people already know. |
| Keeping the agent process across a pause | Needs a detached supervisor on the host. A resume starts the agent again and loads the conversation with session/load. It fits the same API and is left for later. |
How the chosen design works: How plugs wrap a session.