Agent Sandbox Registry

python-sdk

Sandbox Lifecycle

docs/en/explanation/sandbox-lifecycle.md

Sandbox Lifecycle

This document explains the complete sandbox lifecycle, state transitions, and timeout mechanisms.


State Model

The sandbox lifecycle is represented by the SandboxStatus enum:

class SandboxStatus(str, Enum):
    CREATING = "creating"   # Being created
    RUNNING  = "running"    # Running
    PAUSED   = "paused"     # Paused
    STOPPING = "stopping"   # Shutting down
    STOPPED  = "stopped"    # Stopped
    ERROR    = "error"      # Error

State Transitions

stateDiagram-v2
    [*] --> CREATING : create()
    CREATING --> RUNNING : Container ready
    RUNNING --> PAUSED : pause
    PAUSED --> RUNNING : resume
    RUNNING --> STOPPING : kill
    PAUSED --> STOPPING : kill
    STOPPING --> STOPPED
    STOPPED --> [*]

    CREATING --> ERROR
    RUNNING --> ERROR
    PAUSED --> ERROR
    STOPPING --> ERROR

    note right of ERROR : Any state can transition here

Normal Flow

  1. CREATING → RUNNING: Sandbox.create() calls the Platform API to create a container; status becomes RUNNING once the container is ready
  2. RUNNING → PAUSED: sandbox.pause() pauses the sandbox
  3. PAUSED → RUNNING: sandbox.resume() resumes execution
  4. RUNNING → STOPPING → STOPPED: sandbox.kill() destroys the sandbox
  5. Any state → ERROR: An unrecoverable error occurs

Abnormal Flow


Timeout Mechanisms

Sandbox Timeout

Each sandbox has a timeout value (in seconds); the sandbox is automatically destroyed when it expires.

# Set at creation time
sandbox = await Sandbox.create(timeout=600)  # 10 minutes

# Update at runtime
await sandbox.set_timeout(1200)  # Extend to 20 minutes
Parameter Range Default
timeout 1 – 86400 (1 second – 24 hours) 300 (5 minutes)

Command Timeout

# commands.run() defaults to 60 seconds
result = await sandbox.commands.run("command", timeout=120)

# run_code() defaults to 30 seconds
result = await sandbox.run_code("code", timeout=60)

CLI Timeout

# Global default timeout
abx --timeout 600 create

# Command-level timeout
abx exec sbx-xxxx "command" --timeout 120

Context Manager Lifecycle

When using async with, kill() is automatically called on exit:

async with await Sandbox.create() as sandbox:
    # sandbox status: RUNNING
    result = await sandbox.run_code("print(1)")
# Exiting the with block → automatic kill()
# sandbox status: STOPPED

Cleanup occurs even if an exception is raised:

try:
    async with await Sandbox.create() as sandbox:
        raise ValueError("error")
except ValueError:
    pass
# sandbox has been automatically destroyed

Checking Status

# Get cached status (no network request)
status = sandbox.status

# Make an API call to check actual status
is_running = await sandbox.is_running()

# Refresh full info
info = await sandbox.refresh_info()
print(f"Status: {info.status.value}")

SDK Property Freshness

Property Freshness How to Refresh
sandbox.id Immutable —
sandbox.status Snapshot at creation refresh_info()
sandbox.url Snapshot at creation refresh_info()
sandbox.info Snapshot at creation refresh_info()
sandbox.capabilities Resolved at creation Immutable

Next Steps