Spaces:
Running
Running
Download client.py from RAc1928/second-brain-env: direct link, hf CLI and curl.
- Browser
- Download file 1.98 kB
-
https://huggingface.co/spaces/RAc1928/second-brain-env/resolve/main/client.py
- Command line
-
hf download hf://spaces/RAc1928/second-brain-env/client.py
-
curl -L -o client.py https://huggingface.co/spaces/RAc1928/second-brain-env/resolve/main/client.py
1.98 kB
| """ | |
| Second Brain Environment — WebSocket Client | |
| Connects to the running server and exposes reset()/step()/state(). | |
| FIX: The openenv HTTP layer deserializes the observation using the Pydantic | |
| schema, but `reward` has a default of 0.0 — so if the server response omits | |
| the field (or it gets stripped by the base class serializer) it silently | |
| resets to 0. The fix: read `reward` from the raw response dict BEFORE | |
| constructing the typed observation, then attach it as `result.reward` so | |
| inference.py can read it independently of the observation object. | |
| """ | |
| from openenv.core.env_client import EnvClient | |
| from models import SecondBrainAction, SecondBrainObservation, SecondBrainState | |
| from types import SimpleNamespace | |
| class SecondBrainEnv(EnvClient): | |
| action_type = SecondBrainAction | |
| observation_type = SecondBrainObservation | |
| state_type = SecondBrainState | |
| def __init__(self, base_url: str = "http://localhost:8000", task_name: str = "note_categorization"): | |
| super().__init__(base_url=base_url) | |
| self._task_name = task_name | |
| def _step_payload(self, action: SecondBrainAction) -> dict: | |
| return action.model_dump() | |
| def _parse_result(self, data: dict): | |
| obs_data = data.get("observation", {}) | |
| # Pull reward out of the raw dict BEFORE Pydantic touches it. | |
| # The base EnvClient may not forward all fields — this is the only | |
| # reliable place to read it. | |
| reward = float(obs_data.get("reward", 0.0)) | |
| obs = self.observation_type(**obs_data) | |
| done = data.get("done", False) | |
| # Attach reward at the top level of the result so inference.py can | |
| # read result.reward without depending on obs.reward surviving intact. | |
| return SimpleNamespace( | |
| observation=obs, | |
| done=done, | |
| reward=reward, # ← top-level, always correct | |
| ) | |
| def _parse_state(self, data: dict): | |
| return self.state_type(**data) |