This release is a pre-release and may not be stable for production use.
nemo-sandboxed-gym
Trusted episode broker + job-level Gym host orchestrator for running NeMo-Gym inside an OpenSandbox (or compatible) isolation boundary.
This package has no NeMo-RL / GRPO dependency. Callers get raw Gym host
/health and /rollouts/run results. RL-specific postprocessing belongs in the
training client (e.g. NeMo-RL's thin SandboxedGymActor adapter).
Provenance
Vendored from soluwalana/RL branch nmp/customizer at
67821a9 (2026-08-03), the fork this code still shares an ancestor with. Upstream changes have
been applied selectively since; the divergences are deliberate and documented where they occur.
Recorded because the original vendoring landed as one squashed commit with no provenance, and
recovering this took a per-file comparison against every revision of the upstream tree. Diffing
from any earlier commit shows host/entrypoint.py and host/gym_host.sh as drift when they are
already here. Update this line whenever upstream is merged again; it becomes moot once the shared
wheel exists.
Architecture
The trusted side holds the OpenSandbox credential and the episode broker; the sandbox gets a per-run token and nothing else. The episode tier is only used by environments that ask for nested sandboxes -- an ordinary evaluation never creates one.
Two job-host providers
get_host_provider selects by name. docker is for local execution only: it runs the host as
a container, records the egress allowlist rather than applying it, and bind-mounts host
directories. It is not an isolation boundary. opensandbox is the real one -- Kubernetes pod,
PVC mounts, enforced egress, kata-qemu -- and is where the isolation properties actually live.
Install
pip install -e packages/sandboxed_gym
# optional Ray wrappers
pip install -e "packages/sandboxed_gym[ray]"
Serve (always starts the episode broker)
# Mode A — local orchestrator proxy (recommended for cross-job clients)
sandboxed-gym serve --config serve.yaml --mode orchestrator --bind 0.0.0.0:8090 \
--session-file /tmp/session.json
# Mode B — print Gym host URLs and wait
sandboxed-gym serve --config serve.yaml --mode host-urls --session-file /tmp/session.json
Cross-job pattern
- Job A runs
sandboxed-gym serve --mode orchestratorwith environment/dataset PVC mounts (sameSandboxConfigshape as sandboxed GRPO). - Job A writes a
SandboxedGymSessionDescriptor(--session-file). - Job B POSTs to Job A's orchestrator Service:
POST /rollouts/run.
A wildcard --bind advertises the node address, which is routable from another pod but not from
outside the cluster. Pass --advertise-url when the reachable address is not the one Job A binds
-- a published container port, or an ingress in front of the proxy.
Set episode_broker.advertise_url to a stable Service DNS name so the Gym host
egress allowlist does not depend on a pod IP.
Library
from sandboxed_gym import SandboxedGymOrchestrator, SandboxedGymServeConfig
session = SandboxedGymOrchestrator().start(SandboxedGymServeConfig.model_validate(...))
results = session.run_rollouts([{"agent_ref": {...}, ...}])
session.shutdown()
Config sketch
See examples/serve.yaml. Key fields:
sandbox.environment_pvc_claim/dataset_pvc_claim/workspace_pvc_claimepisode_broker(allowlists, TTL,advertise_url)gym_global_config— opaque Gym JSON injected asNMP_GYM_GLOBAL_CONFIGrollout_auth_token— optional bearer for the orchestrator proxy
Metadata
Release files for nemo-sandboxed-gym 0.1.0a0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nemo_sandboxed_gym-0.1.0a0-py3-none-any.whl | Python 3 | none | any | Details for nemo_sandboxed_gym-0.1.0a0-py3-none-any.whl |
Release files / nemo_sandboxed_gym-0.1.0a0-py3-none-any.whl
| Download URL | nemo_sandboxed_gym-0.1.0a0-py3-none-any.whl |
|---|---|
| Size | 111.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
350714bf07bf4ac8bbc857005aa10503e1ae2e78d0aedc410040ead9a8838a43
|
|
BLAKE2b-256 checksum How to use checksums |
f2a659adba74418e9d185862f94f495cba385919fa1a1d8293f2cd4f63e4465e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Security for nemo-sandboxed-gym 0.1.0a0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.