Aswini-Kumar commited on
Commit
d51417c
Β·
verified Β·
1 Parent(s): 12d9933

feat: client.py - OpenEnv 5-step structure

Browse files
Files changed (1) hide show
  1. client.py +93 -0
client.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ client.py β€” Step 3: Create Client
3
+
4
+ EnvClient subclass for the Cross-Session Continuity environment.
5
+ Connects over HTTP/WebSocket to the OpenEnv FastAPI server.
6
+
7
+ Usage:
8
+ from client import ContinuityEnvClient, ContinuityAction
9
+
10
+ # Connect to local server
11
+ with ContinuityEnvClient(base_url="http://localhost:7860") as client:
12
+ obs = client.reset(difficulty="easy", seed=42)
13
+ result = client.step(ContinuityAction(tool="run_tests"))
14
+ print(result.observation.output)
15
+
16
+ # Connect to HF Space
17
+ with ContinuityEnvClient(
18
+ base_url="https://aswini-kumar-cross-session-continuity-env.hf.space"
19
+ ) as client:
20
+ obs = client.reset(difficulty="medium")
21
+ """
22
+
23
+ from typing import Dict
24
+
25
+ try:
26
+ from openenv.core import EnvClient
27
+ from openenv.core.client_types import StepResult
28
+ from openenv.core.env_server.types import State
29
+ _HAS_OPENENV = True
30
+ except ImportError:
31
+ _HAS_OPENENV = False
32
+ EnvClient = object # type: ignore[misc,assignment]
33
+ StepResult = None
34
+ State = None
35
+
36
+ try:
37
+ from models import ContinuityAction, ContinuityObservation
38
+ except ImportError:
39
+ from models import ContinuityAction, ContinuityObservation # type: ignore
40
+
41
+
42
+ class ContinuityEnvClient(EnvClient): # type: ignore[misc]
43
+ """
44
+ Client for the Cross-Session Continuity RL Environment.
45
+
46
+ Wraps the OpenEnv HTTP server with typed Action/Observation classes.
47
+
48
+ Session flow:
49
+ 1. reset() β†’ Session 1 starts
50
+ 2. step(read_file) β†’ read starter code
51
+ 3. step(write_file) β†’ write partial implementation
52
+ 4. step(run_tests) β†’ check progress
53
+ 5. step(write_handoff) β†’ end Session 1
54
+ 6. step(parse_handoff) β†’ Session 2 cold start
55
+ 7. step(write_file) β†’ complete implementation
56
+ 8. step(submit) β†’ scored; done=True
57
+ """
58
+
59
+ def _step_payload(self, action: ContinuityAction) -> Dict:
60
+ return {
61
+ "tool": action.tool,
62
+ "path": action.path,
63
+ "content": action.content,
64
+ }
65
+
66
+ def _parse_result(self, payload: Dict) -> "StepResult":
67
+ obs_data = payload.get("observation", {})
68
+ observation = ContinuityObservation(
69
+ output=obs_data.get("output", ""),
70
+ session=obs_data.get("session", 1),
71
+ passed=obs_data.get("passed", 0),
72
+ total=obs_data.get("total", 0),
73
+ auxiliary_reward=obs_data.get("auxiliary_reward", 0.0),
74
+ error=obs_data.get("error", ""),
75
+ warning=obs_data.get("warning", ""),
76
+ message=obs_data.get("message", ""),
77
+ retries_left=obs_data.get("retries_left", 3),
78
+ done=payload.get("done", False),
79
+ reward=payload.get("reward", 0.0),
80
+ )
81
+ from openenv.core.client_types import StepResult as SR
82
+ return SR(
83
+ observation=observation,
84
+ reward=payload.get("reward", 0.0),
85
+ done=payload.get("done", False),
86
+ )
87
+
88
+ def _parse_state(self, payload: Dict) -> "State":
89
+ from openenv.core.env_server.types import State as S
90
+ return S(
91
+ episode_id=payload.get("episode_id", ""),
92
+ step_count=payload.get("step_count", 0),
93
+ )