A provider backend answers one question: where should this bundle run? Remote calls decide which function runs. Bundles decide what code exists in the sandbox. Providers decide where the image is started and how it is cleaned up.

Use a Backend

The Docker backend is the local development path:
uv add agentix-provider-docker
In code, construct a provider, open a session with a SandboxConfig, and call remote directly on the returned live sandbox handle.
from agentix import SandboxConfig
from agentix.provider.docker import DockerProvider, DockerProviderConfig

provider = DockerProvider(DockerProviderConfig())
config = SandboxConfig(
    image="python:3.13-slim",
    bundle="/home/me/.cache/agentix/bundles/sha256-...",
)

async with provider.session(config) as sandbox:
    result = await sandbox.remote(run, input="hello")
provider.session(...) creates the sandbox on entry, closes the runtime connection, and deletes the container on exit. For manual lifecycle control, create and delete the sandbox yourself:
sandbox = await provider.create(config)
try:
    result = await sandbox.remote(run, input="hello")
finally:
    await sandbox.aclose()
    await provider.delete(sandbox.sandbox_id)
Host-side plugin namespaces register on the sandbox before the first remote call:
async with provider.session(config) as sandbox:
    sandbox.register_namespace(MyHostNamespace())
    result = await sandbox.remote(run, input="hello")
For plugin-agnostic code where the backend name comes from config or an environment variable, look the provider class up by name through the registry instead of a concrete import:
import os
from agentix import providers

ProviderClass = providers().get(os.environ["AGENTIX_PROVIDER"])
provider = ProviderClass()
To discover what is installed, from agentix import providers; providers().all() returns {name: ProviderClass} for every registered backend. If the bundle was built for a non-default architecture, pass the same Docker/OCI platform so the task image and runtime overlay match:
config = SandboxConfig(
    image="python:3.13-slim",
    bundle="/home/me/.cache/agentix/bundles/sha256-...",
    platform="linux/amd64",
)

Backend Plugins

SandboxProvider packages register classes in the agentix.provider entry point group.
pyproject.toml
[project]
name = "agentix-provider-fly"
version = "0.1.0"

[project.entry-points."agentix.provider"]
fly = "my_provider:FlyProvider"
After installation, the backend name becomes available through the registry:
from agentix import providers

FlyProvider = providers().get("fly")

Backend Protocol

Backends subclass SandboxProvider, implement three async methods, and inherit session().
my_provider/__init__.py
import os

from agentix import Sandbox, SandboxConfig, SandboxId, SandboxInfo
from agentix.provider.base import SandboxProvider


class FlyProvider(SandboxProvider):
    def __init__(self) -> None:
        self._token = os.environ["FLY_API_TOKEN"]

    async def create(self, config: SandboxConfig) -> Sandbox:
        ...

    async def delete(self, sandbox_id: SandboxId) -> None:
        ...

    async def get(self, sandbox_id: SandboxId) -> SandboxInfo:
        ...
Most backends construct with no arguments, reading API keys, regions, and templates from environment variables so CLI and code paths behave the same way. A backend MAY accept its own config object — e.g. DockerProvider(DockerProviderConfig(container_engine="podman")) selects the container runtime, network, GPU args, and so on. Backend-neutral settings (image, bundle, env, resource) belong in SandboxConfig, not the backend.

Configuration

VariableUsed byPurpose
AGENTIX_BIND_PORTruntime serverSandbox-side bind port, default 8000
DAYTONA_API_KEYdaytona backendAPI authentication
E2B_API_KEY / E2B_TEMPLATE_IDe2b backendAPI authentication and template selection
The daytona and e2b backends are placeholders today: they validate configuration but their lifecycle methods raise NotImplementedError pending integration. docker/podman, apptainer, and uv are the working backends. The uv backend materializes the runtime from a local uv venv with no container — no isolation, but the fastest path to run the runtime/RPC stack on a bare host for local dev, CI, or trusted eval (see plugins/providers/uv/README.md). Fail fast in __init__ when required configuration is missing. The error should surface before the backend starts creating infrastructure.

Boundary

SandboxProvider backends should not know about agent wrappers, dataset scorers, or remote-call targets. They only stage bundles, start sandboxes, and return the runtime endpoint.