Images and create options

Canonical images, image references, build layers, registry credentials, and the options `Sandboxes.create` takes.

Images are references: the functions here resolve and normalise them without pulling anything. ImageBuild layers and a RegistrySecret go into SandboxCreateOptions.

Python programs usually use the high-level API instead: cua_sandbox.Image.

canonical_image names one public repository per OS; CUA_IMAGE_LINUX, CUA_IMAGE_WINDOWS and CUA_IMAGE_MACOS override it. The image catalog details lists each image's variants, and runtime support where each one runs.

canonical_image#

The canonical image for os (linux, windows, macos) and version (None = default: ghcr.io/trycua/linux:24.04, ghcr.io/trycua/windows:2022, ghcr.io/trycua/macos:26; macOS accepts tahoe/sequoia). CUA_IMAGE_<OS> overrides the default version.

def canonical_image(os: str, version: Optional[str]) -> str
ParameterTypeDefault
osStringrequired
versionOption<String>required

Returns String · Raises CuaError

Example

import cua
 
print([cua.canonical_image(os, None) for os in ("linux", "windows", "macos")])
# ['ghcr.io/trycua/linux:24.04', 'ghcr.io/trycua/windows:2022', 'ghcr.io/trycua/macos:26']

image_alias#

The canonical image a CLI alias (linux, windows, macos[:version], bare ubuntu) names, or None for a plain reference (ubuntu:24.04 is Docker Hub's image).

def image_alias(name: str) -> Optional[str]
ParameterTypeDefault
nameStringrequired

Returns Option<String>

Example

import cua
 
print([cua.image_alias("macos:sequoia"), cua.image_alias("ubuntu:24.04")])
# ['ghcr.io/trycua/macos:15', None]

normalize_image#

Normalises a reference like the docker CLI (python is docker.io/library/python:latest). No registry read.

def normalize_image(reference: str) -> str
ParameterTypeDefault
referenceStringrequired

Returns String · Raises CuaError

Example

import cua
 
print([cua.normalize_image("python:3.12-slim"), cua.normalize_image("ghcr.io/trycua/linux:24.04")])
# ['docker.io/library/python:3.12-slim', 'ghcr.io/trycua/linux:24.04']

resolve_image#

Resolves reference for backend (auto, local, provider, container/docker/gvisor, vm/qemu/kubevirt, lume) on arch (amd64/arm64; None = this host). reference is literal (ubuntu:24.04 is Docker Hub's image): no alias applies here; use image_alias or canonical_image first. Raises NotFound (no such image: e.g. a tag only the local engine has), Unauthenticated (the registry refused the credentials), Unsupported (no variant the backend runs, e.g. a macOS image on a cloud provider). Blocks while the registry is read (cached for five minutes).

def resolve_image(reference: str, backend: str, arch: Optional[str]) -> ResolvedImage
ParameterTypeDefault
referenceStringrequired
backendStringrequired
archOption<String>required

Returns ResolvedImage · Raises CuaError (NotFound, Unauthenticated, Unsupported)

resolve_image_with_secret#

resolve_image for a private image: secret joins the head of the registry auth chain (it is read in this process and never cached or logged). Same errors as resolve_image.

def resolve_image_with_secret(reference: str, backend: str, arch: Optional[str], secret: RegistrySecret) -> ResolvedImage
ParameterTypeDefault
referenceStringrequired
backendStringrequired
archOption<String>required
secretRegistrySecretrequired

Returns ResolvedImage · Raises CuaError

ResolvedImage record#

A reference resolved for a backend.

Returned by resolve_image, resolve_image_with_secret.

FieldTypeDefaultDescription
referenceStringThe reference as given, normalised (docker.io/library/python:3.12-slim).
variant_ref / variantRefStringThe chosen variant by tag (the input or its sibling). Lume pulls this.
pinned_ref / pinnedRefStringregistry/repo@sha256:… of the chosen variant.
digestStringThe digest in pinned_ref.
variantStringrootfs, containerdisk or lume.
archOption<String>Architecture to run (amd64/arm64).
architecturesVec<String>Architectures the variant offers.
emulatedboolWhether arch differs from the requested one (runs emulated).
osStringGuest OS: linux, windows or macos.
spacesdOption<bool>Whether the image carries cua-spacesd (None: cannot tell).

ImageInfo record#

The image a sandbox runs, as resolved and pinned at create time.

Returned by Sandbox.image_info.

FieldTypeDefaultDescription
referenceStringThe reference as requested, normalised (docker.io/library/python:3.12-slim).
pinned_ref / pinnedRefStringregistry/repo@sha256:... of the variant that runs.
digestStringThe digest in pinned_ref.
variantStringrootfs, containerdisk or lume.
archOption<String>Architecture that runs (amd64/arm64), when known.
osStringGuest OS: linux, windows or macos.
emulatedboolWhether it runs emulated (no build for the requested architecture).
spacesdOption<bool>NoneWhether the image carries cua-spacesd (ai.cua.spacesd label or a published 3211); None when it does not say.

ImageBuild record#

Image layers built on top of a sandbox's image. Local: a build into the container engine (container images only; VM images take no layers here), cached by a content hash (cua-b-<hash>), so an identical spec never rebuilds.

FieldTypeDefaultDescription
layersVec<ImageLayer>[]Steps, in order.
envHashMap<String, String>[:]Image environment.
portsVec<u16>[]Ports the image exposes.
filesVec<BuildFile>[]Local files copied in.
timeout_ms / timeoutMsOption<u32>NoneBuild budget (default one hour).

ImageLayer enum#

One image build step (as in images.cua.ai/v1alpha1 recipes).

ImageLayer.APT_INSTALL(packages: List[str])
ImageLayer.PIP_INSTALL(packages: List[str])
ImageLayer.UV_INSTALL(packages: List[str])
ImageLayer.RUN(command: str)
ImageLayer.APP_INSTALL(app_id: str)
VariantDescription
AptInstallapt-get install. Fields: packages: Vec<String>
PipInstallpip install. Fields: packages: Vec<String>
UvInstalluv pip install. Fields: packages: Vec<String>
RunA shell command. Fields: command: String
AppInstallAn app from the cua catalog (VM images only). Fields: app_id: String

BuildFile record#

A local file copied into a built image.

FieldTypeDefaultDescription
sourceStringLocal path.
destinationStringAbsolute path in the image.

RegistrySecret enum#

Credentials for a private registry image, used for the pull. Never logged or persisted.

RegistrySecret.BASIC(username: str, password: str, registry: Optional[str])
RegistrySecret.FROM_ENV(username_var: str, password_var: str, registry: Optional[str])
RegistrySecret.AWS_ECR(region: Optional[str])
VariantDescription
BasicA user name and password (or access token). Fields: username: String, password: String, registry: Option<String>
FromEnvRead from environment variables of this process at create time. Fields: username_var: String, password_var: String, registry: Option<String>
AwsEcrA private Amazon ECR image: a login token from the AWS CLI (aws ecr get-login-password) with the caller's AWS credentials. Fields: region: Option<String>

canonical_image_tier#

The canonical image for os, version and tier: slim (the minimum that passes cua-spacesd doctor --strict; CI and benchmarks use it), full or None (the default, with dev tooling), on macOS xcode / xcode-<X.Y> (full plus one pinned Xcode) or, on Linux, docker (slim plus the Docker engine, a VM: -docker-disk). The tag is <os-version>[-<tier>] (ghcr.io/trycua/linux:24.04-slim); the resolver finds its -disk sibling. CUA_IMAGE_<OS> overrides only the default full image. Raises ImageNotPublished for a tier CI has not published yet, InvalidArgument for an unknown tier, xcode outside macOS or docker outside Linux.

def canonical_image_tier(os: str, version: Optional[str], tier: Optional[str]) -> str
ParameterTypeDefault
osStringrequired
versionOption<String>required
tierOption<String>required

Returns String · Raises CuaError (ImageNotPublished, InvalidArgument)

omarchy_image#

The Omarchy image, ghcr.io/trycua/omarchy:<channel> (default edge; also rc, stable): Omarchy (Arch Linux, Hyprland) with cua-spacesd, as an amd64 VM (QEMU locally, KubeVirt in the cloud; emulated on arm64 hosts). Raises ImageNotPublished until CI publishes the channel; pass the reference explicitly to use it before then.

def omarchy_image(channel: Optional[str]) -> str
ParameterTypeDefault
channelOption<String>required

Returns String · Raises CuaError (ImageNotPublished)

Pools#

A pool is sandboxes of one shape the cua daemon keeps ready on its machine: min at all times (one starts again as soon as one is taken), up to max while creates come faster than sandboxes start, and none after idle_ms without a create. A create with pool set to its name gets the pool's image and size and takes a ready sandbox. Without pools, the daemon keeps sandboxes ready only where repeated creates of a shape pay for it (cua daemon status says why). Pools need a daemon (Cua.connect) and run on this machine only (on = "local"); the CLI is cua sb pool.

Python programs usually use the high-level API instead: create_pool.

Pool methods#

Methods of Sandboxes.

Sandboxes.create_pool#

Creates a pool: sandboxes of image (and options' shape) kept ready on this machine by cua daemon, so that a create from the pool (SandboxCreateOptions.pool) takes one in about 0.1 s.

  • min: kept ready at all times; one starts again as soon as one is created from the pool.
  • max: the most kept ready (not counting those created from the pool); above min only while creates come faster than sandboxes start. Default: min.
  • idle_ms: after this long without a create from the pool it keeps none ready, until the next create (which starts on the default tier and refills it). Default: never.

Pools run on this machine (on = "local", the default). Without a pool, the daemon keeps sandboxes ready only where repeated creates of a shape pay for it; a pool asks for them explicitly. Creating a pool with the name of an existing one updates it.

async def create_pool(self, image: str, options: PoolCreateOptions) -> SandboxPool
ParameterTypeDefault
imageStringrequired
optionsPoolCreateOptionsrequired

Returns SandboxPool · Async · Raises CuaError

Sandboxes.get_pool#

Pool name, with what it holds now.

async def get_pool(self, name: str) -> SandboxPool
ParameterTypeDefault
nameStringrequired

Returns SandboxPool · Async · Raises CuaError

Sandboxes.list_pools#

Every pool, with what each holds now.

async def list_pools(self) -> List[SandboxPool]

Returns Vec<SandboxPool> · Async · Raises CuaError

Sandboxes.delete_pool#

Deletes pool name: its ready sandboxes go; sandboxes created from it stay. false when there was none.

async def delete_pool(self, name: str) -> bool
ParameterTypeDefault
nameStringrequired

Returns bool · Async · Raises CuaError

PoolCreateOptions record#

What a pool's sandboxes are and how many it keeps ready (Sandboxes.create_pool). The shape fields mean what they mean in SandboxCreateOptions.

FieldTypeDefaultDescription
nameOption<String>NonePool name (lower-case letters, digits and -). None: a new name. The name of an existing pool updates it.
onOption<String>NoneWhere its sandboxes run: local (the default; the only location with pools today).
kindOption<String>NoneWhat kind of machine: auto, container, vm or microvm.
runtimeOption<String>NoneWhich engine: auto or one the location offers for the kind.
osOption<String>NoneGuest OS (linux, macos, windows).
cpusOption<u32>NonevCPUs of each sandbox.
memory_mb / memoryMbOption<u64>NoneMemory of each sandbox (MiB).
envHashMap<String, String>[:]Guest environment.
portsVec<u16>[]Extra guest ports to publish.
servicesHashMap<String, u16>[:]Named services (name → guest port).
commandOption<Vec<String>>NoneThe sandboxes' command (argv), replacing the image's entrypoint (as SandboxCreateOptions.command).
headlessboolfalseSandboxes without a desktop (as SandboxCreateOptions.headless).
minu321Sandboxes kept ready at all times (refilled right after each create from the pool).
maxOption<u32>NoneThe most kept ready, not counting those created from the pool (default: min).
idle_ms / idleMsOption<u64>NoneAfter this long without a create from the pool it keeps none ready, until the next create (default: never).

SandboxPool record#

A pool (Sandboxes.create_pool).

Returned by Sandboxes.create_pool, Sandboxes.get_pool, Sandboxes.list_pools.

FieldTypeDefaultDescription
nameStringName.
imageStringImage as given.
locationStringWhere its sandboxes run (local).
kindStringKind and runtime as given (empty: auto).
runtimeString
cpusu32Each sandbox's CPUs and memory (MiB).
memory_mb / memoryMbu64
minu32Sandboxes kept ready at all times, and at most.
maxu32
idle_ms / idleMsOption<u64>After this long without a create it keeps none ready (None: never).
readyu32Ready now, and starting.
startingu32
statusStringWhy it holds what it holds, or why it cannot.

Create options#

Sandboxes.create takes one SandboxCreateOptions. Every field means the same thing locally and in the cloud; on picks where the sandbox runs, kind and runtime what runs it.

Python programs usually use the high-level API instead: Sandbox.create parameters.

SandboxCreateOptions record#

Options for Sandboxes.create.

FieldTypeDefaultDescription
onOption<String>NoneWhere it runs: local, direct:<addr> (an existing machine running cua-spacesd) or a registered provider. None (the default): the user default (default.on in ~/.cua/config.toml, CUA_DEFAULT_ON, else local). cloud fails with the "Cua Cloud has ended" error.
kindOption<String>NoneWhat kind of machine: auto, container, vm or microvm. None: the user default (default.kind, else auto: macOS and Windows images are VMs, an image with a container rootfs is a container, a disk-only image is a VM).
runtimeOption<String>NoneWhich engine: auto or one the location offers for the kind (local gvisor, runc, qemu, lume). None: the user default (default.runtime, else auto, the safest available). A local sandbox with sidecars needs runc where gVisor would run. A combination that does not exist is InvalidPlacement, listing the valid values.
imageString""Image reference. A pool:<name> image fails with the "Cua Cloud has ended" error.
nameOption<String>NoneName. None: ephemeral (no state file; deleted with the sandbox).
tokenOption<String>Nonespacesd token.
poolOption<String>NoneCreate from this pool: locally, a pool made with Sandboxes.create_pool (the sandbox gets the pool's image and shape and takes one of its ready sandboxes in about 0.1 s; image may be left empty).
osOption<String>NoneGuest OS (linux, macos, windows).
cpusOption<u32>NonevCPUs.
memory_mb / memoryMbOption<u64>NoneMemory (MiB).
portsVec<u16>[]Extra guest ports (local: published).
servicesHashMap<String, u16>[:]Named services (name → guest port). env defaults to 3211.
wait_for / waitForVec<ReadinessProbe>[]Readiness probes.
ready_timeout_ms / readyTimeoutMsOption<u32>NoneReadiness budget (default 10 min).
envHashMap<String, String>[:]Guest environment (local: container environment or cloud-init; values are not secrets).
ttl_seconds / ttlSecondsOption<u32>NoneLifetime backstop in seconds: the platform deletes the sandbox this long after it stops being kept alive (a provider sandbox such as on = "e2b": its lifetime). None: the platform's default.
commandOption<Vec<String>>NoneThe sandbox's command (argv), replacing the image's entrypoint. Same meaning local (container ENTRYPOINT, or run by cloud-init in a Linux VM) and in the cloud (the template command with processMode: Run, on gVisor and KubeVirt).
sidecarsVec<Container>[]Sidecar containers, addressed by name (see Container).
registry_secret / registrySecretOption<RegistrySecret>NoneCredentials for a private image (and sidecar images on its registry).
buildOption<ImageBuild>NoneImage layers built on top of image (a build into the local container engine, cached by content).
networkOption<String>NoneGuest network: "default" (unset) gives outbound network, like a Docker container; "none" cuts it while published ports still work. Only local QEMU VMs honour "none"; containers and Lume reject it.
overlaysVec<Overlay>[]Binaries to inject once the sandbox is up, so tests run the build under test and not the copy the image bundles (see Overlay; the same as calling Sandbox.overlay after create). Needs cua-spacesd in the image, or a local container.
keep_on_failure / keepOnFailureboolfalseKeep a named sandbox whose readiness check fails (its VM or container, and its record) to debug it. false (the default): a failed create deletes what it made. Ephemeral sandboxes are always deleted.
gpuOption<String>NoneA GPU option of the runtime it runs on (Spaces.gpu_support lists them): paravirtual (a macOS VM on Lume: GPU acceleration, experimental), virgl (QEMU on Linux), nvidia (a runc container on Linux), a contrib provider's GPU type; auto picks the runtime's own. None (the default): no GPU.
headlessboolfalseA Space without a desktop: only cua-spacesd runs (exec, files, processes, MCP), with no display, window manager or audio. For shell and RL workloads it starts several times faster and fits many more per machine. Images without cua-spacesd are unaffected; a command of your own is kept.
spacesdOption<bool>NoneWhether an image without cua-spacesd gets a static one injected, so any OCI image is a full Space (local containers and microVMs: exec, files, ports). None (the default): yes. Some(false) runs the image as it is.
profileOption<String>NoneA size profile: defaults for what is left unset. "rollout": 1 vCPU, 1024 MiB and headless (a local VM gets no display hardware, so many more fit on one machine), for RL rollouts and agent episodes that mostly wait. None or "default": 2 vCPUs, 4096 MiB.
forkableOption<bool>NoneA fork source (a "bake" sandbox): a local QEMU VM's guest RAM is a shared file, so its checkpoints take milliseconds and forks of them share its pages (Sandboxes.checkpoint, Sandboxes.fork). Other kinds ignore it. None (the default): not one.

ReadinessProbe record#

A user-declared readiness probe. With no probes a sandbox is ready as soon as its provider reports it running; nothing assumes a guest daemon.

Name a declared service (service = "mcp") or a guest port.

FieldTypeDefaultDescription
portu160Guest port (0 with service).
http_path / httpPathOption<String>NoneHTTP path; None is a TCP connect probe.
http_status / httpStatusOption<u16>NoneExact HTTP status to wait for; None accepts any 2xx.
serviceOption<String>NoneA declared service whose guest port to probe (instead of port).

Container record#

An extra container next to a sandbox (a compose-style sidecar), addressed by name on every runtime: the sandbox reaches it at its name (on its ports), it reaches the sandbox at main, and services may name its ports ({"db": 5432}). Local containers run it in the sandbox's network namespace (localhost works too; needs runtime="runc"). Local VM sandboxes refuse sidecars. With sidecars the service names main, sidecars and sc are reserved.

FieldTypeDefaultDescription
imageStringImage reference.
commandOption<Vec<String>>Noneargv replacing the image's entrypoint.
envHashMap<String, String>[:]Environment (plain values, not secrets).
portsVec<u16>[]Ports it listens on.
nameOption<String>NoneName, unique within the sandbox, and its hostname (not main). Unset: from the image (redis).