Remote
Running environments on other machines instead of your local one.
If you're running everything on one machine, you can ignore this page.
This part of Gym Anything is for the case where environments run on other machines and your code talks to them over the network.
Gym Anything Remote runs the environment lifecycle on Gym workers and supports the different runners. For the Sandweave runner, you can also connect directly to a Weave cluster. In that configuration, Gym's episode orchestration runs in the benchmark process and Weave places its Linux sandboxes on Sandweave workers.
When You Need This
Use the remote setup when:
- you have multiple machines for experiments
- environments are too heavy to run on your laptop
- you want one machine to manage work across several workers
The Basic Idea
The remote setup has three pieces:
- a master server that routes requests
- one or more worker servers that actually run environments
- a remote client called
RemoteGymEnv
The Main Commands
The main server commands are:
gym-anything-mastergym-anything-workergym-anything-dashboard
The master, worker and dashboard bind to 127.0.0.1 by default. Start one master:
gym-anything-master --host 127.0.0.1 --port 5800Start a worker on the same machine:
gym-anything-worker \
--host 127.0.0.1 --port 5801 \
--master-url http://127.0.0.1:5800 \
--max-envs 1 \
--advertise-host 127.0.0.1For a worker on another machine, first run this SSH connection from that worker machine and keep it running:
ssh -N -o ExitOnForwardFailure=yes \
-L 127.0.0.1:5800:127.0.0.1:5800 \
-R 127.0.0.1:5801:127.0.0.1:5801 user@master-hostThen run the same worker command there. The local forward lets the worker reach
the master; the reverse forward lets the master reach the worker. Use a distinct
worker port for each worker and match it in --port and both sides of -R.
The SSH server must permit forwarding and retain its default GatewayPorts no
setting so reverse forwards remain on loopback.
From a separate benchmark or browser machine, forward the master port with
ssh -N -L 127.0.0.1:5800:127.0.0.1:5800 user@master-host, then use
http://127.0.0.1:5800. Forward the standalone dashboard's port in the same way
when using gym-anything-dashboard.
The master stores worker and environment routing state in memory, so run a single master process. Submit worker jobs with your cluster scheduler by launching gym-anything-worker in each job. The environment paths and cache paths used by clients must also exist on the worker machines.
Workers run a runner preflight before registering with the master. The same logic that powers gym-anything doctor discovers which runners are usable on the host (binaries present, /dev/kvm openable for QEMU-family runners on Linux, etc.) and the worker advertises that list to the master under metadata.available_runners. The master uses it to route environments only to workers that can run them: when a request includes an explicit runner (set in env.json or forwarded by the client), creation is filtered to matching workers; otherwise routing falls back to least-loaded across the cluster.
If the host has no usable runner the worker exits without registering. Pass --skip-preflight (or GYM_ANYTHING_WORKER_SKIP_PREFLIGHT=1) for local development and tests that don't actually execute a real runner. The previous --skip-kvm-check flag and GYM_ANYTHING_WORKER_SKIP_KVM_CHECK env var still work as deprecated aliases.
To assert that a specific runner must be available before the worker comes up — e.g. when a Slurm job is reserved for QEMU work and should fail fast otherwise — pass --must-support-runner qemu (or GYM_ANYTHING_WORKER_MUST_SUPPORT_RUNNER=qemu,docker for multiple). The preflight raises and the worker exits if any listed runner is unavailable.
Python Usage
From Python, the remote client looks like this:
from gym_anything import RemoteGymEnv
env = RemoteGymEnv.from_config(
remote_url="http://localhost:5800",
env_dir="benchmarks/cua_world/environments/moodle_env",
task_id="enroll_student",
)After that, the flow is similar to a local environment:
reset()step(...)close()
Benchmark Usage
gym-anything benchmark can route environment execution through a remote master or worker:
gym-anything benchmark moodle \
--task enroll_student \
--agent ClaudeAgent \
--model claude-opus-4 \
--remote-url http://127.0.0.1:5800The agent loop still runs in the client process. Environment reset, actions, screenshots, and verification run on the selected worker.
Useful remote flags:
--remote-url: master or worker URL--remote-timeout: HTTP timeout for long reset/step calls--remote-worker-reset-policy: worker-local reset policy, usuallycore
Sandweave With Weave
Install Gym's sandweave extra on the Linux benchmark machine (Python 3.11+)
and Sandweave on the workers. Benchmark agents also need the agents extra and
their model credentials. On first use, Sandweave downloads the versioned Ubuntu
image pinned in sandweave_ubuntu.toml, verifies its SHA-256 checksums, and caches
it in each worker's SANDWEAVE_HOME. Workers need outbound HTTPS and disk space
for image preparation. They do not need a local QEMU image, QEMU, KVM, or a
manually registered base snapshot. Later launches reuse the verified local image.
Use Sandweave 0.2.21 or newer on the client, controller and workers. This release
makes new Weave controllers bind to 127.0.0.1 by default, including startup with
TLS certificates or a credential file. It retains the checkpoint and Docker
storage fixes from 0.2.20. Live Google Earth and Moodle runs on 0.2.20 verified
their default filesystem caches with normal and fast IO using the prepared
image and the official runtime, without local SDK patches.
Moodle's Docker database still fails with a cgroup/BPF program lookup error in this runtime. Its unchanged setup script uses its existing native-MariaDB fallback, after which login and cache restores work. This does not establish Docker-container compatibility with the prepared image.
Start a controller on the server:
sandweave cluster start labThis also registers the server as a worker. A new controller listens on
127.0.0.1 with an automatically assigned port. Existing saved listener settings
are retained: to restrict a previously public controller, stop it and restart
with --listen 127.0.0.1:0.
To use separate worker machines, add --no-worker, then use the SSH connection
link printed by the controller with sandweave cluster join on each
worker. SSH must be available from each worker to the controller. Sandweave
creates the loopback tunnel for that SSH connection.
On the benchmark machine, from the project where you will run benchmarks, save
the connection once. On another machine, paste the SSH connection link printed
by the controller. On the controller machine, the HTTP link also works; preserve
its complete #token=... fragment:
read -r -p 'Sandweave controller connection link: ' weave_address
sandweave cluster connect lab "$weave_address"
unset weave_addressWhen the benchmark and controller use the same Sandweave configuration, lab
is already saved. A saved name uses that configuration's address and credentials;
it does not discover a server on another machine.
Run a benchmark using the existing runner and target settings:
GYM_ANYTHING_RUNNER=sandweave \
GYM_ANYTHING_SANDWEAVE_TARGET=lab \
gym-anything benchmark moodle \
--agent ClaudeAgent \
--split disk \
--parallel 4 \
--use-cache \
--cache-level default \
--fast-ioAdd --model to choose the agent model. Omit --fast-io for normal IO.
--cache-level default honors each environment's cache setting; for example,
Moodle uses post_start and Google Earth uses pre_start. --parallel controls
Gym's concurrent benchmark processes. Weave schedules their sandboxes according
to worker capacity. Gym still owns setup hooks, task initialization, observations,
verification and episode recording.
GYM_ANYTHING_RUNNER=sandweave selects the runner.
GYM_ANYTHING_SANDWEAVE_TARGET=lab selects the cluster; leaving it unset uses
local Sandweave. A controller HTTP, HTTPS or SSH address can also be used directly
as the target. Sandweave manages authentication through the saved connection or
its SANDWEAVE_TOKEN_FILE and SANDWEAVE_CA_FILE settings.
The existing --remote-url flag addresses a Gym Anything master or worker.
For direct Weave execution, use the Sandweave target setting above. When using
Sandweave inside Gym Anything Remote instead, configure the runner and target
in the Gym worker process that creates the environment.
Monitoring And Desktop Access
sandweave dashboard labThe dashboard shows sandbox state, placement, resource measurements and runtime
logs. Sandboxes have names based on the Gym environment ID plus a unique suffix.
Gym's session information retains the SDK sandbox ID in instance_name for
correlation. Gym benchmark tasks are not submitted as Weave Jobs by this runner.
VNC is a separate connection: Weave forwards SDK commands, files, screenshots and input, but does not tunnel the worker's VNC TCP port. Gym exposes the VNC URL when the sandbox runs on the same host. For a remote worker it logs the worker hostname and VNC port instead of advertising an unusable localhost URL. If you have SSH access to that worker, establish a tunnel using those values:
read -r -p 'Worker SSH destination (user@host): ' weave_worker
read -r -p 'Worker VNC port reported by Gym: ' weave_vnc_port
ssh -N -L "127.0.0.1:15901:127.0.0.1:${weave_vnc_port}" "$weave_worker"Keep the tunnel running and open vnc://127.0.0.1:15901 in your VNC viewer.
The SDK screenshot and input paths work through Weave without this VNC tunnel.
See Sandweave's cluster documentation for worker limits, connection options and controller lifecycle.