File size: 6,877 Bytes
edc5871
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# <img width="35" height="35" alt="image" src="https://github.com/user-attachments/assets/2700a971-e5d6-4036-b03f-2f89c9791609" /> OpenEnv: Agentic Execution Environments

An 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.

In 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.


## Overview
`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.

> ⚠️ **Early Development Warning** OpenEnv is currently in an experimental
> stage. You should expect bugs, incomplete features, and APIs that may change
> in future versions. The project welcomes bugfixes, but to make sure things are
> well coordinated you should discuss any significant change before starting the
> work. It's recommended that you signal your intention to contribute in the
> issue tracker, either by filing a new issue or by claiming an existing one.


# OpenEnv Core

Core components for OpenEnv - a framework for building HTTP-based agentic environments.

## Features

- **EnvClient**: Async-first client for interacting with remote environments
- **SyncEnvClient**: Synchronous wrapper via `.sync()` for sync codebases
- **HTTPEnvServer**: FastAPI-based server wrapper for exposing environments over HTTP/WebSocket
- **Container Providers**: Pluggable architecture for running containers (Docker, Kubernetes, etc.)
- **Type System**: Strongly-typed Action/Observation/State interfaces
- **Web Interface**: Optional web UI for interacting with environments

## Installation

```bash
pip install "openenv[core]"
```

For development:
```bash
pip install "openenv[core]"
```

## Quick Start

### Creating an Environment Client

EnvClient is **async by default**. Use `async with` and `await` for all operations:

```python
import asyncio
from openenv.core import EnvClient, StepResult
from dataclasses import dataclass
from typing import Any

@dataclass
class MyAction:
    text: str

@dataclass
class MyObservation:
    response: str

class MyEnvClient(EnvClient[MyAction, MyObservation, Any]):
    def _step_payload(self, action: MyAction) -> dict:
        return {"text": action.text}

    def _parse_result(self, payload: dict) -> StepResult[MyObservation]:
        obs_data = payload["observation"]
        return StepResult(
            observation=MyObservation(**obs_data),
            reward=payload.get("reward"),
            done=payload.get("done", False)
        )

    def _parse_state(self, payload: dict) -> Any:
        return payload

# Async usage (recommended)
async def main():
    client = await MyEnvClient.from_docker_image("my-env:latest")
    async with client:
        result = await client.reset()
        step_result = await client.step(MyAction(text="hello"))

asyncio.run(main())

# Sync usage (via .sync() wrapper)
with MyEnvClient(base_url="http://localhost:8000").sync() as client:
    result = client.reset()
    step_result = client.step(MyAction(text="hello"))
```

### Creating an Environment Server

```python
from openenv.core.env_server import Environment, HTTPEnvServer, create_app
from dataclasses import dataclass

@dataclass
class MyAction:
    text: str

@dataclass
class MyObservation:
    response: str
    reward: float = 0.0
    done: bool = False

class MyEnvironment(Environment):
    def reset(self) -> MyObservation:
        return MyObservation(response="Ready")

    def step(self, action: MyAction) -> MyObservation:
        return MyObservation(
            response=f"Echo: {action.text}",
            reward=1.0,
            done=False
        )

# Create FastAPI app
env = MyEnvironment()
app = create_app(env, MyAction, MyObservation)

# Run with: uvicorn module:app --host 0.0.0.0 --port 8000
```

## Container Providers

OpenEnv Core supports multiple container providers:

### Local Docker Provider

```python
from openenv.core.containers.runtime import LocalDockerProvider

provider = LocalDockerProvider()
base_url = provider.start_container("my-env:latest")
provider.wait_for_ready(base_url)
# Use environment...
provider.stop_container()
```

### Kubernetes Provider (Coming Soon)

```python
from openenv.core.containers.runtime import KubernetesProvider

provider = KubernetesProvider(namespace="envs")
base_url = provider.start_container("my-env:latest")
# Use environment...
provider.stop_container()
```


## API Reference

### EnvClient

Async base class for environment clients. Key methods:

- `async connect()`: Establish WebSocket connection
- `async reset(**kwargs)`: Reset environment
- `async step(action)`: Execute action
- `async state()`: Get current state
- `async close()`: Close connection and cleanup
- `sync()`: Return a SyncEnvClient wrapper for synchronous usage

Abstract methods to implement:
- `_step_payload(action)`: Convert action to JSON
- `_parse_result(payload)`: Parse response to StepResult
- `_parse_state(payload)`: Parse state response

### SyncEnvClient

Synchronous wrapper around EnvClient. Use `client.sync()` to get one:

```python
sync_client = async_client.sync()
with sync_client:
    result = sync_client.reset()
    result = sync_client.step(action)
```

### HTTPEnvServer

Server wrapper with these methods:

- `register_routes(app)`: Register endpoints on FastAPI app
- `_deserialize_action(data)`: Convert JSON to Action
- `_serialize_observation(obs)`: Convert Observation to JSON

### Environment Interface

Base interface for environment implementations:

- `reset()`: Reset environment and return initial observation
- `step(action)`: Execute action and return observation
- `state`: Property returning current environment state

## License

This project is licensed under the BSD-3-Clause License - see the LICENSE file for details.

## Contributing

Contributions are welcome! Please see the main OpenEnv repository for contribution guidelines.

## Links

- **Homepage**: https://github.com/meta-pytorch/OpenEnv
- **Documentation**: https://github.com/meta-pytorch/OpenEnv/blob/main/README.md
- **Bug Tracker**: https://github.com/meta-pytorch/OpenEnv/issues