defender-env / client.py
its-wasp's picture
Upload folder using huggingface_hub
bf5fd17 verified
Raw
History Blame Contribute Delete
2.15 kB
"""Defender RL Environment Client."""
from typing import Dict
from openenv.core import EnvClient
from openenv.core.client_types import StepResult
from openenv.core.env_server.types import State
from .models import DefenderAction, DefenderObservation
class DefenderEnv(EnvClient[DefenderAction, DefenderObservation, State]):
"""Client for the Defender RL Environment.
Maintains a persistent WebSocket connection. Each client instance gets its
own dedicated environment session on the server (factory mode + concurrency).
Example:
>>> with DefenderEnv(base_url="http://localhost:8000") as client:
... result = client.reset()
... print(result.observation.attacker_message)
... result = client.step(DefenderAction(response="I can't share that."))
... print(result.reward, result.done)
"""
def _step_payload(self, action: DefenderAction) -> Dict:
return {"response": action.response}
def _parse_result(self, payload: Dict) -> StepResult[DefenderObservation]:
obs_data = payload.get("observation", {})
observation = DefenderObservation(
attacker_message=obs_data.get("attacker_message", ""),
conversation_history=obs_data.get("conversation_history", []),
turn_index=obs_data.get("turn_index", 0),
system_prompt=obs_data.get("system_prompt", ""),
scenario_id=obs_data.get("scenario_id", ""),
secret_type=obs_data.get("secret_type", ""),
attacker_id=obs_data.get("attacker_id", ""),
leak_occurred=obs_data.get("leak_occurred", False),
leaked_piece=obs_data.get("leaked_piece", ""),
done=payload.get("done", False),
reward=payload.get("reward"),
)
return StepResult(
observation=observation,
reward=payload.get("reward"),
done=payload.get("done", False),
)
def _parse_state(self, payload: Dict) -> State:
return State(
episode_id=payload.get("episode_id"),
step_count=payload.get("step_count", 0),
)