Spaces:
Sleeping
Sleeping
| from typing import Any, Dict | |
| from uuid import uuid4 | |
| from pydantic import BaseModel, Field | |
| from openenv.core.env_server.interfaces import Environment | |
| from openenv.core.env_server.types import State | |
| from env.action_utils import coerce_grid_action | |
| from env.environment import EcoGridEnv | |
| from models.schemas import GridAction, GridState | |
| class ServerObservation(BaseModel): | |
| observation: GridState | |
| reward: float | |
| done: bool | |
| info: Dict[str, Any] = Field(default_factory=dict) | |
| class ServerEcoGridEnv(Environment): | |
| """ | |
| Wrapper around EcoGridEnv to strictly satisfy openenv.core.Environment | |
| interfaces without breaking the local UI/CLI scripts. | |
| """ | |
| SUPPORTS_CONCURRENT_SESSIONS: bool = True | |
| def __init__(self): | |
| self._env = EcoGridEnv() | |
| self._oe_state = State(episode_id=str(uuid4()), step_count=0) | |
| self._current_task = "easy" | |
| def reset(self) -> ServerObservation: | |
| self._oe_state = State(episode_id=str(uuid4()), step_count=0) | |
| # Default reset. The specific task is usually set prior, or defaults to easy. | |
| initial_state = self._env.reset(task=self._current_task, seed=42) | |
| return ServerObservation( | |
| observation=initial_state, | |
| reward=0.0, | |
| done=False, | |
| info={} | |
| ) | |
| def step(self, action: GridAction | dict) -> ServerObservation: | |
| self._oe_state.step_count += 1 | |
| safe_default = GridAction( | |
| renewable_ratio=0.5, | |
| fossil_ratio=0.5, | |
| battery_action=0.0, | |
| ) | |
| parsed_action, action_warning = coerce_grid_action( | |
| action_like=action, | |
| default_action=safe_default, | |
| ) | |
| try: | |
| result = self._env.step(parsed_action) | |
| except Exception as exc: | |
| # Never crash the API on malformed/edge payloads. | |
| fallback_state = self._env.state() if not self._env.is_done else self._env.reset() | |
| return ServerObservation( | |
| observation=fallback_state, | |
| reward=0.001, | |
| done=self._env.is_done, | |
| info={ | |
| "error": f"step_failed:{type(exc).__name__}", | |
| "detail": str(exc), | |
| "action_warning": action_warning or "step_exception_fallback", | |
| }, | |
| ) | |
| info = dict(result.info) | |
| if action_warning: | |
| info["action_warning"] = action_warning | |
| return ServerObservation( | |
| observation=result.observation, | |
| reward=result.reward, | |
| done=result.done, | |
| info=info, | |
| ) | |
| def state(self) -> State: | |
| return self._oe_state | |