AIec

Docs

From nothing to a running sandbox in about five minutes, with no infrastructure of your own.

Five-minute quickstart

  1. Get an account. Public alpha is invite-only. Request access and we will send an invite to your email.
  2. Create an API key. Open the API keys page and generate a key. It is shown once — store it somewhere safe.
  3. Install the SDK.
    pip install agentforge-sdk
  4. Run something.
from agentforge import AIec

af = AIec(api_key="af_live_...")   # defaults to https://api.aiec.gobrowse.dev

box = af.sandboxes.create(image="python:3.13")
print(box.exec(["python", "-c", "print('hello from AIec')"])["stdout"])
box.destroy()

If you are self-hosting, pass your own endpoint instead:

af = AIec(
    base_url="https://agentforge.example.com",
    api_key="af_live_...",
)

Core concepts

Tenant

Every API key belongs to a tenant. A tenant owns its sandboxes, snapshots, artifacts, usage, quotas and secrets. Possession of a resource ID does not grant access to it.

Sandbox

A disposable computer. It is leased from the scheduler, billed while it runs, and destroyed when you are done with it.

API key

A bearer credential. Stored hashed, shown once, revocable, rotatable. Scoped so a key can be limited to specific operations.

Quota

Per-tenant limits on active sandboxes, vCPU, memory and disk, enforced at placement time. Exceeding one returns 429.

Sandbox lifecycle

States move forward and fail closed:

creating -> starting -> running -> stopping -> stopped
                  \-> paused -> running
   any -> failed  (terminal, but recoverable via recovery or restore)
   any -> destroying -> destroyed

Files

box.write_file("/workspace/main.py", source)
contents = box.read_file("/workspace/main.py")
box.make_directory("/workspace/out")
box.delete_file("/workspace/tmp")
for entry in box.list_files("/workspace"):
    print(entry)

Guest paths are confined to the sandbox workspace. Traversal and symlink escapes are rejected by the guest agent, not by the caller.

Snapshots

A workspace snapshot is a portable archive of /workspace. It is the unit of recovery: if a worker is lost, the control plane reassigns the sandbox and reconstructs the workspace from the newest complete snapshot on the new owner.

snap = box.snapshot()
box2 = af.sandboxes.create(image="agentforge:latest")
box2.restore(snap)

Snapshots preserve the workspace filesystem. They do not preserve running VM memory, and a Firecracker VM snapshot is not portable between hosts.

Errors

Every error has the same envelope, so one handler covers all of them:

{
  "error": {
    "code": "quota_exceeded",
    "message": "tenant vCPU quota exceeded",
    "request_id": "01a0e113-..."
  }
}
StatuscodeMeaning
400invalid_requestMalformed request
401unauthorizedMissing or invalid API key
403forbiddenKey lacks the required scope
404not_foundNo such resource in this tenant
409conflictInvalid state transition, or fenced
429quota_exceededTenant quota reached
429rate_limitedToo many requests; see Retry-After
503backend_unavailableNo capacity or a dependency is down

The Python SDK raises AgentForgeError with code, request_id and retry_after populated. Quote the request_id in a support report — it correlates with the server logs.

Self-hosting

AIec OSS needs no managed provider. You need:

git clone https://github.com/fedoragobrowse-design/AIec.git
cd AIec
docker compose up -d postgres minio
./scripts/build-firecracker-guest.sh

export DATABASE_URL='postgresql://agentforge:...@127.0.0.1:5432/agentforge'
export AGENTFORGE_S3_ENDPOINT='http://127.0.0.1:9000'
export AGENTFORGE_S3_BUCKET='agentforge'
# ... TLS paths ...

agentforge doctor      # validates every prerequisite, with actionable errors
agentforge --url https://127.0.0.1:8080 sandbox --image python:3.13

agentforge doctor checks KVM, the Firecracker binary, the guest artifact and its digest, the database, object storage, networking tooling and TLS, and tells you precisely what is missing rather than failing later.

Full instructions: deployment guide.

Operating it

Health endpoints

/health is liveness and is dependency-free. /ready is readiness and reflects the database, object storage and available capacity, so a rolling deploy is held back when the instance genuinely cannot serve traffic.

Metrics

/metrics exposes Prometheus text format: request rate, latency, errors, sandbox counts, worker capacity and health, lease expirations, reassignments, quota and rate-limit denials.

Backups

Back up both the database and the object store, and test the restore. The database holds tenancy, leases and quotas; the object store holds snapshots and artifacts.

Draining a worker

A draining worker receives no new sandboxes while finishing the ones it already holds, so it can be upgraded or restarted without disrupting running work.

SDKs

LanguageInstallImport
Pythonpip install agentforge-sdkfrom agentforge import AIec
Rustcargo add agentforge-clientuse agentforge_client::AgentForgeClient
HTTP—curl / any HTTP client