File size: 2,208 Bytes
812398b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# 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.


from __future__ import annotations

try:
    from openenv.core.client_types import StepResult
    from openenv.core.env_client import EnvClient
    from openenv.core.env_server.types import State
except ImportError:
    from core.client_types import StepResult
    from core.env_client import EnvClient
    from core.env_server.types import State


from .models import GridWorldAction, GridWorldObservation, MoveAction


class GridWorldEnv(EnvClient[GridWorldAction, GridWorldObservation, State]):
    """
    A WebSocket-based client for interacting with the GridWorld environment.

    This client inherits from EnvClient and is configured with the
    GridWorld Pydantic models for automatic (de)serialization.
    """

    def step_move(self, move: MoveAction) -> StepResult[GridWorldObservation]:
        """
        Helper method to send a simple move action.

        Args:
            move: The MoveAction enum (e.g., MoveAction.UP)
        """
        action_payload = GridWorldAction(action=move)
        # 'super().step' comes from the base HTTPEnvClient
        return super().step(action_payload)

    # --- REQUIRED ABSTRACT METHODS (The Missing Pieces) ---

    def _step_payload(self, action: GridWorldAction) -> dict:
        """Convert the Pydantic action model to a dictionary."""
        # Uses Pydantic v2 'model_dump'. If this fails, try 'action.dict()'
        return action.model_dump()

    def _parse_result(self, data: dict) -> StepResult[GridWorldObservation]:
        """Convert the raw dictionary response into a typed StepResult."""
        return StepResult(
            observation=GridWorldObservation(
                **data["observation"], reward=data["reward"], done=data["done"]
            ),
            reward=data["reward"],
            done=data["done"],
            metadata=data.get("metadata"),
        )

    def _parse_state(self, data: dict) -> State:
        """Convert the raw state dictionary into a State object."""
        return State(**data)