Spaces:
Sleeping
Sleeping
| """OpenEnv server wrapper for the focus scheduling simulator.""" | |
| from __future__ import annotations | |
| from uuid import uuid4 | |
| from openenv.core.env_server.interfaces import Environment, EnvironmentMetadata | |
| from openenv.core.env_server.types import State | |
| from focus_resource_env import FocusResourceEnv | |
| try: | |
| from ..models import EngineerManagerAction, EngineerManagerObservation | |
| except ImportError: | |
| from models import EngineerManagerAction, EngineerManagerObservation | |
| class EngineerManagerEnvironment( | |
| Environment[EngineerManagerAction, EngineerManagerObservation, State] | |
| ): | |
| """Expose the scheduling simulator through the OpenEnv HTTP contract.""" | |
| SUPPORTS_CONCURRENT_SESSIONS = True | |
| def __init__( | |
| self, | |
| start_hour: str = "09:00", | |
| end_hour: str = "17:00", | |
| distraction_risk: float = 0.15, | |
| seed: int | None = 7, | |
| ) -> None: | |
| super().__init__() | |
| self._start_hour = start_hour | |
| self._end_hour = end_hour | |
| self._distraction_risk = distraction_risk | |
| self._seed = seed | |
| self._step_count = 0 | |
| self._episode_id = str(uuid4()) | |
| self._env = FocusResourceEnv( | |
| start_hour=start_hour, | |
| end_hour=end_hour, | |
| distraction_risk=distraction_risk, | |
| seed=seed, | |
| ) | |
| def reset( | |
| self, | |
| seed: int | None = None, | |
| episode_id: str | None = None, | |
| **_: object, | |
| ) -> EngineerManagerObservation: | |
| self._seed = self._seed if seed is None else seed | |
| self._episode_id = episode_id or str(uuid4()) | |
| self._step_count = 0 | |
| self._env = FocusResourceEnv( | |
| start_hour=self._start_hour, | |
| end_hour=self._end_hour, | |
| distraction_risk=self._distraction_risk, | |
| seed=self._seed, | |
| ) | |
| return self._to_observation(self._env.reset(), reward=0.0, done=False) | |
| def step( | |
| self, | |
| action: EngineerManagerAction, | |
| timeout_s: float | None = None, | |
| **_: object, | |
| ) -> EngineerManagerObservation: | |
| del timeout_s | |
| observation, reward, done, info = self._env.step( | |
| (action.target_slot, action.operation) | |
| ) | |
| self._step_count += 1 | |
| return self._to_observation(observation, reward=reward, done=done, info=info) | |
| def state(self) -> State: | |
| return State( | |
| episode_id=self._episode_id, | |
| step_count=self._step_count, | |
| current_slot=self._env.current_slot, | |
| done=self._env.current_slot >= self._env.timeline_length, | |
| ) | |
| def get_metadata(self) -> EnvironmentMetadata: | |
| return EnvironmentMetadata( | |
| name="Engineer Manager", | |
| description=( | |
| "Manage a workday by scheduling deep work, rescheduling meetings, " | |
| "and controlling communication noise." | |
| ), | |
| version="0.1.0", | |
| ) | |
| def _to_observation( | |
| self, | |
| observation: dict[str, object], | |
| *, | |
| reward: float | None, | |
| done: bool, | |
| info: dict[str, object] | None = None, | |
| ) -> EngineerManagerObservation: | |
| payload = dict(observation) | |
| payload["reward"] = reward | |
| payload["done"] = done | |
| payload["metadata"] = info or {} | |
| return EngineerManagerObservation.model_validate(payload) | |