openenv 0.2.3__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openenv-0.2.3/src/openenv.egg-info → openenv-0.3.1}/PKG-INFO +35 -22
- {openenv-0.2.3 → openenv-0.3.1}/README.md +30 -17
- {openenv-0.2.3 → openenv-0.3.1}/pyproject.toml +5 -5
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/__init__.py +1 -1
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/auto/_discovery.py +2 -2
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/__main__.py +14 -1
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/_validation.py +81 -9
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/build.py +16 -7
- openenv-0.3.1/src/openenv/cli/commands/collect.py +443 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/push.py +211 -26
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/skills.py +12 -5
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/server/app.py +1 -1
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/http_server.py +50 -6
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/interfaces.py +2 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/web_interface.py +39 -6
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/evals/inspect_harness.py +13 -1
- openenv-0.3.1/src/openenv/core/harness/__init__.py +723 -0
- openenv-0.3.1/src/openenv/core/harness/collect.py +586 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/llm_client.py +32 -8
- {openenv-0.2.3 → openenv-0.3.1/src/openenv.egg-info}/PKG-INFO +35 -22
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv.egg-info/SOURCES.txt +3 -1
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv.egg-info/requires.txt +4 -4
- {openenv-0.2.3 → openenv-0.3.1}/LICENSE +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/MANIFEST.in +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/setup.cfg +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/auto/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/auto/auto_action.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/auto/auto_env.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/_cli_utils.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/fork.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/init.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/serve.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/commands/validate.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/README.md +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/models.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/openenv.yaml +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/pyproject.toml +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/server/Dockerfile +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/server/__ENV_NAME___environment.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/server/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/cli/templates/openenv_env/server/requirements.txt +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/client_types.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/runtime/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/runtime/daytona_provider.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/runtime/providers.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/runtime/uv_provider.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/containers/test_local_docker_provider.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/base_transforms.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/exceptions.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/gradio_theme.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/gradio_ui.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/mcp_environment.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/mcp_types.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/route_config.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/serialization.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/env_server/types.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/evals/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/evals/base.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/evals/types.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/generic_client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/mcp_client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/rubrics/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/rubrics/base.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/rubrics/containers.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/rubrics/llm_judge.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/rubrics/trajectory.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/sync_client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/tools/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/tools/git_server_client.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/tools/local_python_executor.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv/core/utils.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv.egg-info/dependency_links.txt +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv.egg-info/entry_points.txt +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv.egg-info/top_level.txt +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/src/openenv_core/__init__.py +0 -0
- {openenv-0.2.3 → openenv-0.3.1}/tests/test_line_endings.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openenv
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: A unified framework for reinforcement learning environments
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -37,13 +37,13 @@ Requires-Dist: tomli-w>=1.2.0; extra == "cli"
|
|
|
37
37
|
Provides-Extra: docs
|
|
38
38
|
Requires-Dist: sphinx==7.2.6; extra == "docs"
|
|
39
39
|
Requires-Dist: pytorch-sphinx-theme2; extra == "docs"
|
|
40
|
-
Requires-Dist: sphinxcontrib.katex==0.9.
|
|
41
|
-
Requires-Dist: docutils<0.
|
|
40
|
+
Requires-Dist: sphinxcontrib.katex==0.9.11; extra == "docs"
|
|
41
|
+
Requires-Dist: docutils<0.23,>=0.18.1; extra == "docs"
|
|
42
42
|
Requires-Dist: sphinx-design==0.6.1; extra == "docs"
|
|
43
|
-
Requires-Dist: sphinxcontrib-mermaid==
|
|
43
|
+
Requires-Dist: sphinxcontrib-mermaid==2.0.2; extra == "docs"
|
|
44
44
|
Requires-Dist: myst-parser; extra == "docs"
|
|
45
45
|
Requires-Dist: sphinxext-opengraph; extra == "docs"
|
|
46
|
-
Requires-Dist: sphinx-sitemap==2.
|
|
46
|
+
Requires-Dist: sphinx-sitemap==2.9.0; extra == "docs"
|
|
47
47
|
Requires-Dist: sphinx-gallery>=0.14.0; extra == "docs"
|
|
48
48
|
Requires-Dist: matplotlib; extra == "docs"
|
|
49
49
|
Requires-Dist: nest-asyncio; extra == "docs"
|
|
@@ -75,7 +75,7 @@ An e2e framework for creating, deploying and using isolated execution environmen
|
|
|
75
75
|
|
|
76
76
|
## Quick Start
|
|
77
77
|
|
|
78
|
-
Install the OpenEnv
|
|
78
|
+
Install the OpenEnv package:
|
|
79
79
|
|
|
80
80
|
```bash
|
|
81
81
|
pip install openenv
|
|
@@ -91,7 +91,7 @@ Then use the environment:
|
|
|
91
91
|
|
|
92
92
|
```python
|
|
93
93
|
import asyncio
|
|
94
|
-
from echo_env import
|
|
94
|
+
from echo_env import CallToolAction, EchoEnv
|
|
95
95
|
|
|
96
96
|
async def main():
|
|
97
97
|
# Connect to a running Space (async context manager)
|
|
@@ -101,9 +101,14 @@ async def main():
|
|
|
101
101
|
print(result.observation.echoed_message) # "Echo environment ready!"
|
|
102
102
|
|
|
103
103
|
# Send messages
|
|
104
|
-
result = await client.step(
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
result = await client.step(
|
|
105
|
+
CallToolAction(
|
|
106
|
+
tool_name="echo_message",
|
|
107
|
+
arguments={"message": "Hello, World!"},
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
print(result.observation.result) # "Hello, World!"
|
|
111
|
+
print(result.reward)
|
|
107
112
|
|
|
108
113
|
asyncio.run(main())
|
|
109
114
|
```
|
|
@@ -111,16 +116,21 @@ asyncio.run(main())
|
|
|
111
116
|
**Synchronous usage** is also supported via the `.sync()` wrapper:
|
|
112
117
|
|
|
113
118
|
```python
|
|
114
|
-
from echo_env import
|
|
119
|
+
from echo_env import CallToolAction, EchoEnv
|
|
115
120
|
|
|
116
121
|
# Use .sync() for synchronous context manager
|
|
117
122
|
with EchoEnv(base_url="https://openenv-echo-env.hf.space").sync() as client:
|
|
118
123
|
result = client.reset()
|
|
119
|
-
result = client.step(
|
|
120
|
-
|
|
124
|
+
result = client.step(
|
|
125
|
+
CallToolAction(
|
|
126
|
+
tool_name="echo_message",
|
|
127
|
+
arguments={"message": "Hello, World!"},
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
print(result.observation.result)
|
|
121
131
|
```
|
|
122
132
|
|
|
123
|
-
For a detailed quick start, check out the [docs page](https://meta-pytorch.org/OpenEnv/
|
|
133
|
+
For a detailed quick start, check out the [docs page](https://meta-pytorch.org/OpenEnv/auto_getting_started/index.html).
|
|
124
134
|
|
|
125
135
|
## OpenEnv on partner platforms:
|
|
126
136
|
|
|
@@ -138,12 +148,15 @@ In addition to making it easier for researchers and RL framework writers, we als
|
|
|
138
148
|
|
|
139
149
|
The OpenEnv CLI (`openenv`) provides commands to initialize new environments and deploy them to Hugging Face Spaces.
|
|
140
150
|
|
|
151
|
+
OpenEnv is openly governed by a technical committee that includes Hugging Face, Unsloth, Reflection, and Meta PyTorch. The committee coordinates project direction, major technical decisions, RFCs, and release planning through the public issue tracker, pull requests, and RFC process.
|
|
152
|
+
|
|
141
153
|
> ⚠️ **Early Development Warning** OpenEnv is currently in an experimental
|
|
142
154
|
> stage. You should expect bugs, incomplete features, and APIs that may change
|
|
143
|
-
> in future versions. The project welcomes bugfixes, but
|
|
144
|
-
>
|
|
145
|
-
>
|
|
146
|
-
>
|
|
155
|
+
> in future versions. The project welcomes bugfixes, but significant changes
|
|
156
|
+
> should be discussed before implementation so the technical committee and
|
|
157
|
+
> community can coordinate scope, compatibility, and release timing. It's
|
|
158
|
+
> recommended that you signal your intention to contribute in the issue tracker,
|
|
159
|
+
> either by filing a new issue or by claiming an existing one.
|
|
147
160
|
|
|
148
161
|
### RFCs
|
|
149
162
|
|
|
@@ -299,7 +312,7 @@ See [`envs/README.md`](envs/README.md) for a complete guide on building environm
|
|
|
299
312
|
|
|
300
313
|
To use an environment:
|
|
301
314
|
1. Install the client: `pip install git+https://huggingface.co/spaces/openenv/echo-env`
|
|
302
|
-
2. Import: `from echo_env import
|
|
315
|
+
2. Import: `from echo_env import CallToolAction, EchoEnv`
|
|
303
316
|
3. Use async (recommended) or sync API:
|
|
304
317
|
|
|
305
318
|
**Async (recommended):**
|
|
@@ -427,12 +440,12 @@ See the [Oumi example](https://github.com/oumi-ai/oumi/blob/main/notebooks/Oumi%
|
|
|
427
440
|
| [Atari Environment](envs/atari_env/README.md) | Classic Arcade Learning Environment tasks for RL benchmarking. |
|
|
428
441
|
| [FinRL Environment](envs/finrl_env/README.md) | Financial market simulations for algorithmic trading experiments. |
|
|
429
442
|
|
|
430
|
-
> Browse the full catalog of community environments at [meta-pytorch.org/OpenEnv/environments](https://meta-pytorch.org/OpenEnv/environments
|
|
443
|
+
> Browse the full catalog of community environments at [meta-pytorch.org/OpenEnv/environments](https://meta-pytorch.org/OpenEnv/environments.html).
|
|
431
444
|
|
|
432
445
|
## Community Support & Acknowledgments
|
|
433
|
-
This is an open and community-centric project. If you would like to add your
|
|
446
|
+
This is an open and community-centric project, governed in public by a technical committee that includes Hugging Face, Unsloth, Reflection, and Meta PyTorch. If you would like to add your project or organization here, please open a pull request for maintainer review.
|
|
434
447
|
|
|
435
|
-
Supporters include: Meta-PyTorch, Hugging Face, [Scaler AI Labs](https://scalerailabs.com), [Patronus AI](https://patronus.ai), [Surge AI](https://surgehq.ai), [LastMile AI](https://www.lastmileai.dev), Unsloth
|
|
448
|
+
Supporters include: Meta-PyTorch, Hugging Face, [Scaler AI Labs](https://scalerailabs.com), [Patronus AI](https://patronus.ai), [Surge AI](https://surgehq.ai), [LastMile AI](https://www.lastmileai.dev), Unsloth, Reflection, vLLM, SkyRL (UC-Berkeley), LightningAI, Axolotl AI, Stanford Scaling Intelligence Lab, Mithril, [OpenMined](https://openmined.org/), [Fleet AI](https://fleetai.com), [Halluminate](https://halluminate.ai/), [Turing](https://www.turing.com/), [Scale AI](https://scale.com/), [Scorecard](https://www.scorecard.io/) ..
|
|
436
449
|
|
|
437
450
|
And we'd also like to acknowledge the team at Farama Foundation as the OpenEnv API was heavily inspired by the work you all have done on Gymnasium. Cheers!
|
|
438
451
|
|
|
@@ -15,7 +15,7 @@ An e2e framework for creating, deploying and using isolated execution environmen
|
|
|
15
15
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
|
-
Install the OpenEnv
|
|
18
|
+
Install the OpenEnv package:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
pip install openenv
|
|
@@ -31,7 +31,7 @@ Then use the environment:
|
|
|
31
31
|
|
|
32
32
|
```python
|
|
33
33
|
import asyncio
|
|
34
|
-
from echo_env import
|
|
34
|
+
from echo_env import CallToolAction, EchoEnv
|
|
35
35
|
|
|
36
36
|
async def main():
|
|
37
37
|
# Connect to a running Space (async context manager)
|
|
@@ -41,9 +41,14 @@ async def main():
|
|
|
41
41
|
print(result.observation.echoed_message) # "Echo environment ready!"
|
|
42
42
|
|
|
43
43
|
# Send messages
|
|
44
|
-
result = await client.step(
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
result = await client.step(
|
|
45
|
+
CallToolAction(
|
|
46
|
+
tool_name="echo_message",
|
|
47
|
+
arguments={"message": "Hello, World!"},
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
print(result.observation.result) # "Hello, World!"
|
|
51
|
+
print(result.reward)
|
|
47
52
|
|
|
48
53
|
asyncio.run(main())
|
|
49
54
|
```
|
|
@@ -51,16 +56,21 @@ asyncio.run(main())
|
|
|
51
56
|
**Synchronous usage** is also supported via the `.sync()` wrapper:
|
|
52
57
|
|
|
53
58
|
```python
|
|
54
|
-
from echo_env import
|
|
59
|
+
from echo_env import CallToolAction, EchoEnv
|
|
55
60
|
|
|
56
61
|
# Use .sync() for synchronous context manager
|
|
57
62
|
with EchoEnv(base_url="https://openenv-echo-env.hf.space").sync() as client:
|
|
58
63
|
result = client.reset()
|
|
59
|
-
result = client.step(
|
|
60
|
-
|
|
64
|
+
result = client.step(
|
|
65
|
+
CallToolAction(
|
|
66
|
+
tool_name="echo_message",
|
|
67
|
+
arguments={"message": "Hello, World!"},
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
print(result.observation.result)
|
|
61
71
|
```
|
|
62
72
|
|
|
63
|
-
For a detailed quick start, check out the [docs page](https://meta-pytorch.org/OpenEnv/
|
|
73
|
+
For a detailed quick start, check out the [docs page](https://meta-pytorch.org/OpenEnv/auto_getting_started/index.html).
|
|
64
74
|
|
|
65
75
|
## OpenEnv on partner platforms:
|
|
66
76
|
|
|
@@ -78,12 +88,15 @@ In addition to making it easier for researchers and RL framework writers, we als
|
|
|
78
88
|
|
|
79
89
|
The OpenEnv CLI (`openenv`) provides commands to initialize new environments and deploy them to Hugging Face Spaces.
|
|
80
90
|
|
|
91
|
+
OpenEnv is openly governed by a technical committee that includes Hugging Face, Unsloth, Reflection, and Meta PyTorch. The committee coordinates project direction, major technical decisions, RFCs, and release planning through the public issue tracker, pull requests, and RFC process.
|
|
92
|
+
|
|
81
93
|
> ⚠️ **Early Development Warning** OpenEnv is currently in an experimental
|
|
82
94
|
> stage. You should expect bugs, incomplete features, and APIs that may change
|
|
83
|
-
> in future versions. The project welcomes bugfixes, but
|
|
84
|
-
>
|
|
85
|
-
>
|
|
86
|
-
>
|
|
95
|
+
> in future versions. The project welcomes bugfixes, but significant changes
|
|
96
|
+
> should be discussed before implementation so the technical committee and
|
|
97
|
+
> community can coordinate scope, compatibility, and release timing. It's
|
|
98
|
+
> recommended that you signal your intention to contribute in the issue tracker,
|
|
99
|
+
> either by filing a new issue or by claiming an existing one.
|
|
87
100
|
|
|
88
101
|
### RFCs
|
|
89
102
|
|
|
@@ -239,7 +252,7 @@ See [`envs/README.md`](envs/README.md) for a complete guide on building environm
|
|
|
239
252
|
|
|
240
253
|
To use an environment:
|
|
241
254
|
1. Install the client: `pip install git+https://huggingface.co/spaces/openenv/echo-env`
|
|
242
|
-
2. Import: `from echo_env import
|
|
255
|
+
2. Import: `from echo_env import CallToolAction, EchoEnv`
|
|
243
256
|
3. Use async (recommended) or sync API:
|
|
244
257
|
|
|
245
258
|
**Async (recommended):**
|
|
@@ -367,12 +380,12 @@ See the [Oumi example](https://github.com/oumi-ai/oumi/blob/main/notebooks/Oumi%
|
|
|
367
380
|
| [Atari Environment](envs/atari_env/README.md) | Classic Arcade Learning Environment tasks for RL benchmarking. |
|
|
368
381
|
| [FinRL Environment](envs/finrl_env/README.md) | Financial market simulations for algorithmic trading experiments. |
|
|
369
382
|
|
|
370
|
-
> Browse the full catalog of community environments at [meta-pytorch.org/OpenEnv/environments](https://meta-pytorch.org/OpenEnv/environments
|
|
383
|
+
> Browse the full catalog of community environments at [meta-pytorch.org/OpenEnv/environments](https://meta-pytorch.org/OpenEnv/environments.html).
|
|
371
384
|
|
|
372
385
|
## Community Support & Acknowledgments
|
|
373
|
-
This is an open and community-centric project. If you would like to add your
|
|
386
|
+
This is an open and community-centric project, governed in public by a technical committee that includes Hugging Face, Unsloth, Reflection, and Meta PyTorch. If you would like to add your project or organization here, please open a pull request for maintainer review.
|
|
374
387
|
|
|
375
|
-
Supporters include: Meta-PyTorch, Hugging Face, [Scaler AI Labs](https://scalerailabs.com), [Patronus AI](https://patronus.ai), [Surge AI](https://surgehq.ai), [LastMile AI](https://www.lastmileai.dev), Unsloth
|
|
388
|
+
Supporters include: Meta-PyTorch, Hugging Face, [Scaler AI Labs](https://scalerailabs.com), [Patronus AI](https://patronus.ai), [Surge AI](https://surgehq.ai), [LastMile AI](https://www.lastmileai.dev), Unsloth, Reflection, vLLM, SkyRL (UC-Berkeley), LightningAI, Axolotl AI, Stanford Scaling Intelligence Lab, Mithril, [OpenMined](https://openmined.org/), [Fleet AI](https://fleetai.com), [Halluminate](https://halluminate.ai/), [Turing](https://www.turing.com/), [Scale AI](https://scale.com/), [Scorecard](https://www.scorecard.io/) ..
|
|
376
389
|
|
|
377
390
|
And we'd also like to acknowledge the team at Farama Foundation as the OpenEnv API was heavily inspired by the work you all have done on Gymnasium. Cheers!
|
|
378
391
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "openenv"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "A unified framework for reinforcement learning environments"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -52,13 +52,13 @@ cli = [
|
|
|
52
52
|
docs = [
|
|
53
53
|
"sphinx==7.2.6",
|
|
54
54
|
"pytorch-sphinx-theme2",
|
|
55
|
-
"sphinxcontrib.katex==0.9.
|
|
56
|
-
"docutils>=0.18.1,<0.
|
|
55
|
+
"sphinxcontrib.katex==0.9.11",
|
|
56
|
+
"docutils>=0.18.1,<0.23",
|
|
57
57
|
"sphinx-design==0.6.1",
|
|
58
|
-
"sphinxcontrib-mermaid==
|
|
58
|
+
"sphinxcontrib-mermaid==2.0.2",
|
|
59
59
|
"myst-parser",
|
|
60
60
|
"sphinxext-opengraph",
|
|
61
|
-
"sphinx-sitemap==2.
|
|
61
|
+
"sphinx-sitemap==2.9.0",
|
|
62
62
|
"sphinx-gallery>=0.14.0",
|
|
63
63
|
"matplotlib",
|
|
64
64
|
"nest-asyncio",
|
|
@@ -17,7 +17,7 @@ __all__ = [
|
|
|
17
17
|
|
|
18
18
|
def _load_package_version() -> str:
|
|
19
19
|
"""Resolve the installed distribution version for the OpenEnv package."""
|
|
20
|
-
for distribution_name in ("openenv", "openenv"):
|
|
20
|
+
for distribution_name in ("openenv", "openenv-core"):
|
|
21
21
|
try:
|
|
22
22
|
return metadata.version(distribution_name)
|
|
23
23
|
except metadata.PackageNotFoundError:
|
|
@@ -369,14 +369,14 @@ class EnvironmentDiscovery:
|
|
|
369
369
|
logger.warning(f"Failed to get installed packages: {e}")
|
|
370
370
|
return environments
|
|
371
371
|
|
|
372
|
-
# Filter for openenv-* packages
|
|
372
|
+
# Filter for openenv-* environment packages; ignore the legacy core wheel.
|
|
373
373
|
for dist in distributions:
|
|
374
374
|
package_name = dist.metadata["Name"]
|
|
375
375
|
|
|
376
376
|
if not package_name.startswith("openenv-"):
|
|
377
377
|
continue
|
|
378
378
|
|
|
379
|
-
if package_name == "openenv":
|
|
379
|
+
if package_name == "openenv-core":
|
|
380
380
|
continue
|
|
381
381
|
|
|
382
382
|
# Get module name (e.g., "openenv-echo_env" → "echo_env")
|
|
@@ -14,7 +14,16 @@ following the Hugging Face CLI pattern.
|
|
|
14
14
|
import sys
|
|
15
15
|
|
|
16
16
|
import typer
|
|
17
|
-
from openenv.cli.commands import
|
|
17
|
+
from openenv.cli.commands import (
|
|
18
|
+
build,
|
|
19
|
+
collect,
|
|
20
|
+
fork,
|
|
21
|
+
init,
|
|
22
|
+
push,
|
|
23
|
+
serve,
|
|
24
|
+
skills,
|
|
25
|
+
validate,
|
|
26
|
+
)
|
|
18
27
|
|
|
19
28
|
# Create the main CLI app
|
|
20
29
|
app = typer.Typer(
|
|
@@ -47,6 +56,10 @@ app.add_typer(
|
|
|
47
56
|
name="skills",
|
|
48
57
|
help="Manage OpenEnv skills for AI assistants",
|
|
49
58
|
)
|
|
59
|
+
app.command(
|
|
60
|
+
name="collect",
|
|
61
|
+
help="Collect rollouts from a deployed OpenEnv environment",
|
|
62
|
+
)(collect.collect)
|
|
50
63
|
|
|
51
64
|
|
|
52
65
|
# Entry point for setuptools
|
|
@@ -11,6 +11,8 @@ This module provides functions to check if environments are properly
|
|
|
11
11
|
configured for multi-mode deployment (Docker, direct Python, notebooks, clusters).
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
+
import ast
|
|
15
|
+
import re
|
|
14
16
|
from pathlib import Path
|
|
15
17
|
from typing import Any
|
|
16
18
|
from urllib.parse import urlparse
|
|
@@ -426,6 +428,79 @@ def validate_running_environment(
|
|
|
426
428
|
return report
|
|
427
429
|
|
|
428
430
|
|
|
431
|
+
def _has_main_guard_call(app_content: str) -> bool:
|
|
432
|
+
"""Return True when the module calls main() under a __main__ guard."""
|
|
433
|
+
try:
|
|
434
|
+
tree = ast.parse(app_content)
|
|
435
|
+
except SyntaxError:
|
|
436
|
+
return (
|
|
437
|
+
"__name__" in app_content
|
|
438
|
+
and "__main__" in app_content
|
|
439
|
+
and "main(" in app_content
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
for node in ast.iter_child_nodes(tree):
|
|
443
|
+
if not isinstance(node, ast.If):
|
|
444
|
+
continue
|
|
445
|
+
|
|
446
|
+
test = node.test
|
|
447
|
+
if not (
|
|
448
|
+
isinstance(test, ast.Compare)
|
|
449
|
+
and isinstance(test.left, ast.Name)
|
|
450
|
+
and test.left.id == "__name__"
|
|
451
|
+
and len(test.ops) == 1
|
|
452
|
+
and isinstance(test.ops[0], ast.Eq)
|
|
453
|
+
and len(test.comparators) == 1
|
|
454
|
+
and isinstance(test.comparators[0], ast.Constant)
|
|
455
|
+
and test.comparators[0].value == "__main__"
|
|
456
|
+
):
|
|
457
|
+
continue
|
|
458
|
+
|
|
459
|
+
for guarded_node in node.body:
|
|
460
|
+
for candidate in ast.walk(guarded_node):
|
|
461
|
+
if isinstance(candidate, ast.Call):
|
|
462
|
+
func = candidate.func
|
|
463
|
+
if isinstance(func, ast.Name) and func.id == "main":
|
|
464
|
+
return True
|
|
465
|
+
|
|
466
|
+
return False
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
_OPENENV_RUNTIME_DEP_RE = re.compile(r"^openenv(?:\s*(?:$|[<>=!~@;])|\[)")
|
|
470
|
+
_LEGACY_OPENENV_CORE_DEP_RE = re.compile(r"^openenv-core(?:\s*(?:$|[<>=!~@;])|\[)")
|
|
471
|
+
_OPENENV_DOCKER_INSTALL_RE = re.compile(
|
|
472
|
+
r"(?<![a-z0-9_.-])openenv(?:\s*(?:$|[<>=!~@;])|\[)"
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def _dockerfile_installs_openenv_runtime(env_path: Path) -> bool:
|
|
477
|
+
"""Return True when a Docker deployment installs OpenEnv outside pyproject."""
|
|
478
|
+
for dockerfile_path in (
|
|
479
|
+
env_path / "server" / "Dockerfile",
|
|
480
|
+
env_path / "Dockerfile",
|
|
481
|
+
):
|
|
482
|
+
if not dockerfile_path.exists():
|
|
483
|
+
continue
|
|
484
|
+
|
|
485
|
+
try:
|
|
486
|
+
dockerfile = dockerfile_path.read_text(encoding="utf-8")
|
|
487
|
+
except OSError:
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
for line in dockerfile.splitlines():
|
|
491
|
+
stripped = line.strip().lower()
|
|
492
|
+
if not stripped or stripped.startswith("#"):
|
|
493
|
+
continue
|
|
494
|
+
if _OPENENV_DOCKER_INSTALL_RE.search(stripped):
|
|
495
|
+
return True
|
|
496
|
+
if "openenv-core" in stripped:
|
|
497
|
+
return True
|
|
498
|
+
if "git+https://github.com/meta-pytorch/openenv" in stripped:
|
|
499
|
+
return True
|
|
500
|
+
|
|
501
|
+
return False
|
|
502
|
+
|
|
503
|
+
|
|
429
504
|
def validate_multi_mode_deployment(env_path: Path) -> tuple[bool, list[str]]:
|
|
430
505
|
"""
|
|
431
506
|
Validate that an environment is ready for multi-mode deployment.
|
|
@@ -475,15 +550,12 @@ def validate_multi_mode_deployment(env_path: Path) -> tuple[bool, list[str]]:
|
|
|
475
550
|
|
|
476
551
|
# Check required dependencies
|
|
477
552
|
deps = [dep.lower() for dep in pyproject.get("project", {}).get("dependencies", [])]
|
|
478
|
-
has_openenv = any(
|
|
479
|
-
|
|
480
|
-
)
|
|
481
|
-
has_legacy_core = any(dep.startswith("openenv") for dep in deps)
|
|
553
|
+
has_openenv = any(_OPENENV_RUNTIME_DEP_RE.match(dep) for dep in deps)
|
|
554
|
+
has_legacy_core = any(_LEGACY_OPENENV_CORE_DEP_RE.match(dep) for dep in deps)
|
|
555
|
+
has_dockerfile_core = _dockerfile_installs_openenv_runtime(env_path)
|
|
482
556
|
|
|
483
|
-
if not (has_openenv or has_legacy_core):
|
|
484
|
-
issues.append(
|
|
485
|
-
"Missing required dependency: openenv>=0.2.0 (or openenv>=0.2.0)"
|
|
486
|
-
)
|
|
557
|
+
if not (has_openenv or has_legacy_core or has_dockerfile_core):
|
|
558
|
+
issues.append("Missing required dependency: openenv>=0.2.0")
|
|
487
559
|
|
|
488
560
|
# Check server/app.py exists
|
|
489
561
|
server_app = env_path / "server" / "app.py"
|
|
@@ -496,7 +568,7 @@ def validate_multi_mode_deployment(env_path: Path) -> tuple[bool, list[str]]:
|
|
|
496
568
|
issues.append("server/app.py missing main() function")
|
|
497
569
|
|
|
498
570
|
# Check if main() is callable
|
|
499
|
-
if
|
|
571
|
+
if not _has_main_guard_call(app_content):
|
|
500
572
|
issues.append(
|
|
501
573
|
"server/app.py main() function not callable (missing if __name__ == '__main__')"
|
|
502
574
|
)
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
+
import re
|
|
11
12
|
import shutil
|
|
12
13
|
import subprocess
|
|
13
14
|
import sys
|
|
@@ -21,6 +22,18 @@ from .._cli_utils import console
|
|
|
21
22
|
|
|
22
23
|
app = typer.Typer(help="Build Docker images for OpenEnv environments")
|
|
23
24
|
|
|
25
|
+
_OPENENV_RUNTIME_DEP_RE = re.compile(r"^openenv(?:\s*(?:$|[<>=!~@;])|\[)")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _is_openenv_runtime_dependency(dep: str) -> bool:
|
|
29
|
+
"""Return True for the OpenEnv runtime distribution, not openenv-* envs."""
|
|
30
|
+
normalized = dep.strip().lower()
|
|
31
|
+
return (
|
|
32
|
+
_OPENENV_RUNTIME_DEP_RE.match(normalized) is not None
|
|
33
|
+
or normalized.startswith("openenv-core")
|
|
34
|
+
or normalized.startswith("openenv_core")
|
|
35
|
+
)
|
|
36
|
+
|
|
24
37
|
|
|
25
38
|
def _detect_build_context(env_path: Path) -> tuple[str, Path, Path | None]:
|
|
26
39
|
"""
|
|
@@ -156,19 +169,15 @@ def _prepare_inrepo_build(env_path: Path, repo_root: Path, temp_dir: Path) -> Pa
|
|
|
156
169
|
pyproject = tomli.load(f)
|
|
157
170
|
deps = pyproject.get("project", {}).get("dependencies", [])
|
|
158
171
|
|
|
159
|
-
# Replace
|
|
172
|
+
# Replace OpenEnv package references with local source.
|
|
160
173
|
new_deps = []
|
|
161
174
|
for dep in deps:
|
|
162
|
-
if (
|
|
163
|
-
dep.startswith("openenv")
|
|
164
|
-
or dep.startswith("openenv_core")
|
|
165
|
-
or dep.startswith("openenv")
|
|
166
|
-
):
|
|
175
|
+
if _is_openenv_runtime_dependency(dep):
|
|
167
176
|
# Skip - we'll use local core
|
|
168
177
|
continue
|
|
169
178
|
new_deps.append(dep)
|
|
170
179
|
|
|
171
|
-
# Write back with local
|
|
180
|
+
# Write back with local OpenEnv reference
|
|
172
181
|
pyproject["project"]["dependencies"] = new_deps + [
|
|
173
182
|
"openenv @ file:///app/env/openenv"
|
|
174
183
|
]
|