Move the shared sandbox layer to openenv.core.sandbox#1010
Draft
sergiopaniego wants to merge 21 commits into
Draft
Move the shared sandbox layer to openenv.core.sandbox#1010sergiopaniego wants to merge 21 commits into
sergiopaniego wants to merge 21 commits into
Conversation
…roxy PiSessionFactory/PiSession/PiConfig mirror the OpenCode primitive: install the pi CLI (Node bootstrap + npm), write models.json pointing at an OpenAI-compatible endpoint, run pi --print --mode json headless, and (transparent_proxy mode) capture per-token logprobs via the shared interception proxy for GRPO. The sandbox backend (HFSandboxBackend) and interception proxy are imported from opencode_env for now; the plan is to consolidate both into openenv.core in a follow-up. Includes builder + factory-lifecycle unit tests.
Mirrors opencode_env's second layer so pi_env is both an in-process harness primitive and a deployable OpenEnv environment: PiEnv MCP client + FastAPI server (PiEnvironment with the run_rollout tool, task catalog, Gradio UI) + Dockerfile + openenv.yaml. HF sandbox (image, HF_TOKEN) replaces E2B (template, E2B_API_KEY); in-sandbox paths are /root; the sandbox backend and interception proxy are imported from opencode_env. Adds uv.lock and the pi-env server-image entry to docker-build.yml.
sync_env_docs.py --fix generates the docs/source/environments/pi.md stub from the README; the HTML catalog card in environments.md and the _toctree.yml nav entry are added manually (the script does not manage those). check-env-docs now passes.
…, pipefail - README: correct the HF sandbox docs URL, drop redundant/circular links - .dockerignore: HF_TOKEN, not E2B_API_KEY - pi_runtime: gate Node >=22.19 (not just major 22); use the full model id and select by --provider so a slashed id isn't split; set -o pipefail so the piped tee doesn't mask Pi's exit code
…docs Import the primitive from its defining modules instead of the top-level pi_env package (which re-exports the client), per the server/client-separation invariant. Reword the setup docs: it runs at rollout start, not strictly before the agent.
…dead field - harness/server: size the sandbox lifetime and MCP-tool timeout to the full Node+Pi cold install, not just the agent - README: note the opencode_env install prerequisite for the primitive path; correct the server Dockerfile comment - config: drop unused request_timeout_ms - client: document the endpoint shorthand
Mirror opencode_env's pre-baked image: bake Node + Pi + proxy deps so rollouts skip the cold install (the proxy source is uploaded at runtime since it lives in opencode_env). Also drop the stale '(default)' on transparent_proxy in the harness docstring (the factory default is black_box).
…ps; guard UI stderr - server: only run verify + compute reward when the run is clean (a failed setup/agent leaves a half-prepared sandbox); dedupe the endpoint error paren - harness: set -o pipefail on the proxy-deps install so a failed pip isn't masked by tail - gradio: don't index an empty stderr split (IndexError when exit!=0, no stderr)
…e separately - token check via huggingface_hub.get_token() (HF_TOKEN, legacy var, or a cached login) instead of guessing env var names - _start_proxy: skip the pip install when the deps import, independent of the proxy source upload, so the pre-baked image (deps baked, source not) skips it
Mirror of the OpenCodeSessionFactory retry: session creation (sandbox + Pi install + proxy + agent) is the flakiest step, and a single transient failure dropped the rollout as unscorable. create() now retries create_attempts times with exponential backoff; the per-attempt logic moved to _create_once, which already tears its own sandbox down on failure, so a retry never leaks.
The sandbox protocol (SandboxBackend/SandboxHandle/BgJob/ExecResult), the E2B and Hugging Face backends, the interception proxy, and build_template move from envs/opencode_env/sandbox/ to src/openenv/core/sandbox/, so both opencode_env and pi_env import them from core instead of pi_env peer-depending on opencode_env. - opencode_env and pi_env now import from openenv.core.sandbox; pi_env drops its opencode_env peer dependency (the server Dockerfile no longer installs it, and `pip install openenv-pi-env` no longer needs opencode_env). - interception.py is no longer baked into the opencode pre-baked image; the harness uploads it at rollout start from core (matching the pi-sandbox image). The opencode hf_image dir moves out of sandbox/ to opencode_env/hf_image/ to match pi. - e2b stays a lazy import so core keeps no hard e2b dependency. - No backward-compat shim: both opencode_env and the TRL async_grpo path are experimental, so external importers (our gists, the TRL opencode example) update to openenv.core.sandbox directly. AI-assisted.
They now live under src/ (lint-checked) rather than envs/ (not linted), so usort + ruff format run over them.
Under src/ these are ruff-lint-checked (they were not under envs/): remove the unused typing.Any in base.py and .base.SandboxBackend in e2b.py.
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Warning
Do not merge until #999 lands. This branch is stacked on #999 (
pi_env). Opening it againstmainis the only option (GitHub cannot base an upstream PR on a fork branch), so the diff currently includes all of #999; it auto-cleans to just the sandbox-move once #999 merges. Review the sandbox-move commit; the pi_env files belong to #999.Moves the shared sandbox layer out of
envs/opencode_env/sandbox/intosrc/openenv/core/sandbox/, soopencode_envandpi_envboth import it from core instead ofpi_envpeer-depending onopencode_env. This closes the peer-dependency flagged in #999 (a plainpip install openenv-pi-envno longer needsopencode_env).What moves
SandboxBackend/SandboxHandle/BgJob/ExecResult(the protocol), theE2Band Hugging Face backends,interception.py(the proxy), andbuild_template.py→openenv.core.sandbox.Notable changes
opencode_envandpi_envimport fromopenenv.core.sandbox.pi_envdrops itsopencode_envpeer dep: the server Dockerfile no longer installsopenenv-opencode-env, and_PROXY_SOURCE_PATHreadsinterception.pyfrom core.interception.pyis no longerCOPYed into the opencode pre-baked image; the harness uploads it at rollout start (matching the existing pi-sandbox image). The opencodehf_image/dir moves out ofsandbox/toopencode_env/hf_image/to match pi, anddocker-build.ymlis updated.e2bstays a lazy import incore/sandbox/__init__.py, so core keeps no harde2bdependency (unchanged behavior).sync_env_docs --checkgreen).No backward-compat shim (deliberate)
Both
opencode_envand the TRLasync_grpoharness path are experimental, so a clean move is fine. Known downstream that must update one importopencode_env.sandbox→openenv.core.sandbox:examples/scripts/openenv/opencode.py, Async grpo OpenEnv harness rollout trl#6420) importsfrom opencode_env.sandbox.base import ExecResult, SandboxHandle— one-line change, for its author to apply.AI-assisted.