-
Notifications
You must be signed in to change notification settings - Fork 138
add HuggingFace-style AutoEnv and AutoAction classes #222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wukaixingxp
wants to merge
63
commits into
meta-pytorch:main
Choose a base branch
from
wukaixingxp:autoenv
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 24 commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
3bf6a91
first save
wukaixingxp 3fe46b3
remove unneeded
wukaixingxp 156738e
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp a4877bc
auto env rebased
wukaixingxp 3ccd2a1
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp 0b15865
Test workflow
zkwentz e04a79a
refactor: migrate from dataclasses to Pydantic models
rycerzes f15fbdf
fix: specify type for state in get_state
rycerzes 522b2ae
refactor: migrate echo_env to use Pydantic
rycerzes ff1bd7c
feat: endpoints to retrieve JSON schemas actions, observations, and sโฆ
rycerzes 82acaf2
feat: request and response models for reset and step endpoints
rycerzes 04eb97b
feat: extra fields in reset and step request models for custom params
rycerzes 4078161
chore: API docs and metadata extraction for action fields
rycerzes a9038dc
feat: env metadata
rycerzes 5f2e451
delete registry
wukaixingxp 304b5fc
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp de0e7fd
auto_example working
wukaixingxp 85a7f4c
refactor: Simplify AutoEnv/AutoAction API - rename from_docker_image/โฆ
wukaixingxp 98ee0b5
refactor: Remove AutoEnv.from_hub() method - not implemented yet
wukaixingxp d010ac6
fix: Update test assertions to match actual class names
wukaixingxp 90b6c61
refactor: Remove redundant AutoAction.from_env() method
wukaixingxp f322f94
ready to merge
wukaixingxp dd8e48e
add src/envs/.discovery_cache.json to gitignore
wukaixingxp 0ad8620
rm src/envs/.discovery_cache.json
wukaixingxp 2468b23
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp f1f8d29
revert back
wukaixingxp d673db7
use the instead
wukaixingxp 3ec13a3
delete envs directory
burtenshaw 0d59dc3
delete src/core
burtenshaw 75af090
delete src/openenv_cli
burtenshaw 3b5c245
add openenv cli
burtenshaw b4785a3
add openenv core
burtenshaw 701e07a
add init shims
burtenshaw 83dda10
move envs to root
burtenshaw 3597636
update tests
burtenshaw 2251f3a
grep update examples
burtenshaw d196fc1
update scripts with new envs path
burtenshaw f66f189
update gh actions
burtenshaw 916dc30
update rfcs
burtenshaw 0659195
update readme
burtenshaw 1e7e398
update docs for restructure
burtenshaw a784df9
update project toml
burtenshaw 7bd8559
simplify all optional group in toml
burtenshaw bbf9252
feat: serialization utilities and route config
rycerzes c4f20d7
chore: types
rycerzes 0356bd1
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp 88a8292
now support hf space with autoenv
wukaixingxp fde4707
test auto working
wukaixingxp 80996ee
add cache to avoid download twice
wukaixingxp 2f18f5b
add example and test
wukaixingxp c51471b
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp e612a1b
Merge pull request #225 from meta-pytorch/restructure-package
burtenshaw c4b0e6d
Merge branch 'main' into release
burtenshaw e58eb83
Merge branch 'main' into release
burtenshaw b254e20
Merge branch 'release' into pr/217-with-release
burtenshaw cd8b057
Merge pull request #217 from rycerzes/pydantic-migration
burtenshaw b78349f
Merge branch 'meta-pytorch:main' into autoenv
wukaixingxp 46ef41c
Merge upstream release branch (#232) into autoenv
wukaixingxp 46c4b23
Refactor: Move auto-discovery to src/openenv/auto and update imports
wukaixingxp 60890b0
Rename from_name() to from_hub() in AutoEnv and AutoAction
wukaixingxp 0329c91
Add pytest markers for auto-discovery tests
wukaixingxp 35d7a4d
docs: Convert auto_env_example.py to comprehensive documentation
wukaixingxp 0487d7e
test: Fix test module paths after refactoring
wukaixingxp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -109,3 +109,4 @@ outputs/ | |
| .uv/ | ||
|
|
||
| *.backup*/ | ||
| src/envs/.discovery_cache.json | ||
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
| 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() |
|
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
| 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", | ||
| ] |
Oops, something went wrong.
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.
There was a problem hiding this comment.
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
docsthat explains how to use it.