AIStor Memory
Integrations

OpenAI Codex / Agents SDK

Mount an AIStor Memory Bucket at /workspace in a self-hosted Codex or Agents SDK sandbox, so the agent's apply_patch edits survive teardown.

Codex makes its edits with apply_patch, and it needs a writable filesystem under the agent's working directory. In a self-hosted Codex or OpenAI Agents SDK sandbox, AIStor Memory mounts a Memory Bucket at that directory. The agent's edits become files in your AIStor, next to the memory files it reads (CLAUDE.md, AGENTS.md) and the annotations it writes under .aimem/annot/. A later session mounts the same bucket and finds the same files.

Codex Cloud, the hosted offering, is not supported. Its 12-hour container-snapshot lifecycle does not work with a running FUSE process.

Prerequisites

Use a Memory Bucket

aimem mounts only a Memory Bucket. See Prerequisites.

  • Docker, on a host that allows /dev/fuse and grants CAP_SYS_ADMIN. Docker Desktop, GitHub Actions, and most production hosts do.
  • An OpenAI API key.
  • An AIStor endpoint that the container can reach, and signing credentials for it.

Integration shape

  1. The example image extends ghcr.io/openai/codex-universal with aimem, the setuid aimem-fusermount helper, Codex CLI, and the Python SDKs.
  2. The entrypoint mounts the bucket at /workspace, waits for the mount, registers OPENAI_API_KEY with Codex CLI when it is set, and then starts the agent command inside the mount.
  3. Codex CLI and the Codex SDK must use the full-access sandbox (--sandbox danger-full-access on the CLI; sandbox=Sandbox.full_access in the Python SDK; sandboxMode: "danger-full-access" in the TypeScript SDK). Otherwise Codex's built-in bubblewrap (bwrap) sandbox rebuilds the mount namespace and hides the FUSE mount. See openai/codex#14794 and #15505.

Quick start

Download the example, then create the settings file and start the agent from that directory:

mkdir aimem-openai-agents-sdk && cd aimem-openai-agents-sdk
base=https://docs.min.io/aimem/examples/openai-agents-sdk
for f in agent.py agent_smoke.py aimem-mount codex.Dockerfile codex_sdk_smoke.py \
  entrypoint.sh run-agent; do
  curl -fsSLO "$base/$f"
done
curl -fsSL "$base/env.example" -o .env.example
chmod +x aimem-mount entrypoint.sh run-agent
mkdir -p bin

cp .env.example .env
$EDITOR .env
./run-agent

Fill in these .env values:

VariableRequiredNotes
AIMEM_BUCKETyesMemory Bucket to mount at /workspace
AIMEM_ENDPOINTyesAIStor endpoint URL (Enterprise / paid tier)
AIMEM_ACCESS_KEYyesAIStor Memory S3 access key
AIMEM_SECRET_KEYyesAIStor Memory S3 secret key
OPENAI_API_KEYyesUsed by Agents SDK, Codex CLI, and SDKs
AIMEM_SESSION_TOKENnoTemporary credential token, when needed
AIMEM_AGENTnoAgent-memory warmup profile (default codex)
AIMEM_WORKDIRnoMount path inside the container (default /workspace)
AIMEM_LOCALnoStaging dir for open-for-write files (default /var/cache/aimem-staging)
AIMEM_AGENT_MODELnoModel agent.py uses (default gpt-5-mini)
AIMEM_SMOKE_MODELnoModel the Agents SDK / Codex SDK smoke scripts use (default gpt-5-mini)

If the variables are already set in your shell, you can skip .env; run-agent passes them through.

./run-agent builds the aimem-openai-agents-sdk:latest image if it is missing, mounts the bucket at AIMEM_WORKDIR (/workspace by default), and runs python /agent.py. That demo agent writes SUMMARY.md through AIStor Memory.

Run other agents

Codex CLI, on the same mounted workspace, with the bwrap bypass:

./run-agent codex exec --sandbox danger-full-access --skip-git-repo-check \
  "summarize the repo"

To check that each SDK can use the mount, run its test script:

./run-agent python /agent_smoke.py
./run-agent python /codex_sdk_smoke.py

Use the Codex SDK

The SDKs start the same Codex binary as the CLI, so they also need the full-access sandbox (step 3 in Integration shape). In the image, the Codex binary is at /usr/local/bin/codex; point the Python SDK at it:

import os
from openai_codex import Codex, CodexConfig, Sandbox

config = CodexConfig(codex_bin="/usr/local/bin/codex")
with Codex(config) as codex:
    codex.login_api_key(os.environ["OPENAI_API_KEY"])
    thread = codex.thread_start(
        sandbox=Sandbox.full_access,   # required — see Integration shape step 3
        cwd="/workspace",              # the AIStor Memory mount
    )
    result = thread.run("Diagnose the test failure and propose a fix.")
    print(result.final_response)

The TypeScript SDK (@openai/codex-sdk) works the same way:

import { Codex } from "@openai/codex-sdk";
const codex = new Codex();
const thread = codex.startThread({
  sandboxMode: "danger-full-access",
  workingDirectory: "/workspace",
});
const turn = await thread.run("Diagnose the test failure and propose a fix.");
console.log(turn.finalResponse);

Keep the model loop outside the sandbox

For new orchestrators, run the model loop, approvals, tracing, and the model API key in a trusted worker outside the sandbox. Send only typed shell or file tool calls into the sandbox. The sandbox holds the AIStor Memory mount and narrow storage credentials; the worker never opens /workspace and the model key never enters the sandbox. Adapt the tool transport to your sandbox provider's client or MCP. The image flow above still suits self-hosted Codex CLI.

What the agent sees

PathModeNotes
/workspace/rwBucket-backed workspace; atomic upload on close
/workspace/.aimem/annot/rwPer-object annotation namespace
/var/cache/aimem-staging/rwStaging dir - random writes land here first

On each mount, AIStor Memory installs the aimem skill in $HOME/.agents/skills/aimem/ (read by Codex CLI and the SDKs) and $HOME/.claude/skills/aimem/. It never overwrites existing files, and it skips the install when $HOME is inside the mount. To turn it off, set AIMEM_INSTALL_SKILL=0. Instruction files (CLAUDE.md, AGENTS.md, .cursorrules) read from the mount also start with a short usage preamble, added in memory.

A worker outside the sandbox does not see the mount or the installed skill. Install the skill in the worker:

npx skills add minio/skills/aimem

See SKILLS for details.

Image options

To pin an AIStor Memory release, rebuild with:

AIMEM_VERSION=RELEASE.<date> AIMEM_BUILD=1 ./run-agent

For an offline build, put Linux/amd64 aimem and aimem-fusermount binaries in bin/ in the example directory and rebuild:

AIMEM_BUILD=1 ./run-agent

To change the Codex base image or the SDK versions:

CODEX_IMAGE=my-org/codex-base:latest \
OPENAI_AGENTS_VERSION=<version> \
OPENAI_CODEX_SDK_VERSION=0.1.0b2 \
AIMEM_BUILD=1 ./run-agent

OPENAI_AGENTS_VERSION and CODEX_IMAGE follow latest by default. Pin both to a version or digest for repeatable builds.

How FUSE works here

aimem opens /dev/fuse and passes the device to the setuid-root aimem-fusermount helper, which performs the mount. The agent process runs without privileges inside the container.

Reference