Skip to main content

Antioch simulation SDK

antioch-sim is the typed Python SDK and command-line interface for running Isaac simulations on warm Antioch GPU machines. Write ordinary Python on your computer. The remote simulation image supplies Isaac, so no local simulator or GPU is required.

The public wheel contains the antioch API, the CLI, shared models, and the supported Isaac typing surfaces. The public preview uses the Antioch staging service and requires Python 3.12.

Quick start

Install uv if it is not already available:

curl -LsSf https://astral.sh/uv/install.sh | sh

In an empty directory, create a Python 3.12 project and choose one engine:

uv init --bare --python '>=3.12,<3.13'
uv python pin 3.12
uv add --compile-bytecode "antioch-sim[isaac-601-ga]"
export ANTIOCH_ENV=staging
uv run antioch auth login
uv run antioch init
uv run antioch run src/main.py

The login command prints a short code and a URL to open in a browser. The run command allocates or reuses a GPU machine, starts the generated Isaac Sim 6.0.1 example, relays its output, and prints a Mission Control link for its stream.

Use antioch-sim[isaac-lab-30b2] instead to create an Isaac Lab 3.0.0-beta2 project. Choose exactly one engine extra per project. In an existing Python project, skip uv init and uv python pin.

Install the SDK

The engine extra selects the image and examples that antioch init writes. The wheel already contains every supported typing surface. uv.lock pins the SDK and its third-party dependencies for repeatable installs. Isaac itself is not a Python dependency and is not installed on your computer.

antioch init creates local files only. It does not allocate a machine, register a remote project, or replace existing source. If a package manager does not save the extra in pyproject.toml, select the engine explicitly:

uv run antioch init --engine isaac-601-ga

Activate .venv if you want to omit uv run:

source .venv/bin/activate
antioch --help

Mission Control already includes the authenticated CLI and example projects, so its hosted workspace does not need a local SDK installation.

Update a project

Refresh the SDK version in the lock file and reinstall the environment:

uv lock --upgrade-package antioch-sim
uv sync --compile-bytecode
uv run antioch --version

For an existing project, also change services.sim.image in antioch.yaml to the engine and SDK version that the new lock selected. For example:

services:
  sim:
    image: antioch-sim/isaac-601-ga:0.3.32

If the project has a Dockerfile, update its matching FROM coordinate. The SDK and remote image must use the same version. Do not run antioch init again over an existing project.

Remove the SDK

uv remove antioch-sim

This removes the dependency from the Python project. It does not delete source, antioch.yaml, recorded scenarios, or remote assets. Run antioch auth logout before removal if you also want to remove the local login.

Complete commands in your shell

Every command, subcommand, option, and enumerated value completes on Tab. Add the line for your shell to its startup file:

# ~/.bashrc
eval "$(_ANTIOCH_COMPLETE=bash_source antioch)"
# ~/.zshrc
eval "$(_ANTIOCH_COMPLETE=zsh_source antioch)"
# ~/.config/fish/completions/antioch.fish
_ANTIOCH_COMPLETE=fish_source antioch | source

Completion resolves the one command being typed, so it stays as fast as the CLI itself.

Sign in

Sign in with antioch auth login. The CLI prints a short code and confirmation URL that you can open in any browser, so the flow also works over SSH. Signing in again replaces the active session. antioch auth whoami displays the active user and organization, while antioch auth switch selects another available organization. The CLI stores the login securely under ~/.config/antioch and shares it across projects. antioch auth logout removes the local login and machine access from this computer.

Your first script

antioch init creates local files only; it does not register a remote project, allocate a machine, or replace existing source. It creates a src-layout project with a visible example simulation, repeatable scenarios, and smoke and sweep suites. For Isaac Sim, generated src/main.py rains colored cubes onto a ground plane; for Isaac Lab it drives a cartpole. Both step physics and render for 30 seconds by default. Run the local file on a remote machine with:

antioch run src/main.py

The generated simulation keeps the Isaac viewport responsive long enough to watch the motion. Streaming is on by default; pass --no-stream for a headless run. antioch.boot() consumes that process-scoped declaration wherever it is called in the program. Before Isaac starts, the command prints a Mission Control link for each machine so you can watch its livestream. The target remains ordinary Python: it can use native Isaac APIs, parse arguments, and control when Isaac starts. Arguments after -- reach the script unchanged; stdout, stderr, and the exit code remain the process's own.

run starts one finite process on one machine; --machine pins which one. Ctrl-C signals that exact process gracefully first, and a second Ctrl-C force-kills only it. Native programs can tune render fidelity directly:

import antioch

antioch.boot(render_quality="quality", viewport=(1920, 1080))

render_quality picks a DLSS fidelity preset from "performance" through "ultra"; viewport sets the main non-streamed render target. Leave either unset to keep its default. Streaming stays a launch concern: it is on by default, while --no-stream opts out; the runtime chooses a safe initial encoder target, and the connected browser takes over dynamic sizing. Simulation code does not configure transport policy.

Antioch does not override Isaac or Kit logging by default, so output matches the selected engine's native behavior. Set a level only when you deliberately want to change that behavior:

antioch.boot(log_level="error")  # or "fatal" / "warning" / "verbose"

For decorated scenarios, antioch scenario run keeps its concise live board while antioch scenario run --verbose relays the informational process output.

Your first scenario

A scenario turns a script into a named, repeatable simulation: decorate a function with @antioch.scenario and Antioch can collect it, set its parameters, run it across many machines, and save its source hash, parameters, results, and telemetry. antioch scenario run collects every scenario under the manifest's explicit scenario_paths, or the sim build-context discovery scope when that field is omitted, and runs the selection on one project machine by default. Pass --machines N or repeat --machine to fan out explicitly:

When scenario_paths is omitted, the sim build context is scanned recursively. The default boundary skips hidden directories, virtualenvs (directories with pyvenv.cfg), node_modules, common cache/build directories, and paths matched by the context's .gitignore or .dockerignore. Use scenario_paths when a project needs a narrower or different source scope.

antioch scenario run                        # every scenario in the project
antioch scenario run --scenario falling_cube --set drop_height=4
antioch scenario run --scenario falling_cube --case resting
antioch scenario run --scenario falling_cube -t smoke
antioch scenario run --scenario falling_cube --scenario cartpole_balance
antioch scenario run -t physics --exclude-tag slow
antioch scenario run -t physics -t nightly      # repeat -t for a union of tags
antioch scenario run --path src/physics     # discover somewhere other than the manifest
antioch suite run nightly        # named suite from antioch.yaml
antioch scenario run                        # livestream by default
antioch scenario run --no-stream            # headless run

The CLI prints the console URL to watch each machine on before it dispatches, because the window worth watching is the run itself. The stream server needs roughly fifteen seconds of engine boot before it accepts a viewer, so a scenario that finishes in under half a minute is largely over by the time the first frame arrives — give a run you intend to watch something to do.

A scenario receives its run as the first argument. Use that run to save results and artifacts, and to report the outcome. Annotating it is what makes the handle discoverable in an editor; the SDK supplies that one name when it reads your signature, so a module with from __future__ import annotations can leave ScenarioRun behind if TYPE_CHECKING: rather than importing it at runtime.

import antioch

logger = antioch.Logger("cube")


@antioch.scenario(tags=["physics"], sim=antioch.BootProfile(physics_dt=1 / 240), cases=[antioch.case({"drop_height": 0.0}, id="resting", tags=["edge"])])
def falling_cube(run: antioch.ScenarioRun, drop_height: float = 2.0) -> None:
    world = antioch.world()
    ...
    logger.scalar("height", z)  # -> entity path "cube/height"
    run.add_result("final_z", z)
    run.add_artifact(output / "trace.csv")
    run.check("came to rest", z < 0.4, detail=f"rested at {z:.3f} m")

sim= declares what the scenario needs to be correct — physics and render steps, render fidelity, Isaac log severity, the PhysX/Newton backend, and native Kit arguments. How you watch a run (streaming is default; --no-stream and --verbose stay on the CLI). --verbose changes whether process bytes are relayed live; it never changes which bytes Isaac emits.

For a supported frame from the active viewport, aim Kit's USD camera with set_camera_view(...), step the world, and call antioch.capture_viewport(). It returns an RGB-compatible array or None when no active viewport exists. The legacy isaacsim.sensors.camera.Camera path is blocked on Isaac Sim 6.0.1 because its second render product can hang World.step(render=True); use the active viewport helper or the experimental RTX camera APIs instead. Newton is opt-in with antioch.BootProfile(physics_engine="newton") and is not available on Isaac Lab images.

Omit sim to use the default Kit profile. Pass sim=None when the scenario does not need a simulator at all; the runner still records its result and telemetry, but it does not boot Kit. Use --no-stream for these runs because there is no simulator viewport to stream.

A Logger is a channel prefix and nothing else, created once at module scope like logging.getLogger — it captures no run, so the same instance serves every run the process executes. Its text always reaches the terminal and additionally reaches the recording whenever a run is active, so a helper shared between a scenario and a standalone script logs correctly in both. Results belong to the run, not the logger. antioch.current_scenario_run() reaches the run from an imported helper that cannot take it as an argument.

run.check(criterion, passed, detail=...) is how a scenario says what its task was and whether it was done. Every check is recorded and measured — a failing one does not stop the body — and a run that fails any check finishes FAILED, so the outcome is the task's outcome rather than a proxy for whether the process survived. Reach for assert or run.fail only where the run genuinely cannot continue.

The ScenarioRun handed to a decorated scenario is the whole authoring surface: it saves what that scenario produced and cannot start, stop, or finalize unrelated processes. Raw antioch run, direct exec, and notebook processes do not save structured results; author a scenario when results must be retained and reviewed.

Durable outputs for long runs

Plain antioch run output and files under /workspace/output are machine-local scratch. They are not a durable process record and disappear when the machine is released. For training or dataset generation, make the work a scenario and register each checkpoint with the existing scenario artifact seam:

from pathlib import Path

import antioch


@antioch.scenario(tags=["training"])
def train(run: antioch.ScenarioRun, steps: int = 10_000) -> None:
    """Train a model and retain checkpoints as scenario artifacts."""

    output = Path("/workspace/output/checkpoints")
    output.mkdir(parents=True, exist_ok=True)
    for step in range(steps):
        # Run one training step and write a complete checkpoint atomically.
        if step % 100 == 0:
            checkpoint = output / f"step-{step:06d}.ckpt"
            checkpoint.write_bytes(b"checkpoint bytes")
            run.add_artifact(checkpoint, name=f"checkpoints/{checkpoint.name}")

Run and retrieve it with antioch scenario run --scenario train, then antioch scenario download SCENARIO_RUN_ID. Each successful run.add_artifact(...) upload is retained in the scenario run even if the machine is later killed or reaped. A direct antioch services cp sim:/workspace/output/FILE ./FILE is an immediate copy for a plain run; it does not replace scenario artifact registration.

Scalars you log land in the scenario run's Rerun recording. Managed scenarios and native ScenarioSession runs also sample Kit's existing active viewport every 0.5 seconds of simulation time, logging JPEG frames to /antioch/viewport at up to 640 pixels wide and capped at 600 frames. An authored camera can keep using /viewport; the platform read-back has its own path so the two writers never interleave. Capture does not create or frame a camera; set the active viewport camera in simulation code when composition matters. A run that never steps a simulator simply has no platform viewport entity. Use @antioch.scenario(capture=False) or ScenarioSession(..., capture=False) to opt out; batch suites can disable the default globally with ANTIOCH_TELEMETRY_CAPTURE=0.

The recording is finalized with an automatic Rerun blueprint: /antioch/viewport is shown in a spatial view, each logged scalar gets a time-series view, and three-dimensional entities get a spatial view. To choose the layout yourself, call the one canonical setter while the run is active; it suppresses the automatic layout and is stored in the downloaded RRD as well as the live viewer:

import rerun.blueprint as rrb


@antioch.scenario()
def falling_cube(run: antioch.ScenarioRun) -> None:
    run.set_blueprint(rrb.Blueprint(rrb.TimeSeriesView(origin="/cube/height")))
    ...

To inspect the installed 0.36.0 reader's blueprint store in a downloaded RRD, use rerun.experimental.RrdReader("run.rrd").blueprints(); the same reader's stream(store=...) exposes the logged entities and their time columns.

The webapp renders that recording on the scenario-run detail page, where results, telemetry, logs, and artifacts remain grouped under the authored run.

Every reusable parameter variation is an addressable case, and antioch.case(...) is its only spelling. One declaration can be a singleton, a Cartesian grid, or correlated combinations; all three expand locally into the same flat case catalog:

@antioch.scenario(
    cases=[
        antioch.case(id="default", tags=["smoke"]),
        antioch.case({"drop_height": 0.0}, id="resting", tags=["edge"]),
        antioch.case({"capture_batches": 100}, grid={"seed": range(50), "friction": [0.3, 0.8]}, id="seed-{seed}-mu-{friction}", tags=["production"]),
        antioch.case(combinations=[{"mass": 1.0, "speed": 2.0}, {"mass": 4.0, "speed": 0.5}], id="mass-{mass}-speed-{speed}"),
    ],
)
def falling_cube(...): ...

The positional mapping holds one case's values, or values shared beneath a grid/combinations expansion. Grid axes follow scenario-signature order and authored value order. An omitted id derives from the explicit values; an id on any case is a format template over resolved parameters, and one without braces is unchanged. A scenario with no cases= contributes one implicit default run. Once it declares cases, it runs exactly those cases—add antioch.case(id="default") when defaults should remain in the catalog. Select one or more with repeated --case, a family with -t edge, and see the expansion with antioch scenario collect --json.

Suites are immutable unions of exact selector clauses. Clauses are ORed; fields inside one clause are ANDed; values in paths, scenarios, and cases are exact alternatives. Required and excluded tags read the union of scenario and case tags:

suites:
  acceptance:
    description: "Warehouse acceptance"
    select:
      - paths: ["scenarios/safety"]
        tags: ["smoke"]
        exclude_tags: ["slow"]
      - scenarios: ["falling_cube"]
        cases: ["resting", "extreme"]

Overlapping clauses produce one scenario run at the first matching position, and each clause must match at least one case so a typo cannot silently shrink a suite.

antioch scenario collect inspects authored definitions entirely locally, and antioch suite collect expands every declared suite to the exact scenario files and cases it would run. scenario list, show, logs, delete, and suggest use the scenario surface; suite run, list, summary, show, and cancel use the distinct suite surface. If a deployment includes runs from an earlier Antioch version, the same commands include those runs and identify them as legacy. Use Settings in the webapp to show or hide legacy data for the account. Each run shows only the actions that it supports, such as deletion, rerun, or output retrieval. Scenario decorators can override catalog names and descriptions, carry a Rerun blueprint, opt out of default viewport capture with capture=False, and declare validated case catalogs. Prefer run.set_blueprint(...) when a layout depends on what the scenario actually logged. Scalar parameters support descriptions and inclusive numeric bounds through antioch.param; Literal[...] annotations become closed CLI choices. A plain scenario selection expands every declared case. --case selects one or more declared cases by id; repeat the option to select several. --set with an exact scenario creates one ad-hoc run from its defaults. The two modes cannot be combined. Named suites remain immutable.

The history commands keep the webapp's full operational query surface while adding script-oriented filters. Both scenario and suite histories filter by project, member, phase, outcome, time, and interactive or queued dispatch; scenario history additionally filters exact scenario and invocation ids, suite membership, tags, params, and results. Repeat --phase or --outcome on scenario list to select a union of display states. Every list cursor pins that exact query, so continuation commands pass only --cursor and --limit.

antioch scenario show SCENARIO_RUN_ID prints results and every named output. Retrieve one output or the complete set directly from object storage with:

antioch scenario download SCENARIO_RUN_ID --artifact telemetry
antioch scenario download SCENARIO_RUN_ID --artifact metrics/probe.csv -o output/
antioch scenario download SCENARIO_RUN_ID -o output/  # every artifact

Legacy outputs use the same command even when the older stack recorded no size or digest. A legacy suite invocation id is only unique inside its suite, so open it with antioch suite show SUITE_RUN_ID --suite NAME.

Queued runs

--queue builds or resolves the selected Docker-backed services on the submitter's assigned machine, adds the current project source to the simulation image, and pushes the digest-pinned environment to your organization's private registry. antioch suite run NAME --queue stores one suite run plus all of its scenario children, while antioch scenario run --queue stores standalone scenario runs. Queued fan-out draws on the same per-user machine quota as interactive work, and Antioch distributes children fairly across eligible warm machines:

antioch suite run nightly --queue
antioch suite show SUITE_RUN_ID --follow
antioch suite cancel SUITE_RUN_ID
antioch suite rerun SUITE_RUN_ID
antioch scenario run --tag smoke --queue
antioch scenario cancel SCENARIO_RUN_ID
antioch scenario rerun SCENARIO_RUN_ID

Queued runs save their exact digest-pinned environment before Antioch distributes them. For a single-machine interactive run, Antioch captures the admitted sim container's project workspace at dispatch and then attempts to save the exact images and source the run used. When that capture and publish succeeds, scenario rerun and suite rerun create fresh queued runs with the same environment, parameters, and cases. They do not change the original run. Multi-machine interactive runs are not currently rerunnable. Repeat the original command or use --queue when the result must be rerunnable. Antioch explains when an older run or a failed source capture or publish leaves the environment unavailable.

--follow reports the state it finds on connect and then every change, so a suite waiting on capacity says so instead of going quiet. There is no estimated finish time, because the fleet cannot honestly predict one. A followed suite is a stream rather than a document, so --follow --json emits line-delimited frames: one state frame per observed state and a final completed frame carrying the suite-run view. Without --follow, --json remains the single indented document it has always been.

Every finite history command supports --json. Every paged response — each list and suite summary — uses the same {"items": [...], "next_cursor": "..."} shape; pass next_cursor back with --cursor and do not repeat filters, because the opaque token carries the original query. Every *_at field in JSON is a Unix timestamp in microseconds; humanized clock labels stay in human tables. Repeatable filters are unions, while repeating a scalar option is a usage error. JSON failures are written to stderr as one error object with a stable type, exit code, HTTP status when the server answered, and retryable. Interactive terminals keep raw stdout/stderr or print destination paths, and their help names that exception. Finite file transfers accept --json and return a manifest with the destination, byte count, checksum, and replacement fact. Scenario and suite history commands use a customer-facing projection. Their JSON keeps run identity, suite and project links, dispatch provenance, authored inputs, lifecycle state, outcomes, timings, results, logs, artifacts, and capability flags. It omits tenant keys, raw user subjects, queue claims, assignment and process identities, attempt counters, and generation data. See the Antioch agent plugin JSON reference for the shared contract; use each command's --help for its current flags and payload.

Versioned assets

Assets are immutable named file revisions shared across the active organization. antioch assets push, list, show, pull, and repair expose the asset library in the CLI. Authenticated Python tools can use the same signed direct-storage path:

from antioch import load_asset, save_asset

asset = save_asset("robots/commissioning-arm", version="v1", source="robot.usda", description="Validated commissioning geometry")
prim = load_asset(asset.name, prim_path="/World/CommissioningArm", version="v1")

Saves always land in the current organization's store. Loads resolve against one asset library — organization assets, Antioch's shared assets, and the legacy stack, with a current asset shadowing a legacy one of the same name. Antioch transfers asset bytes directly to object storage, and the client verifies the stored size and SHA-256 before publishing the local destination atomically. A legacy revision has neither, because the legacy stack recorded neither, so its bytes are checked against the provider's declared length alone.

Choosing an engine

A project selects its engine with an image coordinate: antioch-sim/<engine>:<sim-version>. antioch init detects the installed engine extra and stamps that coordinate into an image-first antioch.yaml; edit it to upgrade. The platform reads runtime engine identity and SDK version from the image's labels. Add a Dockerfile only for custom dependencies and use the same coordinate in its FROM line; saved run environments pin the resulting image by digest.

The public antioch-sim wheel includes the supported engine typing surfaces. The declared extra selects the initial scaffold and is locked in uv.lock:

dependencies = ["antioch-sim[isaac-lab-30b2]"]

Antioch's own building blocks state which engines they support, because the engines genuinely differ: some are Isaac Lab APIs with no Isaac Sim equivalent, and some need a minimum release. Using one outside its support says so directly rather than failing somewhere deep inside Isaac:

wrap_task_env requires Isaac Lab 3.0+ but this image runs Isaac Sim 6.0.1
('isaac-601-ga')

Support only widens: a component that works on an engine keeps working on later releases of it, and new engines are added without changing your code.

Base image inventory

The published engine image is the base for a project Dockerfile. The isaac-601-ga core starts from Ubuntu 24.04 and includes the Isaac Sim 6.0.1 runtime, Python 3 with pip, venv, and development headers, uv, git, and git-lfs. It also includes the runtime graphics and audio libraries that Kit needs: Vulkan and vulkan-tools, GL/EGL/GLES/GLVND, X11, and audio support. The Isaac Sim layer carries the in-process ROS 2 Jazzy Python stack. The isaac-lab-30b2 layer adds Isaac Lab 3.0.0b2 and its pinned framework extras.

This is a runtime inventory, not a promise of a general build workstation. The base does not include gcc/g++ or build-essential, the FFmpeg command line tool, graphics development headers, the full ROS 2 command-line and message-build toolchain, or project-specific system packages. Install those in the project Dockerfile when the project needs them. Verify an image that you changed with antioch services exec sim command -v TOOL before dispatch.

The FROM antioch-sim/<engine>:<sim-version> line is the cache boundary. A coordinate change invalidates the engine and every project layer. A changed apt-get or uv instruction rebuilds that instruction and the layers after it; a changed source COPY rebuilds only the later project layers. Keep slow, stable system dependencies before source copies. Watch sync updates source without rebuilding, while a queued or saved run freezes the final image by digest.

Configure project services

antioch.yaml owns the complete project stack: one required services.sim entry and auxiliary services in that same mapping; a top-level sim is not valid. schema_version is optional and defaults to the latest schema, and streaming is a runtime choice rather than a manifest stream key. The sim image coordinate pins the engine and SDK version; edit it to upgrade. Add build only when a Dockerfile is needed for custom dependencies, and make its FROM line that coordinate. Declare dependencies, environment, health checks, watch rules, and authenticated ports on those service blocks. Docker runs underneath Antioch through the Engine API. The CLI supplies GPU access, init, restart policy no, and the output bind; host networking and IPC default to host mode, with explicit supported network_mode and ipc values available as opt-outs. See the Compose file reference for the kept field vocabulary.

Start a foreground development session with antioch services up --watch. It builds, health-gates, watches, and keeps declared ports reachable at localhost while the stack is up. Ctrl-C ends the watch session but leaves containers and declared ports running; use antioch services down to stop everything. A bare antioch services up builds, health-gates the stack, opens its declared ports, then returns. Every finite dispatch reconciles the source it will run once before starting; it never silently executes stale source. A running watcher keeps the project services current for ordinary run, scenario, and suite dispatch; all share one stack even when that watcher is live. Whenever Antioch recreates a container, it reapplies the declared sync rules, so services up, services restart, an image change, and run --restart never leave /workspace/project empty while waiting for a watch session. services ps, services logs, and services down resolve the existing project and never allocate a machine. Development watch and tunnels are stripped when a scenario or suite enters the queue with an immutable, digest-pinned environment.

Private image: services use the local Docker config for an interactive pull. For queued work, the submitter pulls with that credential, pushes a digest-pinned copy into your organization's private registry, and saves that reference in the queued environment; workers and reruns need no third-party registry login. The staged sim image also bakes the exact submitted project tree at /workspace/project, because queued children run with no watch session to publish source.

Local runs, Jupyter, and machines

antioch run FILE is the local-first Python workflow. It prepares the healthy sim service when needed and starts one remote process with faithful output and exit status. antioch run executes your file inside the running sim container, next to whatever command: the service declares. A decorated scenario or suite saves results, telemetry, and artifacts. Use antioch services exec sim python for a raw diagnostic, antioch services ssh for a human shell, and antioch services cp sim:/workspace/output/result.png ./result.png for an explicit container transfer; all three resolve an existing assignment rather than allocating one. antioch services exec SERVICE CMD relays piped stdin to the selected service; use antioch services ssh for an interactive shell. Use antioch machine ssh for the VM shell. Docker runs underneath, so antioch machine ssh followed by raw docker ps, docker logs, or docker exec is supported for host-level diagnosis. The shell has no process identity, so work started there is not tracked or timed.

services cp follows Docker cp destination rules. A destination ending in / is a directory, and the source basename is placed under it; for example, antioch services cp ./payload sim:/workspace/output/ writes /workspace/output/payload/.... Without a trailing slash, the destination path receives the source contents, so ./payload copied to sim:/workspace/output/payload writes directly under that path. The service directory named by a trailing-slash destination must already exist.

antioch machine status prints the direct machine URL and, when available, the stream address. It also names Mission Control workspace when a workspace is holding the assignment. antioch machine list shows the same holder in its HOLDER column. This is an assignment hold, not a running-process count: the hosted Lab's cell-aware idle policy is deliberate, and its machine stays held until the workspace assignment is released. For captured stack output, use a focused service view such as:

antioch scenario show SCENARIO_RUN_ID --logs --service sim

antioch jupyter is the interactive surface, for people and for agents alike. One kernel-only Jupyter server runs in the project's sim container and every subcommand reaches it through one SSH forward, so a notebook and a coding agent drive the same warm Isaac. jupyter lab runs JupyterLab locally in gateway mode — notebooks, the editor, and Lab's terminal stay on your laptop while kernels and kernelspecs come from the machine. jupyter cell [CODE] runs one cell and exits, with --json for a structured result and a non-zero status when the cell fails. jupyter start, jupyter kernels, jupyter show, jupyter stop, jupyter stream, and jupyter unstream open a kernel and print its identity, list the machine's kernels, inspect one, end one, declare the one-per-machine livestream, and release that livestream. Declare a livestream before calling antioch.boot(); stopping that exact kernel releases its livestream. Repeating the same stream claim is idempotent. Sharing is explicit both ways: a command that finds several kernels refuses to guess, so a session that wants its own opens it with start and passes --kernel from then on.

Kernels outlive the command that made them, so the next cell lands on an Isaac that is already booted; an unattended idle kernel is culled and the machine then idles out normally. Restart replaces only that kernel and preserves the local notebook.

The machine lifecycle surface is list, status, checkout, release, and ssh. Container connections are under antioch services: services ssh opens /workspace/project in sim by default and services cp is the explicit transfer path. Use the machine lifecycle commands to choose or return assignments; they do not replace the service stack.

A project may hold several machines at once, and antioch machine checkout MACHINE says which of them single-machine commands use — the same idea as a checked-out git branch, and machine list marks it with *. Commands resolve an explicit --machine first, then the checked-out machine, then the project's sole assignment; holding several with none checked out is the one case they refuse to guess at. antioch machine checkout --none clears the choice, and releasing a machine clears it too.

Local source remains authoritative throughout the watch session. Write temporary checkpoints, frames, and debug files to $ANTIOCH_OUTPUT_DIR (/workspace/output), which is outside the project tree and disappears when the ephemeral VM is recycled. Retrieve a plain-run file before release with antioch services cp sim:/workspace/output/FILE ./FILE; that copy is not a durable record. Use the scenario artifact path above when output must survive machine loss. See antioch --help for the public command contract and the generated project for small authoring examples.

Troubleshooting

  • antioch is not found: use uv run antioch from the project, or activate .venv with source .venv/bin/activate.
  • Authentication is required or expired: set ANTIOCH_ENV=staging and run uv run antioch auth login again. Use uv run antioch auth whoami to check the active user and organization.
  • The project cannot select an engine: declare exactly one supported extra in pyproject.toml, then run uv sync. For a new project, you can also pass antioch init --engine isaac-601-ga explicitly.
  • The remote image version does not match the SDK: update services.sim.image in antioch.yaml and any matching Dockerfile FROM line to the version in the project lock.
  • A stream is not ready immediately: engine startup takes about 15 seconds. Use --no-stream for a short or headless run.

The CLI prints value-specific errors and recovery commands. Use uv run antioch scenario run --help for one example of the current command options.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

antioch_sim-0.3.32-py3-none-any.whl (26.2 MB view details)

Uploaded Python 3

File details

Details for the file antioch_sim-0.3.32-py3-none-any.whl.

File metadata

  • Download URL: antioch_sim-0.3.32-py3-none-any.whl
  • Upload date:
  • Size: 26.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.27 {"installer":{"name":"uv","version":"0.11.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for antioch_sim-0.3.32-py3-none-any.whl
Algorithm Hash digest
SHA256 dfcae3542040c584c6a0e927d00cb1eb88a27b6c95e66b7d1ea48e884c1b5421
MD5 77b848bf4256bbbe960a4395b0a93e5a
BLAKE2b-256 2f0c06046309a6585dd987e78ecb83fcf02538fddb243abefec4b4dafee00f08

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page