rishitha14 commited on
Commit
64ba330
·
verified ·
1 Parent(s): b178e29

Updated client.py

Browse files
Files changed (1) hide show
  1. client.py +13 -64
client.py CHANGED
@@ -1,48 +1,20 @@
1
- """
2
- client.py — xsecure environment client.
3
- Extends openenv-core's HTTPEnvClient — WebSocket, sync wrapper,
4
- from_hub() and from_docker_image() all come for free.
5
-
6
- Usage (async):
7
- async with IncidentResponseEnv(base_url="http://localhost:7860") as env:
8
- obs = await env.reset(task_id=1)
9
- result = await env.step(IncidentAction(action_type="analyze_log", target="L001"))
10
-
11
- Usage (sync):
12
- with IncidentResponseEnv(base_url="http://localhost:7860").sync() as env:
13
- obs = env.reset(task_id=1)
14
- result = env.step(IncidentAction(action_type="analyze_log", target="L001"))
15
-
16
- Usage (Docker — auto-pulls and runs):
17
- env = await IncidentResponseEnv.from_docker_image("xsecure:latest")
18
- async with env:
19
- obs = await env.reset(task_id=1)
20
- """
21
-
22
  from __future__ import annotations
23
-
24
- from dataclasses import asdict
25
  from typing import Any, Dict
26
 
27
- try:
28
- from openenv_core.http_env_client import HTTPEnvClient
29
- from openenv_core.types import StepResult
30
- except ImportError:
31
- from core.http_env_client import HTTPEnvClient
32
- from core.types import StepResult
33
 
34
  from models import IncidentAction, IncidentObservation, IncidentState
35
 
36
-
37
- class IncidentResponseEnv(HTTPEnvClient[IncidentAction, IncidentObservation]):
38
  """
39
  Client for the xsecure Incident Response environment.
40
- Inherits reset(), step(), state(), sync(), from_hub(), from_docker_image()
41
- from openenv-core's HTTPEnvClient.
42
  """
43
 
44
  def _step_payload(self, action: IncidentAction) -> Dict[str, Any]:
45
- """Serialize action to JSON dict for the HTTP /step endpoint."""
46
  return {
47
  "action_type": action.action_type,
48
  "target": action.target,
@@ -51,43 +23,20 @@ class IncidentResponseEnv(HTTPEnvClient[IncidentAction, IncidentObservation]):
51
  def _parse_result(self, payload: Dict[str, Any]) -> StepResult:
52
  """Deserialize HTTP response into a typed StepResult."""
53
  obs_data = payload.get("observation", {})
54
-
55
- # Re-hydrate nested dataclass lists
56
- from models import LogEntry, AlertEntry, ServiceStatus
57
- logs = [LogEntry(**l) for l in obs_data.get("logs", [])]
58
- alerts = [AlertEntry(**a) for a in obs_data.get("alerts", [])]
59
- services = [ServiceStatus(**s) for s in obs_data.get("services", [])]
60
-
61
- obs = IncidentObservation(
62
- logs=logs,
63
- alerts=alerts,
64
- services=services,
65
- active_users=obs_data.get("active_users", []),
66
- step_count=obs_data.get("step_count", 0),
67
- reward=obs_data.get("reward", 0.0),
68
- done=obs_data.get("done", False),
69
- info=obs_data.get("info", {}),
70
- last_action_result=obs_data.get("last_action_result", ""),
71
- )
72
 
73
  return StepResult(
74
  observation=obs,
75
  reward=payload.get("reward", 0.0),
76
  done=payload.get("done", False),
77
- info=payload.get("info", {}),
78
  )
79
 
80
  def _parse_state(self, payload: Dict[str, Any]) -> IncidentState:
81
  """Deserialize /state response into IncidentState."""
82
  data = payload.get("state", payload)
83
- return IncidentState(**{
84
- k: v for k, v in data.items()
85
- if k in IncidentState.__dataclass_fields__
86
- })
87
-
88
-
89
- # ---------------------------------------------------------------------------
90
- # Backward-compatible StepResult re-export
91
- # ---------------------------------------------------------------------------
92
-
93
- __all__ = ["IncidentResponseEnv", "StepResult"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from __future__ import annotations
 
 
2
  from typing import Any, Dict
3
 
4
+ # Standard OpenEnv imports
5
+ from openenv_core import EnvClient
6
+ from openenv_core.client_types import StepResult
 
 
 
7
 
8
  from models import IncidentAction, IncidentObservation, IncidentState
9
 
10
+ class IncidentResponseEnv(EnvClient[IncidentAction, IncidentObservation, IncidentState]):
 
11
  """
12
  Client for the xsecure Incident Response environment.
13
+ Inherits all core methods (reset, step, state) from HTTPEnvClient.
 
14
  """
15
 
16
  def _step_payload(self, action: IncidentAction) -> Dict[str, Any]:
17
+ """Serialize action for the /step endpoint."""
18
  return {
19
  "action_type": action.action_type,
20
  "target": action.target,
 
23
  def _parse_result(self, payload: Dict[str, Any]) -> StepResult:
24
  """Deserialize HTTP response into a typed StepResult."""
25
  obs_data = payload.get("observation", {})
26
+
27
+ # Leverage Pydantic's ability to handle the dictionary directly
28
+ obs = IncidentObservation(**obs_data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  return StepResult(
31
  observation=obs,
32
  reward=payload.get("reward", 0.0),
33
  done=payload.get("done", False),
34
+ #info=payload.get("info", {}),
35
  )
36
 
37
  def _parse_state(self, payload: Dict[str, Any]) -> IncidentState:
38
  """Deserialize /state response into IncidentState."""
39
  data = payload.get("state", payload)
40
+ # Filters keys to match the Pydantic model fields
41
+ valid_fields = set(IncidentState.model_fields.keys())
42
+ return IncidentState(**{k: v for k, v in data.items() if k in valid_fields})