Aex Brain
Guides

Write an agent loop

Register synchronous hooks and build a portable agent loop artifact.

Install Brain and Zod, then export a named definition from src/index.ts:

npm install @aexhq/brain zod
import { agentloop } from "@aexhq/brain";
import { z } from "zod";

const options = z.object({ instructions: z.string().default("Be helpful.") });
const state = z.object({ messages: z.array(z.unknown()) });

export const assistant = agentloop({ options }, (author) => {
  const memory = author.state(state, () => ({ messages: [] }));

  author.on.message((message, turn) => {
    memory.messages.push({ role: "user", content: [{ type: "text", text: String(message.content) }] });
    return turn.model({ messages: memory.messages });
  });

  author.on.model((completed, turn) => {
    memory.messages.push(completed.response.message);
    const text = completed.response.message.content
      .filter((block) => block.type === "text")
      .map((block) => block.text)
      .join("");
    return turn.reply(text);
  });
});

Build every named extension export with one command:

npx brain build

Applications import the generated factory and pass it under agentloop:

const session = await client.sessions.create({
  agentloop: assistant({ instructions: "Answer briefly." }),
  model,
});

Registration and agent loop handlers are synchronous. Return turn.model, turn.tools, turn.emit, turn.reply, turn.done, or turn.fail. Ordinary deterministic packages can be bundled. I/O and async work belong in Tools and Environments.