Skip to content
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
3bf6a91
first save
wukaixingxp Nov 9, 2025
3fe46b3
remove unneeded
wukaixingxp Nov 9, 2025
156738e
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Nov 17, 2025
a4877bc
auto env rebased
wukaixingxp Nov 17, 2025
3ccd2a1
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Nov 18, 2025
0b15865
Test workflow
zkwentz Oct 18, 2025
e04a79a
refactor: migrate from dataclasses to Pydantic models
rycerzes Nov 17, 2025
f15fbdf
fix: specify type for state in get_state
rycerzes Nov 17, 2025
522b2ae
refactor: migrate echo_env to use Pydantic
rycerzes Nov 17, 2025
ff1bd7c
feat: endpoints to retrieve JSON schemas actions, observations, and sโ€ฆ
rycerzes Nov 18, 2025
82acaf2
feat: request and response models for reset and step endpoints
rycerzes Nov 18, 2025
04eb97b
feat: extra fields in reset and step request models for custom params
rycerzes Nov 18, 2025
4078161
chore: API docs and metadata extraction for action fields
rycerzes Nov 19, 2025
a9038dc
feat: env metadata
rycerzes Nov 19, 2025
5f2e451
delete registry
wukaixingxp Nov 19, 2025
304b5fc
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Nov 19, 2025
de0e7fd
auto_example working
wukaixingxp Nov 20, 2025
85a7f4c
refactor: Simplify AutoEnv/AutoAction API - rename from_docker_image/โ€ฆ
wukaixingxp Nov 20, 2025
98ee0b5
refactor: Remove AutoEnv.from_hub() method - not implemented yet
wukaixingxp Nov 20, 2025
d010ac6
fix: Update test assertions to match actual class names
wukaixingxp Nov 20, 2025
90b6c61
refactor: Remove redundant AutoAction.from_env() method
wukaixingxp Nov 20, 2025
f322f94
ready to merge
wukaixingxp Nov 20, 2025
dd8e48e
add src/envs/.discovery_cache.json to gitignore
wukaixingxp Nov 20, 2025
0ad8620
rm src/envs/.discovery_cache.json
wukaixingxp Nov 20, 2025
2468b23
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Nov 22, 2025
f1f8d29
revert back
wukaixingxp Nov 22, 2025
d673db7
use the instead
wukaixingxp Nov 22, 2025
3ec13a3
delete envs directory
burtenshaw Nov 25, 2025
0d59dc3
delete src/core
burtenshaw Nov 25, 2025
75af090
delete src/openenv_cli
burtenshaw Nov 25, 2025
3b5c245
add openenv cli
burtenshaw Nov 25, 2025
b4785a3
add openenv core
burtenshaw Nov 25, 2025
701e07a
add init shims
burtenshaw Nov 25, 2025
83dda10
move envs to root
burtenshaw Nov 25, 2025
3597636
update tests
burtenshaw Nov 25, 2025
2251f3a
grep update examples
burtenshaw Nov 25, 2025
d196fc1
update scripts with new envs path
burtenshaw Nov 25, 2025
f66f189
update gh actions
burtenshaw Nov 25, 2025
916dc30
update rfcs
burtenshaw Nov 25, 2025
0659195
update readme
burtenshaw Nov 25, 2025
1e7e398
update docs for restructure
burtenshaw Nov 25, 2025
a784df9
update project toml
burtenshaw Nov 25, 2025
7bd8559
simplify all optional group in toml
burtenshaw Nov 25, 2025
bbf9252
feat: serialization utilities and route config
rycerzes Nov 25, 2025
c4f20d7
chore: types
rycerzes Nov 25, 2025
0356bd1
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Nov 27, 2025
88a8292
now support hf space with autoenv
wukaixingxp Nov 28, 2025
fde4707
test auto working
wukaixingxp Dec 2, 2025
80996ee
add cache to avoid download twice
wukaixingxp Dec 2, 2025
2f18f5b
add example and test
wukaixingxp Dec 2, 2025
c51471b
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Dec 2, 2025
e612a1b
Merge pull request #225 from meta-pytorch/restructure-package
burtenshaw Dec 3, 2025
c4b0e6d
Merge branch 'main' into release
burtenshaw Dec 3, 2025
e58eb83
Merge branch 'main' into release
burtenshaw Dec 3, 2025
b254e20
Merge branch 'release' into pr/217-with-release
burtenshaw Dec 3, 2025
cd8b057
Merge pull request #217 from rycerzes/pydantic-migration
burtenshaw Dec 3, 2025
b78349f
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp Dec 10, 2025
46ef41c
Merge upstream release branch (#232) into autoenv
wukaixingxp Dec 10, 2025
46c4b23
Refactor: Move auto-discovery to src/openenv/auto and update imports
wukaixingxp Dec 10, 2025
60890b0
Rename from_name() to from_hub() in AutoEnv and AutoAction
wukaixingxp Dec 10, 2025
0329c91
Add pytest markers for auto-discovery tests
wukaixingxp Dec 10, 2025
35d7a4d
docs: Convert auto_env_example.py to comprehensive documentation
wukaixingxp Dec 10, 2025
0487d7e
test: Fix test module paths after refactoring
wukaixingxp Dec 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ outputs/
.uv/

*.backup*/
src/envs/.discovery_cache.json
311 changes: 311 additions & 0 deletions examples/auto_env_example.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this from the PR and add an md file in docs that explains how to use it.

Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
#!/usr/bin/env python3
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

"""
Comprehensive AutoEnv and AutoAction Example
=============================================

This example demonstrates how to use the AutoEnv and AutoAction classes
to automatically select and use environments without manual imports.

The AutoEnv/AutoAction API follows the HuggingFace pattern, making it easy
to work with different environments using a consistent interface.

Run this example with:
python examples/auto_env_example.py

Or test a specific environment:
python examples/auto_env_example.py --env coding
"""

import sys
import argparse
from pathlib import Path

from envs import AutoEnv, AutoAction


def example_basic_usage():
"""Example 1: Basic usage with AutoEnv and AutoAction"""
print("=" * 70)
print("Example 1: Basic Usage")
print("=" * 70)
print()

# Instead of:
# from envs.coding_env import CodingEnv, CodeAction
# client = CodingEnv.from_docker_image("coding-env:latest")

# You can now do:
print("Creating environment using AutoEnv...")
client = AutoEnv.from_name("coding-env")
print("โœ“ Environment created!")
print()

# Get the Action class automatically
print("Getting Action class using AutoAction...")
CodeAction = AutoAction.from_name("coding-env")
print(f"โœ“ Got Action class: {CodeAction.__name__}")
print()

# Use them together
print("Testing the environment:")
result = client.reset()
print(f" Reset: exit_code={result.observation.exit_code}")

action = CodeAction(code="print('Hello from AutoEnv!')")
step_result = client.step(action)
print(f" Step result: {step_result.observation.stdout.strip()}")

client.close()
print("โœ“ Environment closed")
print()


def example_alternative_syntax():
"""Example 2: Alternative syntax using environment key"""
print("=" * 70)
print("Example 2: Alternative Syntax")
print("=" * 70)
print()

# You can also use just the environment key
print("Getting Action class by environment name...")
CodeAction = AutoAction.from_name("coding")
print(f"โœ“ Got Action class: {CodeAction.__name__}")
print()

# Create instance
action = CodeAction(code="x = 5 + 3\nprint(f'Result: {x}')")
print(f"Created action: {action}")
print()


def example_list_environments():
"""Example 3: List all available environments"""
print("=" * 70)
print("Example 3: List Available Environments")
print("=" * 70)
print()

# List all available environments
AutoEnv.list_environments()
print()


def example_list_actions():
"""Example 4: List all available action classes"""
print("=" * 70)
print("Example 4: List Available Action Classes")
print("=" * 70)
print()

# List all available action classes
AutoAction.list_actions()
print()


def example_environment_info():
"""Example 5: Get detailed environment information"""
print("=" * 70)
print("Example 5: Environment Information")
print("=" * 70)
print()

# Get detailed info about a specific environment
env_name = "coding"
print(f"Information about '{env_name}' environment:")
print("-" * 70)

info = AutoEnv.get_env_info(env_name)
print(f" Description: {info['description']}")
print(f" Docker Image: {info['default_image']}")
print(f" Environment Class: {info['env_class']}")
print(f" Action Class: {info['action_class']}")
print(f" Observation Class: {info['observation_class']}")
print(f" Module: {info['module']}")
print(f" Version: {info['version']}")
print(f" Spec Version: {info['spec_version']}")
print()


def example_error_handling():
"""Example 6: Error handling with helpful messages"""
print("=" * 70)
print("Example 6: Error Handling")
print("=" * 70)
print()

# Try an unknown environment
print("Trying unknown environment 'nonexistent'...")
try:
env = AutoEnv.from_name("nonexistent-env")
except ValueError as e:
print(f"โœ“ Got expected error: {e}")
print()

# Try a typo - should suggest similar names
print("Trying typo 'cooding' (should suggest 'coding')...")
try:
env = AutoEnv.from_name("cooding-env")
except ValueError as e:
print(f"โœ“ Got helpful suggestion: {e}")
print()

# Try deprecated julia environment
print("Trying deprecated 'julia' environment...")
try:
env = AutoEnv.from_name("julia-env")
except ValueError as e:
print(f"โœ“ Got deprecation notice: {e}")
print()


def example_hf_space():
"""Example 7: Environments with special requirements"""
env = AutoEnv.from_name("wukaixingxp/coding-env-test")

# Reset environment
observation = env.reset()
print(f"Reset observation: {observation}")

# Get action class
CodeAction = AutoAction.from_name("wukaixingxp/coding-env-test")

# Create and execute action
action = CodeAction(code="print('Hello!')")
result = env.step(action) # Returns StepResult object, not tuple

# Access result properties
print(f"Observation: {result.observation}")
print(f"Reward: {result.reward}")
print(f"Done: {result.done}")

# Clean up
env.close()


def test_specific_environment(env_name: str):
"""Test a specific environment by name"""
print("=" * 70)
print(f"Testing {env_name} Environment")
print("=" * 70)
print()

try:
# Get environment info
info = AutoEnv.get_env_info(env_name)
image = info["default_image"]

print(f"Creating {env_name} environment...")
print(f" Docker image: {image}")
print()

# Create environment with extended timeout for slow containers
# Use the simplified name format
env_image_name = f"{env_name}-env" if not env_name.endswith("-env") else env_name
env = AutoEnv.from_name(env_image_name, wait_timeout=60.0)
print("โœ“ Environment created!")

# Get action class
ActionClass = AutoAction.from_name(env_name)
print(f"โœ“ Action class: {ActionClass.__name__}")
print()

# Test reset
print("Testing reset()...")
result = env.reset()
print(f"โœ“ Reset successful")
print()

# Get state
state = env.state()
print(f"State: episode_id={state.episode_id}, step_count={state.step_count}")
print()

# Close
env.close()
print("โœ“ Environment closed")
print()

print("=" * 70)
print(f"โœ“ {env_name} environment test passed!")
print("=" * 70)

return True

except Exception as e:
print(f"\nโŒ Error testing {env_name}: {e}")
import traceback

traceback.print_exc()
return False


def main():
"""Main function to run examples"""
parser = argparse.ArgumentParser(
description="AutoEnv and AutoAction Examples",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument(
"--env",
type=str,
help="Test a specific environment (e.g., coding, echo, git)",
)
parser.add_argument(
"--all-examples",
action="store_true",
help="Run all examples (without Docker)",
)

args = parser.parse_args()

if args.env:
# Test specific environment
success = test_specific_environment(args.env)
sys.exit(0 if success else 1)

elif args.all_examples:
# Run all examples (no Docker needed)
example_basic_usage() # This requires Docker
# Skip Docker examples, run info-only examples
example_alternative_syntax()
example_list_environments()
example_list_actions()
example_environment_info()
example_error_handling()
example_hf_space()

else:
# Show usage info and examples that don't need Docker
print("AutoEnv and AutoAction Examples")
print("=" * 70)
print()
print("This demonstrates the HuggingFace-style API for OpenEnv.")
print()
print("Usage:")
print(" python examples/auto_env_example.py --all-examples")
print(" python examples/auto_env_example.py --env coding")
print()
print("Running info examples (no Docker required)...")
print()

example_list_environments()
example_list_actions()
example_environment_info()
example_error_handling()
example_hf_space()

print()
print("To test with actual Docker environments:")
print(" python examples/auto_env_example.py --env coding")
print()


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions src/envs/__init__.py
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This directory will be removed in #232 .

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.

"""
OpenEnv Environments
====================

This package contains all environment implementations for OpenEnv.

Each environment provides:
- An environment client class (e.g., CodingEnv, AtariEnv)
- Action and Observation data classes
- Server implementations for the HTTP API

Auto Classes
------------
The AutoEnv and AutoAction classes provide a HuggingFace-style API for
automatically selecting the correct environment and action types based on
environment names.

Example:
>>> from envs import AutoEnv, AutoAction
>>>
>>> # Automatically detect and create environment from name
>>> client = AutoEnv.from_name("coding-env")
>>>
>>> # Get the corresponding Action class
>>> CodeAction = AutoAction.from_name("coding-env")
>>>
>>> # Use them together
>>> result = client.reset()
>>> action = CodeAction(code="print('Hello, AutoEnv!')")
>>> step_result = client.step(action)
>>> client.close()

Direct Imports
--------------
You can also import specific environment classes directly:

>>> from envs.coding_env import CodingEnv, CodeAction
>>> from envs.echo_env import EchoEnv, EchoAction
>>> from envs.git_env import GitEnv, GitAction
>>> # ... etc

List Available Environments
---------------------------
To see all available environments:

>>> AutoEnv.list_environments()
>>> AutoAction.list_actions()
"""

from .auto_env import AutoEnv
from .auto_action import AutoAction

__all__ = [
"AutoEnv",
"AutoAction",
]
Loading