Aex Brain
Guides

Write an Environment extension

Own a Tool runtime and expose provider-specific methods with one authoring shape.

An Environment owns somewhere Tools run. open, run, and close may be async and may use normal runtime libraries:

import { environment } from "@aexhq/brain";
import { z } from "zod";
import Provider from "@vendor/cloud-sdk";

const options = z.object({ region: z.string() });

export const cloudVm = environment({ options }, (author) => {
  const vm = author.open(async ({ options, id }) => {
    const provider = new Provider({ region: options.region });
    return provider.getOrCreate({ id });
  });

  vm.run(async (request, context) => context.instance.execute(request, { signal: context.signal }));
  vm.close(async ({ instance }) => instance.close());

  return {
    suspend: vm.method(async (_input, context) => context.instance.suspend()),
  };
});

Build it with npx brain build. The generated application object implements Brain's Environment interface and keeps its own methods:

const vm = cloudVm({ region: "eu-west-2" });
const session = await client.sessions.create({
  agentloop: pi(),
  model,
  tools: [read().useIn(vm), bash().useIn(vm)],
});

await vm.suspend();

The exact Environment object identifies the attachment. A generated method fails before the session attaches and after it ends. Brain journals the call intent, routes it to that attachment, and records the terminal receipt.