openenv/echo_env
6
1# OpenEnv: Agentic Execution Environments2 3An e2e framework for creating, deploying and using isolated execution environments for agentic RL training, built using Gymnasium style simple APIs. OpenEnv provides a standard for interacting with agentic execution environments via simple Gymnasium style APIs - step(), reset(), state(). Users of agentic execution environments can interact with the environment during RL training loops using these simple APIs.4 5In addition to making it easier for researchers and RL framework writers, we also provide tools for environment creators making it easier for them to create richer environments and make them available over familiar protocols like HTTP and packaged using canonical technologies like docker. Environment creators can use the OpenEnv framework to create environments that are isolated, secure, and easy to deploy and use.6 7OpenEnv is openly governed by a technical committee that includes Meta-PyTorch, Reflection, Unsloth, Modal, Prime Intellect, Nvidia, Mercor, Fleet AI, Microsoft, Hugging Face, RadixArk, and Nebius. The committee coordinates project direction, major technical decisions, RFCs, and release planning through the public issue tracker, pull requests, and RFC process.8 9 10## Overview11`openenv.core` provides the foundational building blocks for creating and interacting with containerized environments over HTTP. It enables you to build agent environments that can be deployed as Docker containers and accessed via a simple HTTP API.12 13> ⚠️ **Early Development Warning** OpenEnv is currently in an experimental14> stage. You should expect bugs, incomplete features, and APIs that may change15> in future versions. The project welcomes bugfixes, but significant changes16> should be discussed before implementation so the technical committee and17> community can coordinate scope, compatibility, and release timing. It's18> recommended that you signal your intention to contribute in the issue tracker,19> either by filing a new issue or by claiming an existing one.20 21 22# OpenEnv Core23 24Core components for OpenEnv - a framework for building HTTP-based agentic environments.25 26## Features27 28- **EnvClient**: Async-first client for interacting with remote environments29- **SyncEnvClient**: Synchronous wrapper via `.sync()` for sync codebases30- **HTTPEnvServer**: FastAPI-based server wrapper for exposing environments over HTTP/WebSocket31- **Container Providers**: Pluggable architecture for running containers (Docker, Kubernetes, etc.)32- **Type System**: Strongly-typed Action/Observation/State interfaces33- **Web Interface**: Optional web UI for interacting with environments34- **Experimental Harness Helpers**: `openenv.core.harness` provides35 `ResourceSessionFactory`, `StepEnvSessionAdapter`, and `HarnessAdapter` for36 MCP-first training/evaluation harnesses37 38## Experimental Harness Helpers39 40OpenEnv now includes an additive harness-facing layer for cases where a rollout41driver should interact with environment resources through tools instead of42calling `reset()` / `step()` directly. These helpers are currently43experimental while RFC 005 remains in review, so import them from44`openenv.core.harness`.45 46Core pieces:47 48- `ResourceSessionFactory.create(task, seed, episode_id)` creates an isolated49 per-rollout session50- `StepEnvSessionAdapter` wraps an existing client and exposes session tools51- `SessionMCPBridge` exposes a session through MCP-style JSON-RPC52- `MCPHarnessAdapter` drives white-box rollouts where the trainer still owns53 model sampling, token IDs, and logprobs54- `CLIHarnessAdapter` supports opaque evaluation harnesses over the same session55 surface56- `build_harness_rollout_func(...)` builds a TRL-compatible `rollout_func`57 58This layer is additive. Existing environment clients and MCP environments keep59their current control-plane APIs unchanged.60 61## Installation62 63```bash64pip install "openenv"65```66 67For development:68```bash69pip install "openenv"70```71 72## Quick Start73 74### Creating an Environment Client75 76EnvClient is **async by default**. Use `async with` and `await` for all operations:77 78```python79import asyncio80from openenv.core import EnvClient, StepResult81from dataclasses import dataclass82from typing import Any83 84 85@dataclass86class MyAction:87 text: str88 89 90@dataclass91class MyObservation:92 response: str93 94 95class MyEnvClient(EnvClient[MyAction, MyObservation, Any]):96 def _step_payload(self, action: MyAction) -> dict:97 return {"text": action.text}98 99 def _parse_result(self, payload: dict) -> StepResult[MyObservation]:100 obs_data = payload["observation"]101 return StepResult(102 observation=MyObservation(**obs_data),103 reward=payload.get("reward"),104 done=payload.get("done", False),105 )106 107 def _parse_state(self, payload: dict) -> Any:108 return payload109 110 111# Async usage (recommended)112async def main():113 client = await MyEnvClient.from_docker_image("my-env:latest")114 async with client:115 result = await client.reset()116 step_result = await client.step(MyAction(text="hello"))117 118 119asyncio.run(main())120 121# Sync usage (via .sync() wrapper)122with MyEnvClient(base_url="http://localhost:8000").sync() as client:123 result = client.reset()124 step_result = client.step(MyAction(text="hello"))125```126 127### Creating an Environment Server128 129```python130from openenv.core.env_server import Environment, HTTPEnvServer, create_app131from dataclasses import dataclass132 133 134@dataclass135class MyAction:136 text: str137 138 139@dataclass140class MyObservation:141 response: str142 reward: float = 0.0143 done: bool = False144 145 146class MyEnvironment(Environment):147 def reset(self) -> MyObservation:148 return MyObservation(response="Ready")149 150 def step(self, action: MyAction) -> MyObservation:151 return MyObservation(response=f"Echo: {action.text}", reward=1.0, done=False)152 153 154# Create FastAPI app155env = MyEnvironment()156app = create_app(env, MyAction, MyObservation)157 158# Run with: uvicorn module:app --host 0.0.0.0 --port 8000159```160 161## Container Providers162 163OpenEnv Core supports multiple container providers:164 165### Local Docker Provider166 167```python168from openenv.core.containers.runtime import LocalDockerProvider169 170provider = LocalDockerProvider()171base_url = provider.start_container("my-env:latest")172provider.wait_for_ready(base_url)173# Use environment...174provider.stop_container()175```176 177### Kubernetes Provider (Coming Soon)178 179```python180from openenv.core.containers.runtime import KubernetesProvider181 182provider = KubernetesProvider(namespace="envs")183base_url = provider.start_container("my-env:latest")184# Use environment...185provider.stop_container()186```187 188 189## API Reference190 191### EnvClient192 193Async base class for environment clients. Key methods:194 195- `async connect()`: Establish WebSocket connection196- `async reset(**kwargs)`: Reset environment197- `async step(action)`: Execute action198- `async state()`: Get current state199- `async close()`: Close connection and cleanup200- `sync()`: Return a SyncEnvClient wrapper for synchronous usage201 202Abstract methods to implement:203- `_step_payload(action)`: Convert action to JSON204- `_parse_result(payload)`: Parse response to StepResult205- `_parse_state(payload)`: Parse state response206 207### SyncEnvClient208 209Synchronous wrapper around EnvClient. Use `client.sync()` to get one:210 211```python212sync_client = async_client.sync()213with sync_client:214 result = sync_client.reset()215 result = sync_client.step(action)216```217 218### HTTPEnvServer219 220Server wrapper with these methods:221 222- `register_routes(app)`: Register endpoints on FastAPI app223- `_deserialize_action(data)`: Convert JSON to Action224- `_serialize_observation(obs)`: Convert Observation to JSON225 226### Environment Interface227 228Base interface for environment implementations:229 230- `reset()`: Reset environment and return initial observation231- `step(action)`: Execute action and return observation232- `state`: Property returning current environment state233 234## License235 236This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.237 238## Contributing239 240Contributions are welcome! Please see the main OpenEnv repository for contribution guidelines.241 242## Links243 244- **Homepage**: https://github.com/huggingface/OpenEnv245- **Documentation**: https://github.com/huggingface/OpenEnv/blob/main/README.md246- **Bug Tracker**: https://github.com/huggingface/OpenEnv/issues247 