Skip to content

About

Official Aex extensions: agentloops and tools built on the published public SDKs

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

extensions

Official Agentloop, Tool and Environment extensions for Aex. They use only the public @aexhq/brain extension API.

Environment providers are independent of Aex hosting. For example, env-modal accepts the application's own Modal client and API credentials; Aex's managed keys, admission and billing are optional composition outside the extension. See the standalone Modal example.

package role
@aexhq/env Scoped Environment control through an ordinary Tool
@aexhq/agentloop-pi Upstream Pi agentloop
@aexhq/agentloop-codex Upstream Codex agentloop
@aexhq/agentloop-opencode Upstream OpenCode agentloop
@aexhq/tool-bash Run Bash commands
@aexhq/tool-edit Replace one exact text occurrence
@aexhq/tool-glob Find workspace paths by glob pattern
@aexhq/tool-grep Search workspace text with ripgrep
@aexhq/tool-ls List directory entries
@aexhq/tool-read Read UTF-8 text
@aexhq/tool-todo Read or replace the workspace to-do list
@aexhq/tool-write Write UTF-8 files
@aexhq/env-http Bounded application tools in existing HTTP or serverless APIs
@aexhq/env-local Docker workspace Environment with retained files and prepared Python projects
@aexhq/env-modal Finite isolated Modal Sandbox with fixed command profiles and cumulative resource usage
@aexhq/tools-mcp Selected MCP Tools in the application's host Environment
@aexhq/env-browser Playwright Environment and five browser Tools, including screenshot media

Brain consumes installed agentloop executables through its public protocol. This repository owns the Pi, Codex and OpenCode adapters, pinned upstream runtimes and their tests. Operators register implementations at startup; sessions select an installed name and settings:

import { pi } from "@aexhq/agentloop-pi";
const session = await brain.sessions.create({ model, tools, agentloop: pi({ contextWindow: 64_000 }) });

pi() returns selection data. It does not load Pi in the client. See the Pi, Codex, and OpenCode startup examples. The composed image ghcr.io/aexhq/brain-agentloops:latest includes all three and pins its Brain base image. Use an immutable digest from the release's agentloops-image.json for deployments.

Tools default to the registering application; pass { env } to place them elsewhere. Workspace Tools ship browser-safe bindings and native Node executables, and run in a prepared Node host, Docker workspace or Modal profile with the package runtime. Prompt-based answer validation and corrective turns belong to downstream applications.

Continue the Brain quickstart with its brain client and model configuration. Install the tool packages and add them to the session:

import { pi } from "@aexhq/agentloop-pi";
import { bash } from "@aexhq/tool-bash";
import { read } from "@aexhq/tool-read";

const session = await brain.sessions.create({
  model,
  agentloop: pi(),
  tools: [read(), bash()],
});

Tool publishers own their builds. The chosen Environment loads the implementation and enforces its resource grants.

Environment services use Brain's public @aexhq/brain/runtime helpers for command validation, authenticated HTTP serving and scoped callbacks. Provider code owns resource allocation, isolation and cancellation. See Write an environment for a service using the same adapters; there is no separate extension-owned wire schema.

These tools run in the registering Node process, using its working directory. Bash must be installed, and the process must stay connected while tools are needed. For an isolated workspace, follow env-local setup, then pass { env: workspace } to each tool. env-local requires an operator-configured image and workspace grants. env-browser requires an operator-supplied browser launcher and deployment isolation. Hosted Aex supports managed Environments, Brain's Wasm Environment, connected hostEnv / clientBrowser Tools, and Application tools served by your authenticated HTTPS endpoint. Use standalone Brain to deploy other Environment services.

Application-resident Tools use the same public factory with run. Their code executes in the application process, and ctx.emit records application-defined events in the session journal. Tool schemas describe accepted inputs; defaulted arguments are optional and the runtime applies Zod defaults and transforms before invoking the handler. Ordinary objects strip extra fields; strict objects reject them. The shared client tool connection suspends after five idle seconds and reconnects before the same live client starts more work. Set connectionIdleTimeoutMs: 0 when other callers or future autonomous events must reach its tools. Call await brain.close() when the application is finished with that client. Use session.interrupt() to stop a turn, end() to finish a conversation, and delete() to remove its stored history.

import { tool } from "@aexhq/brain";
import { z } from "zod";

const notify = tool({
  name: "notify",
  description: "Send a notification.",
  input: z.object({ message: z.string() }),
  run: async ({ message }, ctx) => {
    await ctx.emit("notification_sent", { message });
    return ctx.finish({ delivered: true });
  },
});

const tools = [notify()];

Brain runtime boundary

These packages consume Brain SDK 0.41.0 and its public contracts. Brain remains independently usable without this repository or Aex. Upstream harnesses own native persistence and compaction; Brain owns the journal and commits every mediated model and Tool effect before execution. Native state lives beside the journal. Failed or interrupted native activations require a new session and are never replayed automatically. Brain separates Tool return from completion. Return releases the synchronous caller; ctx.emitResult(value) can supply observations before or after return, and ctx.finish(value) commits the final optional result and completion. Both methods accept { content: summary } to present text alongside the structured result. ctx.model({ messages }) makes an independent request under the Tool's lifetime and the session's model authority; it does not edit the transcript. Use return ctx.finish(value) for ordinary Tools. A Tool that forgets to finish remains open until its original deadline, cancellation or Environment loss; without a deadline it can remain open indefinitely.

Results and completion enter the ordered journal before the harness receives them. Harnesses also consume committed background events. Brain coalesces wakeups for five milliseconds without delaying commits. Interrupt cancels unfinished Tools even between turns. Environments use automatic lifecycle by default; applications can override it with environment.lifecycle. Include the ordinary env Tool when the model should inspect or manage authorized Environments. Tools and harnesses receive their own fixed control grants.

The upstream adapters expose a fixed Tool catalogue, with one model-visible name per admitted placement. They resolve the current Environment instance on each dispatch. The env Tool can manage dynamic resources within its grants; upstream adapters do not add new Tool placements mid-session. There is no automatic placement fallback.

Packages pin their Brain SDK dependency. Use the same version in applications so extension bindings share its TypeScript brands. Pi supports HTTPS image and PDF inputs and Tool results; configure a publication callback for Browser screenshots and MCP binary media. The Codex and OpenCode adapters currently accept text and require an empty initial transcript.

This release requires a new Brain data directory. Old Wasm loops, session-selected executable Agentloops and their checkpoints are removed. Deploy the matching Brain runtime, SDK and extensions together.

Resource lifetimes

Saving a Brain session does not preserve every resource its tools use. Choose a provider with the lifetime your application needs:

Provider What persists and what ends it
Local Docker workspace Files survive tool calls and detach; teardown removes the volume. Host or volume loss can still lose files.
Browser Browser state survives turns and detach. Teardown, an active-call cancellation/timeout or browser loss closes it; a controller restart cannot reattach it.
Modal The sandbox has a finite expiry. Cancel, detach and teardown stop the whole sandbox; an optional turn-end policy can stop it earlier.
HTTP tools A tool finishes within one application request. Persist business state and background jobs in your application's own storage.

Tests

Install Docker, bash and ripgrep, then run npx playwright install-deps chromium and npm run test:prepare to build fixture images and install Chromium. Run npm test for unit/runtime tests and npm run package-smoke for packed consumer composition.

CI runs every Tool, Environment and MCP journey against the pinned Brain image with installed extensions. A mixed-runtime test runs 36 sessions across Pi, Codex and OpenCode concurrently. For local journeys, start Brain on 127.0.0.1:18092 with token extension-fixture-token, model base URL http://127.0.0.1:18093/v1, and BRAIN_AGENTLOOPS:

{
  "pi": {"command":"brain-agentloop-pi","workers":2,"configuration":{"contextWindow":200000,"maxTokens":8192,"compaction":{"enabled":false}}},
  "codex": {"command":"brain-agentloop-codex"},
  "opencode": {"command":"brain-agentloop-opencode"}
}

Then run npm run test:journeys. The tests exercise real Docker workspace recovery, lost replies, MCP errors and cancellation, retained browser state and screenshot media. Scripted model responses keep these gates deterministic. Missing runtime dependencies fail checks. Adapter tests cover native resume, compaction, cancellation and effect mediation. Brain's own suite tests the neutral protocol, worker pools and journal barriers.

npm publishing

Each package's npm trusted publisher must allow npm publish from GitHub organization aexhq, repository extensions, workflow filename npm-publish.yml, and environment npm-production. Configuring this relationship requires interactive npm authentication; bypass-2FA access tokens do not authorize npm trust operations. See the npm setup guide and authentication requirements.

The publish workflow requires an immutable release tag, successful source CI, the real Modal integration check and a successful immutable image build before staging exact package archives under next. Supply that image run's ID when staging. Promotion reuses those archives and the scanned multi-architecture image without rebuilding them, then publishes their manifests together in the GitHub release.

For the first image publication, set brain-agentloops to Public in GitHub package settings. The image workflow verifies anonymous pulls before it can become a release.

About

Official Aex extensions: agentloops and tools built on the published public SDKs

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages