From 334de283789e1ba250d19b5be00701cfade21f87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:34:39 +0000 Subject: [PATCH 1/4] Initial plan From 228da4f9b856c9a0c98f88c55e103b2ae15a0c20 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:39:04 +0000 Subject: [PATCH 2/4] Fix bare except and test documentation mismatch - Changed bare except to except Exception as e with logging - Updated README to accurately reflect 9 smoke tests instead of 105 - Removed misleading test references from test file docstring - All tests pass (8 passed, 1 skipped) Co-authored-by: Darktex <890615+Darktex@users.noreply.github.com> --- src/envs/android_env/README.md | 71 +++++++++---------- .../android_env/server/android_environment.py | 4 +- tests/envs/test_android_env.py | 19 ++--- 3 files changed, 43 insertions(+), 51 deletions(-) diff --git a/src/envs/android_env/README.md b/src/envs/android_env/README.md index 586d93aea2..3f8ad78d6c 100644 --- a/src/envs/android_env/README.md +++ b/src/envs/android_env/README.md @@ -170,47 +170,46 @@ pixels = np.ndarray((1920, 1080, 3), dtype=np.uint8, buffer=shm.buf) # pixels now points directly to emulator's screen buffer ``` -#### 5. **Comprehensive Test Suite** (tests/ - 105 tests, 90% coverage) - -**Unit Tests** (63 tests - no dependencies): -- `test_models.py`: 18 tests - RFC 004 compliance, action/observation validation -- `test_gestures.py`: 13 tests - Gesture primitives, ADB commands, escaping -- `test_edge_cases.py`: 32 tests - Boundaries, unicode, special chars, long strings - -**Integration Tests** (42 tests - require Docker): -- `test_environment_mocked.py`: 18 tests - Action conversion, coordinate clipping, ADB execution, workflows -- `test_emulator_pool.py`: 24 tests - Thread safety, pool exhaustion, cleanup, multi-task - -**What We Test**: -- ✅ Coordinate pass-through (x=0.5, y=0.5 → touch_position=[0.5, 0.5]) -- ✅ Coordinate clipping (x=1.5 → 1.0, y=-0.5 → 0.0) -- ✅ ADB execution (execute_adb_call actually called with correct commands) -- ✅ Gesture sequencing (tap=2 primitives, swipe=10+ primitives) -- ✅ Shared memory (obs.screen_image = "shm://..." when enabled) -- ✅ Observation decode (base64 → valid image with correct dimensions) -- ✅ Multi-action workflows (tap → swipe → text → button in sequence) -- ✅ Multi-episode lifecycle (reset → steps → reset with new episode_id) -- ✅ Thread safety (64 workers competing for 5 emulators) -- ✅ Text escaping (quotes, unicode 世界, emojis 🌍, shell chars $;|) +#### 5. **Test Suite** (9 smoke tests) + +**Current Status**: This PR includes smoke tests to verify basic functionality. Full integration tests requiring Docker and android_env will be added in a future PR. + +**Smoke Tests** (9 tests - in `tests/envs/test_android_env.py`): +- `test_android_models_import`: Verify AndroidAction and AndroidObservation models can be imported +- `test_android_action_all_types`: Test creation of all 10 action types (tap, swipe, long_press, etc.) +- `test_android_observation_structure`: Verify observation structure and fields +- `test_gesture_builder_tap`: Test GestureBuilder tap primitive (TOUCH + LIFT) +- `test_gesture_builder_swipe`: Test GestureBuilder swipe with interpolation +- `test_adb_commands_text_input`: Test ADB text input command generation with escaping +- `test_adb_commands_keyevent`: Test ADB keyevent command generation (HOME, BACK) +- `test_coordinate_clipping`: Test out-of-bounds coordinate handling +- `test_android_environment_full_integration`: Placeholder for future Docker-based tests (skipped) + +**What These Tests Verify**: +- ✅ RFC 004 compliance (ToolCallAction pattern) +- ✅ All 10 action types can be created +- ✅ Observation structure is correct +- ✅ GestureBuilder generates correct primitives (TOUCH, REPEAT, LIFT) +- ✅ ADB commands are properly formatted +- ✅ Text escaping for spaces and special characters +- ✅ Coordinate handling for gestures **Run tests**: ```bash -# Unit tests (instant, no dependencies) -cd src/envs/android_env/tests -./run_unit_tests.sh -# 63/63 PASSED ✅ - -# Integration tests (require Docker with android_env) -./run_docker_tests.sh -# 42/42 PASSED ✅ +# Run all smoke tests +pytest tests/envs/test_android_env.py -v + +# Run specific test +pytest tests/envs/test_android_env.py::test_android_models_import -v ``` -**Coverage**: -- models.py: ~95% -- gestures.py: ~90% -- emulator_pool.py: ~85% -- android_environment.py: ~90% -- **Overall: ~90%** (up from 58% before testing push) +**Future Work**: +Full integration testing (105 tests with ~90% coverage) will require: +- Docker with android_env installed +- Android SDK and emulator setup +- Unit tests for models, gestures, edge cases (63 tests) +- Integration tests for environment and pool (42 tests) +- These will be added in a follow-up PR once the basic environment is validated #### 6. **OpenEnv RFC Compliance** - **RFC 001**: HTTP-based environment server ✅ diff --git a/src/envs/android_env/server/android_environment.py b/src/envs/android_env/server/android_environment.py index 808c5afe42..c00a57f1b7 100644 --- a/src/envs/android_env/server/android_environment.py +++ b/src/envs/android_env/server/android_environment.py @@ -206,8 +206,8 @@ def close(self) -> None: try: self._shared_mem.close() self._shared_mem.unlink() - except: - pass + except Exception as e: + logger.warning(f"Failed to clean up shared memory: {e}") logger.info("Android environment closed") def _convert_action_to_gestures(self, action: AndroidAction) -> List[dict]: diff --git a/tests/envs/test_android_env.py b/tests/envs/test_android_env.py index 931bc2ceef..94bca2cce7 100644 --- a/tests/envs/test_android_env.py +++ b/tests/envs/test_android_env.py @@ -1,16 +1,9 @@ -"""Integration test for Android environment. - -This test verifies that the Android environment can be imported and basic -functionality works. Full integration tests with emulator are in -src/envs/android_env/tests/. - -Note: This is a smoke test. Full test coverage (105 tests, 90% coverage) -is in src/envs/android_env/tests/: -- test_models.py: 18 unit tests -- test_gestures.py: 13 unit tests -- test_edge_cases.py: 32 unit tests -- test_environment_mocked.py: 18 integration tests -- test_emulator_pool.py: 24 integration tests +"""Smoke tests for Android environment. + +This test suite verifies that the Android environment can be imported and basic +functionality works. These are smoke tests that don't require Docker or android_env. + +Full integration tests with Docker and android_env will be added in a future PR. """ import pytest From f8867cc545dafd34a912212bedcf3f751d03d89d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:40:21 +0000 Subject: [PATCH 3/4] Add OpenEnv principles alignment documentation - Document reward computation compliance (PRINCIPLES.md:31) - Document agent isolation from reset (INVARIANTS.md:45-57) - Clarify HTTP vs WebSocket status and future migration plan - Address alignment review feedback items #5 and #6 Co-authored-by: Darktex <890615+Darktex@users.noreply.github.com> --- src/envs/android_env/README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/envs/android_env/README.md b/src/envs/android_env/README.md index 3f8ad78d6c..a86bfbc9fb 100644 --- a/src/envs/android_env/README.md +++ b/src/envs/android_env/README.md @@ -217,6 +217,37 @@ Full integration testing (105 tests with ~90% coverage) will require: - **RFC 003**: Environment lifecycle (reset/step/state) ✅ - **RFC 004**: ToolCallAction pattern (tool_name + parameters) ✅ +#### 7. **OpenEnv Principles Alignment** + +**Rewards Inside Environment** (PRINCIPLES.md:31, INVARIANTS.md:64-67): +- ✅ **Compliance**: Rewards are computed entirely within the environment boundary +- **How**: The `AndroidEnvironment` wrapper delegates to `android_env.step()`, which: + 1. Executes the action in the emulator + 2. Checks task completion criteria (defined in task textproto) + 3. Computes reward based on task-specific logic + 4. Returns reward as part of the timestep +- **Agent Perspective**: Agent receives `AndroidObservation.reward` field but cannot influence reward computation +- **Location**: All reward logic lives in android_env's task definitions (external to agent) + +**Agent Isolation from Reset** (INVARIANTS.md:45-57): +- ✅ **Compliance**: Agents cannot trigger environment resets +- **Architecture**: + - **Orchestration Layer**: HTTP/WebSocket endpoints (`/reset`, `/step`) - controlled by training loop + - **Agent Layer**: Receives observations and returns actions only (no reset capability) + - **No MCP Tools Exposed**: This environment does not expose any MCP tools to agents +- **How Isolation Works**: + 1. Agent interacts via `step(action)` only + 2. Training orchestrator calls `reset()` between episodes + 3. `android_env` library does not expose reset to action space + 4. EmulatorPool manages lifecycle (agent has no access) +- **Dual API Boundary**: Training code uses HTTP/WebSocket API (has reset). Agent code uses action-only interface (no reset). + +**Note on HTTP vs WebSocket** (INVARIANTS.md:69-73): +- ⚠️ **Current State**: This PR implements HTTP-only communication +- **Reason**: INVARIANTS.md:73 acknowledges "both protocols are currently available" during transition +- **Future Work**: Migration to WebSocket will be needed when OpenEnv completes WebSocket-only transition (see PR #252) +- **Impact**: No architectural changes needed - just swap HTTPEnvClient for WebSocketEnvClient + ### ⚠️ Limitations and Future Work #### What We Intentionally Skipped (Not in Spec) From a8d99da96ad5a3d0ea5a7d97e26135171104848b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:41:16 +0000 Subject: [PATCH 4/4] Clarify test docstring - tests import modules without Docker Tests verify module imports and basic functionality without requiring Docker container or running Android emulator. Co-authored-by: Darktex <890615+Darktex@users.noreply.github.com> --- tests/envs/test_android_env.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/envs/test_android_env.py b/tests/envs/test_android_env.py index 94bca2cce7..98fea5afea 100644 --- a/tests/envs/test_android_env.py +++ b/tests/envs/test_android_env.py @@ -1,7 +1,7 @@ """Smoke tests for Android environment. -This test suite verifies that the Android environment can be imported and basic -functionality works. These are smoke tests that don't require Docker or android_env. +This test suite verifies that the Android environment modules can be imported and basic +functionality works without requiring a Docker container or running Android emulator. Full integration tests with Docker and android_env will be added in a future PR. """