Spaces:
Sleeping
Sleeping
| """ | |
| FastAPI application entrypoint for the Visual Memory environment. | |
| Uses OpenEnv's create_app() factory which auto-generates: | |
| - POST /reset, POST /step, GET /state, GET /health | |
| - WebSocket /ws for persistent connections | |
| - /web interface (when ENABLE_WEB_INTERFACE=true on HF Spaces) | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| from pathlib import Path | |
| from dotenv import load_dotenv | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from openenv.core.env_server.http_server import create_app | |
| load_dotenv(os.path.join(os.path.dirname(__file__), "..", ".env")) | |
| # Override the generic Quick Start with gym-specific content | |
| import openenv.core.env_server.web_interface as _wi # noqa: E402 | |
| _wi.DEFAULT_QUICK_START_MARKDOWN = """ | |
| ### How to use this environment | |
| **Visual Memory (Phantom Grid)** β a hidden-state reasoning gym. Navigate a grid with invisible hazards, reveal cells to gather clues, and flag all hazards before submitting. | |
| Use the **Playground** on the right. Type a **Tool Name** and **Arguments Json**, then click **Step**. | |
| --- | |
| #### 1. Start a session | |
| 1. Click **Reset** | |
| 2. `list_tools` β `{}` β discover all tools & params | |
| 3. `list_scenarios` β `{}` β see all 10 scenarios | |
| 4. `load_scenario` β `{"scenario_id": "directional_trap_8x8"}` | |
| #### 2. Explore the board | |
| - `get_board_view` β `{}` β render SVG board | |
| - `get_status` β `{}` β score, flags, steps | |
| - `reveal_cell` β `{"row": 0, "col": 0}` β uncover a cell *(costs 1 step)* | |
| - `inspect_region` β `{"center_row": 3, "center_col": 3, "radius": 1}` β peek without revealing *(costs 1 step)* | |
| - `recall_log` β `{}` β signals found so far | |
| - `get_action_history` β `{}` β full action log | |
| - `get_progress_stats` β `{}` β % revealed, steps left | |
| - `move_viewport` β `{"row": 5, "col": 5}` β move camera *(fog scenarios only)* | |
| > **Note:** `inspect_region` uses **center_row** / **center_col**, not row/col. | |
| #### 3. Flag hazards & submit | |
| - `flag_cell` β `{"row": 1, "col": 1}` β mark hazardous | |
| - `unflag_cell` β `{"row": 1, "col": 1}` β remove flag | |
| - `submit_solution` β `{"flagged_positions": "[[0,1],[2,3]]"}` β submit & end game | |
| > `submit_solution` also accepts optional `safe_positions`. | |
| #### 4. Trap tools (avoid!) | |
| These always fail with **-0.1 reward penalty**: | |
| - `auto_solve` β `{}` | |
| - `peek_hidden_cell` β `{"row": 2, "col": 2}` | |
| - `undo_last_action` β `{}` | |
| --- | |
| #### Scenarios (10) | |
| `directional_trap_8x8` Β· `ambiguous_cluster_10x10` Β· `partial_intel_9x9` Β· `cascading_deduction_11x11` Β· `safe_zone_identification_9x9` Β· `flash_fade_minefield_7x7` Β· `delayed_recall_keys_8x8` Β· `fog_labyrinth_10x10` Β· `fog_key_hunt_8x8` Β· `decoy_minefield_8x10` | |
| #### Connect from Python | |
| ```python | |
| from visual_memory import VisualMemoryAction, VisualMemoryEnv | |
| env = VisualMemoryEnv(base_url="http://localhost:8000") | |
| obs = env.reset() | |
| obs = await env.step(VisualMemoryAction( | |
| tool_name="load_scenario", | |
| arguments_json='{"scenario_id": "directional_trap_8x8"}' | |
| )) | |
| ``` | |
| For more, see the [OpenEnv documentation](https://meta-pytorch.org/OpenEnv/). | |
| """ | |
| try: | |
| from visual_memory.models import VisualMemoryAction, VisualMemoryObservation | |
| from visual_memory.server.memory_environment import MemoryEnvironment | |
| except ImportError: | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| from models import VisualMemoryAction, VisualMemoryObservation | |
| from server.memory_environment import MemoryEnvironment | |
| MAX_CONCURRENT_ENVS = int(os.getenv("MAX_CONCURRENT_ENVS", "8")) | |
| app = create_app( | |
| MemoryEnvironment, | |
| VisualMemoryAction, | |
| VisualMemoryObservation, | |
| env_name="visual_memory", | |
| max_concurrent_envs=MAX_CONCURRENT_ENVS, | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| def main(host: str = "0.0.0.0", port: int = 8000): | |
| import uvicorn | |
| uvicorn.run(app, host=host, port=port) | |
| if __name__ == "__main__": | |
| main() | |