Aex Brain
Reference

Harness protocol

Startup selection, lifecycle, native state, and journaled callbacks.

Brain reads a name-to-registration map from --agentloops or BRAIN_AGENTLOOPS before readiness. Each registration has command, optional args, optional configuration, workers (default 1), and max_concurrency per worker (default 64). Counts must be positive. Names contain 1–64 ASCII letters, digits, underscores or hyphens.

Sessions require agentloop: { name, configuration?, environments? }. The name selects a startup registration. Commands and implementation code are rejected in session requests. The selection, options and Environment grants are immutable after creation.

Brain balances newly opened sessions across healthy workers in that registration. Open sessions retain their worker assignment. An activation waits for worker capacity; cancellation also works while queued. Failure does not reassign an open session or retry effects. Other workers remain available. Readiness succeeds while any worker can serve requests; creating a session for an unavailable registration fails.

Transport and lifecycle

The process exchanges one JSON-RPC 2.0 object per UTF-8 line over stdin/stdout. Both directions use request ids; diagnostics belong on stderr. The protocol is brain/harness/v1. Rust types in brain-protocol/src/harness.rs define its payloads.

Brain requestParametersResult
initializeprotocol, state_directory, configurationprotocol, name, state_version
session/opensession_idnull
session/runsession_id, sequence, model, input{ result? }
session/cancelsession_idnull
session/closesession_idnull
session/deletesession_idnull
shutdown{}null

sequence names the activation's journal record. model supplies advisory model metadata, not credentials. input contains optional user input, transcript, KV, pending events, immutable tool declarations and current placements, system prompt, session configuration, and the runtime envelope.

There is one active run per session. Different sessions can run concurrently. Cancellation must be handled while run is pending. Initialization has a 30-second deadline; cancellation has a five-second grace period before Brain kills the harness process. Killing a worker also fails its other active sessions; other workers are unaffected.

Callbacks

A harness requests brain/call with:

{
  "session_id": "ses_12345678901234567890",
  "sequence": 3,
  "method": "model",
  "input": {
    "messages": [{"role":"user","content":[{"type":"text","text":"Hello"}]}],
    "tools": []
  }
}
MethodInput / result
modelModelRequest / ModelResult
dispatchToolInvocation[] / ToolReturn[]
set_transcriptMessage[] / committed sequence
kv_readkey string / {} or { value }
kv_put{ key, value } / committed sequence
kv_deletekey string / committed sequence
eventssequence / finite EventPage
emit{ event_type, data } / committed sequence
environmentsEnvironmentControlRequest / operation result
telemetryJSON record / null

Callbacks work only during the named activation. Await every callback before returning. An error contains data.code and data.fatal; fatal errors stop the activation even when upstream catches them. The TypeScript binding aborts ctx.signal and calls cancel. Brain drains already admitted callbacks before closing their authority.

Model and Tool requests cross durable journal barriers. Brain sends each effect once and records an unknown outcome if a remote result is uncertain. Missing usage counters remain absent. Upstream token estimates used for compaction are private runtime state.

Native state and recovery

The harness identity and state version are bound to the data directory. A mismatched identity refuses startup. Native state lives beneath agentloops/<registration>/<session_id>/; closing or passivating a session retains it, while session deletion removes it.

Brain records brain.harness.activation before entering native execution and removes it only after successful completion. A remaining marker refuses subsequent execution, including after restart. Create a new session after an interrupted or failed native activation. The journal and transcript remain readable. This prevents an upstream at-least-once recovery routine from replaying an uncertain tool effect.

The journal is authoritative for Brain's effects. Upstream files are authoritative for agent continuation. There is no cross-harness checkpoint conversion or transactional crash recovery spanning the two stores. Pre-0.41 active sessions are not compatible; start with a new data directory.

Upstream adapters

The ghcr.io/aexhq/brain-agentloops image composes the public Brain image with extension-owned runtimes. For a custom deployment, install the corresponding package:

npm install @aexhq/brain@0.41.0 @aexhq/agentloop-pi@11.0.0
npm install @aexhq/agentloop-codex@11.0.0 @aexhq/agentloop-opencode@1.0.0

They provide brain-agentloop-pi, brain-agentloop-codex and brain-agentloop-opencode. Pi uses Node 22.19+, Codex launches its pinned Rust executable, and OpenCode uses Bun 1.3.14. Client exports construct selections; /runtime exports the implementation. The packages own upstream compatibility tests, configuration types and dependency pins.

AdapterConfiguration
PicontextWindow?, maxTokens?, compaction?: { enabled?, reserveTokens?, keepRecentTokens? }
CodexcontextWindow?, compactAtTokens?
OpenCodecontextWindow?, maxTokens?, compaction?: { auto?, buffer?, keep?: { tokens? } }

Session values override deployment values. Missing context-window or output-limit metadata must be supplied explicitly where required. Unknown keys fail.

Pi uses the complete coding-agent session SDK. OpenCode uses its embedded SDK with a custom provider and tool catalogue. Codex uses its Rust app-server, dynamic tools, and a local Responses gateway into Brain's model adapter; its dynamic-tool API is experimental and version-pinned. All three delegate compaction to upstream, retain opaque model continuation, exclude unadmitted tools, and disable transport retries.

Pi accepts HTTPS media and imported transcripts. Codex and OpenCode currently accept text only and start from native state. All three keep a fixed tool-placement catalogue per native session. A changed catalogue fails explicitly; incarnation references are resolved from the current activation. Custom harnesses may support additional features.

Environment control

Grant a harness access with agentloop.environments, and declare the corresponding Environments in the session. Call ctx.environments in a custom implementation. Upstream adapters do not invent management tools or interpret these grants as model tools. See Environment control.

On this page