A minimal, distributed and extensible agent runtime
18
stars
187
commits
Rust
primary language
Sep 10, 2026
updated
______ ______ _______ _______ _______ ▄████▄ | __ \ __ \ _ |_ _| | | ▄██▄██▄██▄ | __ < < |_| |_| | ▀▀ ▀▀ |______/___|__|___|___|_______|__|____|
A minimal, blazing fast, extensible agent runtime.
Docs · API Reference · Website · Official extensions · 中文
Brain is a minimal, blazingly fast, extensible agent runtime server. You write the agent loop and the tools, and Brain runs the session. Tools run anywhere, from a browser tab to a server sandbox. Agent loops run in a Wasm sandbox, so the runtime is secure by design. Each session uses very little memory, and every step is an event you can watch in real time.
[!NOTE] Early preview. The API and functionality may change without backward compatibility or notice until we cut 1.0.0.
No model latency in any number. ★ marks Brain in each chart.
Turn round-trip
Brain █ 40 ms ★
ZeroClaw ███ 53 ms
OpenFang ██████████ 128 ms
AgentScope ██████████████████ 338 ms
Letta ███████████████████████ 678 ms
LangGraph ████████████████████████████ 1.22 s
Awaken █████████████████████████████████ 2.23 s
OpenClaw ████████████████████████████████████ 3.33 s
Time to first token
Brain █ 2.9 ms ★
ZeroClaw ████████ 11 ms
OpenFang ██████████████████ 70 ms
LangGraph ████████████████████████ 207 ms
AgentScope ███████████████████████████ 332 ms
Letta ████████████████████████████ 407 ms
OpenClaw ██████████████████████████████████ 1.33 s
Awaken ████████████████████████████████████ 1.93 s
New session
LangGraph █ 0.66 ms
Brain ██ 0.76 ms ★
ZeroClaw ██████████ 2.2 ms
Awaken ████████████████ 5.1 ms
OpenClaw █████████████████ 5.4 ms
OpenFang █████████████████████ 9.8 ms
Letta ████████████████████████████████████ 67 ms
Memory per idle session
Brain █ 14 KiB ★
OpenFang ██████████████ 0.6 MiB
ZeroClaw ████████████████████████████ 50 MiB
OpenClaw ████████████████████████████████████ 490 MiB
Each number is the median from the harness in tools/bench, run on
the same AWS c7g.xlarge for every subject. Bars use a log scale. The chart includes
only agent runtimes that own sessions behind an API. BENCHMARKS.md has
the method and the subject versions.
Brain owns the session. Everything else is an extension. You write it with the @aexhq/brain
SDK, run npx brain build, and pass the generated factory to a session. There are three
kinds, and each one is a small typed declaration.
npx brain build compiles it to a WebAssembly component, and
Brain runs that component in a Wasmtime sandbox with no filesystem,
network, clock, or secrets. Brain performs every effect the loop asks for, so each decision is
deterministic and can be replayed from the journal.
Write an agent loopfs, process, net, dom, secrets). Inside, it is plain code for the
platform it runs on. If the environment does not declare what the tool needs, Brain rejects
the session at create time. A tool that is one shell command or one HTTP request needs no
code at all. Write a toolThe packages in aexhq/extensions use the same SDK and the same build. Nothing built in gets a shortcut.
| Package | Kind | What it is |
|---|---|---|
@aexhq/agentloop-pi | Agent loop | Pi-style coding loop. Tool calls run in parallel. |
@aexhq/agentloop-codex | Agent loop | Codex-style coding loop. Tool calls run one at a time. |
@aexhq/tools | Tools | read, write, edit, ls, glob, grep, bash, todo |
@aexhq/env-aws-microvm | Environment | One AWS microVM per session, with fs, process, and net |
This is one turn from start to finish. The agent loop decides what to do next. Brain does the I/O, writes the intent to the journal before acting, and streams the result while the turn is still running.
+-------------------------------+
your app ------->| session state, in memory |
<-------| live event feed |
+---------------+---------------+
| activate
v
+-------------------------------+
| agent loop, a Wasm component | decides
+---------------+---------------+
| decision
v
+-------------------------------+ +-----------------+
| Brain does the I/O |<------>| append-only log |
| for the loop | intent | off the turn's |
+---------------+---------------+ result | hot path |
| +-----------------+
+--> model provider, streaming
|
+--> tool, in any environment
Brain owns the session. You supply the agent loop, the model, the tools, and the environment. Four design choices make it fast:
Brain is one native Rust binary on Tokio. It serves the session API over HTTP and SSE with Axum and needs no external store.
In this example the tool is a plain function in your own process. You declare it once and pass it to the session. The SDK answers the model's calls from the session's event feed, so your app needs no server, no open port, and no extra channel.
Run a server:
docker run --rm -p 127.0.0.1:8080:8080 \
-e BRAIN_LISTEN=0.0.0.0:8080 -e BRAIN_API_TOKEN=quickstart \
-v brain-data:/var/lib/brain ghcr.io/aexhq/brain:latest
npm install @aexhq/brain @aexhq/agentloop-pi zod
Save as order.mjs and run with node order.mjs:
import { Brain, tool } from "@aexhq/brain";
import { pi } from "@aexhq/agentloop-pi";
import { z } from "zod";
const orders = { "A-1001": { status: "shipped", eta: "Thursday" } };
const lookupOrder = tool({
name: "lookup_order",
description: "Look up an order's status by id.",
input: z.object({ id: z.string() }),
execute: ({ id }) => orders[id] ?? { status: "unknown order" },
});
const brain = new Brain({ baseUrl: "http://127.0.0.1:8080", token: "quickstart" });
const session = await brain.sessions.create({
model: { provider: "openai", name: "gpt-5-mini", apiKey: process.env.OPENAI_API_KEY },
agentloop: pi(),
tools: [lookupOrder],
});
await session.send("Where is order A-1001?");
for await (const event of session.events()) console.log(event.sequence, event.type);
await session.end();
await session.delete();
process.exit(0);
The model reads the question and calls lookup_order. The call arrives as a typed record
on the session's event feed, your function answers it using the orders object it closes
over, and the SDK posts the result back. The journal keeps both the call and the result. If
a tool has to run somewhere else, such as a browser page, a sandbox, or another machine, it
declares a hosting environment instead and the session API stays the same. See the
app tools guide.
brain, tool, and environment authoring with brain build@aexhq/brain SDKenv-app and env-aws-microvmsendcheckpoint and restoreagentloop.wit contractFor support and bug reports, open an issue or write to support@aex.dev. For collaboration and partnerships, write to admin@aex.dev.
187 commits
Rust
88.9%
TypeScript
6.6%
JavaScript
2.5%
Python
1.6%
A minimal, distributed and extensible agent runtime
18
stars
187
commits
Rust
primary language
Sep 10, 2026
updated
______ ______ _______ _______ _______ ▄████▄ | __ \ __ \ _ |_ _| | | ▄██▄██▄██▄ | __ < < |_| |_| | ▀▀ ▀▀ |______/___|__|___|___|_______|__|____|
A minimal, blazing fast, extensible agent runtime.
Docs · API Reference · Website · Official extensions · 中文
Brain is a minimal, blazingly fast, extensible agent runtime server. You write the agent loop and the tools, and Brain runs the session. Tools run anywhere, from a browser tab to a server sandbox. Agent loops run in a Wasm sandbox, so the runtime is secure by design. Each session uses very little memory, and every step is an event you can watch in real time.
[!NOTE] Early preview. The API and functionality may change without backward compatibility or notice until we cut 1.0.0.
No model latency in any number. ★ marks Brain in each chart.
Turn round-trip
Brain █ 40 ms ★
ZeroClaw ███ 53 ms
OpenFang ██████████ 128 ms
AgentScope ██████████████████ 338 ms
Letta ███████████████████████ 678 ms
LangGraph ████████████████████████████ 1.22 s
Awaken █████████████████████████████████ 2.23 s
OpenClaw ████████████████████████████████████ 3.33 s
Time to first token
Brain █ 2.9 ms ★
ZeroClaw ████████ 11 ms
OpenFang ██████████████████ 70 ms
LangGraph ████████████████████████ 207 ms
AgentScope ███████████████████████████ 332 ms
Letta ████████████████████████████ 407 ms
OpenClaw ██████████████████████████████████ 1.33 s
Awaken ████████████████████████████████████ 1.93 s
New session
LangGraph █ 0.66 ms
Brain ██ 0.76 ms ★
ZeroClaw ██████████ 2.2 ms
Awaken ████████████████ 5.1 ms
OpenClaw █████████████████ 5.4 ms
OpenFang █████████████████████ 9.8 ms
Letta ████████████████████████████████████ 67 ms
Memory per idle session
Brain █ 14 KiB ★
OpenFang ██████████████ 0.6 MiB
ZeroClaw ████████████████████████████ 50 MiB
OpenClaw ████████████████████████████████████ 490 MiB
Each number is the median from the harness in tools/bench, run on
the same AWS c7g.xlarge for every subject. Bars use a log scale. The chart includes
only agent runtimes that own sessions behind an API. BENCHMARKS.md has
the method and the subject versions.
Brain owns the session. Everything else is an extension. You write it with the @aexhq/brain
SDK, run npx brain build, and pass the generated factory to a session. There are three
kinds, and each one is a small typed declaration.
npx brain build compiles it to a WebAssembly component, and
Brain runs that component in a Wasmtime sandbox with no filesystem,
network, clock, or secrets. Brain performs every effect the loop asks for, so each decision is
deterministic and can be replayed from the journal.
Write an agent loopfs, process, net, dom, secrets). Inside, it is plain code for the
platform it runs on. If the environment does not declare what the tool needs, Brain rejects
the session at create time. A tool that is one shell command or one HTTP request needs no
code at all. Write a toolThe packages in aexhq/extensions use the same SDK and the same build. Nothing built in gets a shortcut.
| Package | Kind | What it is |
|---|---|---|
@aexhq/agentloop-pi | Agent loop | Pi-style coding loop. Tool calls run in parallel. |
@aexhq/agentloop-codex | Agent loop | Codex-style coding loop. Tool calls run one at a time. |
@aexhq/tools | Tools | read, write, edit, ls, glob, grep, bash, todo |
@aexhq/env-aws-microvm | Environment | One AWS microVM per session, with fs, process, and net |
This is one turn from start to finish. The agent loop decides what to do next. Brain does the I/O, writes the intent to the journal before acting, and streams the result while the turn is still running.
+-------------------------------+
your app ------->| session state, in memory |
<-------| live event feed |
+---------------+---------------+
| activate
v
+-------------------------------+
| agent loop, a Wasm component | decides
+---------------+---------------+
| decision
v
+-------------------------------+ +-----------------+
| Brain does the I/O |<------>| append-only log |
| for the loop | intent | off the turn's |
+---------------+---------------+ result | hot path |
| +-----------------+
+--> model provider, streaming
|
+--> tool, in any environment
Brain owns the session. You supply the agent loop, the model, the tools, and the environment. Four design choices make it fast:
Brain is one native Rust binary on Tokio. It serves the session API over HTTP and SSE with Axum and needs no external store.
In this example the tool is a plain function in your own process. You declare it once and pass it to the session. The SDK answers the model's calls from the session's event feed, so your app needs no server, no open port, and no extra channel.
Run a server:
docker run --rm -p 127.0.0.1:8080:8080 \
-e BRAIN_LISTEN=0.0.0.0:8080 -e BRAIN_API_TOKEN=quickstart \
-v brain-data:/var/lib/brain ghcr.io/aexhq/brain:latest
npm install @aexhq/brain @aexhq/agentloop-pi zod
Save as order.mjs and run with node order.mjs:
import { Brain, tool } from "@aexhq/brain";
import { pi } from "@aexhq/agentloop-pi";
import { z } from "zod";
const orders = { "A-1001": { status: "shipped", eta: "Thursday" } };
const lookupOrder = tool({
name: "lookup_order",
description: "Look up an order's status by id.",
input: z.object({ id: z.string() }),
execute: ({ id }) => orders[id] ?? { status: "unknown order" },
});
const brain = new Brain({ baseUrl: "http://127.0.0.1:8080", token: "quickstart" });
const session = await brain.sessions.create({
model: { provider: "openai", name: "gpt-5-mini", apiKey: process.env.OPENAI_API_KEY },
agentloop: pi(),
tools: [lookupOrder],
});
await session.send("Where is order A-1001?");
for await (const event of session.events()) console.log(event.sequence, event.type);
await session.end();
await session.delete();
process.exit(0);
The model reads the question and calls lookup_order. The call arrives as a typed record
on the session's event feed, your function answers it using the orders object it closes
over, and the SDK posts the result back. The journal keeps both the call and the result. If
a tool has to run somewhere else, such as a browser page, a sandbox, or another machine, it
declares a hosting environment instead and the session API stays the same. See the
app tools guide.
brain, tool, and environment authoring with brain build@aexhq/brain SDKenv-app and env-aws-microvmsendcheckpoint and restoreagentloop.wit contractFor support and bug reports, open an issue or write to support@aex.dev. For collaboration and partnerships, write to admin@aex.dev.
187 commits
Rust
88.9%
TypeScript
6.6%
JavaScript
2.5%
Python
1.6%