File tree 5 files changed +25
-8
lines changed
5 files changed +25
-8
lines changed Original file line number Diff line number Diff line change @@ -42,6 +42,10 @@ workspace_base = "./workspace"
42
42
# If it's a folder, the session id will be used as the file name
43
43
# save_trajectory_path="./trajectories"
44
44
45
+ # Whether to save screenshots in the trajectory
46
+ # The screenshots are encoded and can make trajectory json files very large
47
+ # save_screenshots_in_trajectory = false
48
+
45
49
# Path to replay a trajectory, must be a file path
46
50
# If provided, trajectory will be loaded and replayed before the
47
51
# agent responds to any user instruction
Original file line number Diff line number Diff line change @@ -897,10 +897,13 @@ def set_initial_state(
897
897
# Always load from the event stream to avoid losing history
898
898
self ._init_history ()
899
899
900
- def get_trajectory (self ) -> list [dict ]:
900
+ def get_trajectory (self , include_screenshots : bool = False ) -> list [dict ]:
901
901
# state history could be partially hidden/truncated before controller is closed
902
902
assert self ._closed
903
- return [event_to_trajectory (event ) for event in self .state .history ]
903
+ return [
904
+ event_to_trajectory (event , include_screenshots )
905
+ for event in self .state .history
906
+ ]
904
907
905
908
def _init_history (self ) -> None :
906
909
"""Initializes the agent's history from the event stream.
Original file line number Diff line number Diff line change @@ -29,6 +29,7 @@ class AppConfig(BaseModel):
29
29
file_store: Type of file store to use.
30
30
file_store_path: Path to the file store.
31
31
save_trajectory_path: Either a folder path to store trajectories with auto-generated filenames, or a designated trajectory file path.
32
+ save_screenshots_in_trajectory: Whether to save screenshots in trajectory (in encoded image format).
32
33
replay_trajectory_path: Path to load trajectory and replay. If provided, trajectory would be replayed first before user's instruction.
33
34
workspace_base: Base path for the workspace. Defaults to `./workspace` as absolute path.
34
35
workspace_mount_path: Path to mount the workspace. Defaults to `workspace_base`.
@@ -58,6 +59,7 @@ class AppConfig(BaseModel):
58
59
file_store : str = Field (default = 'local' )
59
60
file_store_path : str = Field (default = '/tmp/openhands_file_store' )
60
61
save_trajectory_path : str | None = Field (default = None )
62
+ save_screenshots_in_trajectory : bool = Field (default = False )
61
63
replay_trajectory_path : str | None = Field (default = None )
62
64
workspace_base : str | None = Field (default = None )
63
65
workspace_mount_path : str | None = Field (default = None )
Original file line number Diff line number Diff line change @@ -210,9 +210,9 @@ def on_event(event: Event):
210
210
else :
211
211
file_path = config .save_trajectory_path
212
212
os .makedirs (os .path .dirname (file_path ), exist_ok = True )
213
- histories = controller .get_trajectory ()
213
+ histories = controller .get_trajectory (config . save_screenshots_in_trajectory )
214
214
with open (file_path , 'w' ) as f :
215
- json .dump (histories , f )
215
+ json .dump (histories , f , indent = 4 )
216
216
217
217
return state
218
218
Original file line number Diff line number Diff line change 5
5
from pydantic import BaseModel
6
6
7
7
from openhands .events import Event , EventSource
8
- from openhands .events .observation .observation import Observation
9
8
from openhands .events .serialization .action import action_from_dict
10
9
from openhands .events .serialization .observation import observation_from_dict
11
10
from openhands .events .serialization .utils import remove_fields
34
33
]
35
34
36
35
DELETE_FROM_TRAJECTORY_EXTRAS = {
37
- 'screenshot' ,
38
36
'dom_object' ,
39
37
'axtree_object' ,
40
38
'active_page_index' ,
44
42
'extra_element_properties' ,
45
43
}
46
44
45
+ DELETE_FROM_TRAJECTORY_EXTRAS_AND_SCREENSHOTS = DELETE_FROM_TRAJECTORY_EXTRAS | {
46
+ 'screenshot' ,
47
+ 'set_of_marks' ,
48
+ }
49
+
47
50
48
51
def event_from_dict (data ) -> 'Event' :
49
52
evt : Event
@@ -133,10 +136,15 @@ def event_to_dict(event: 'Event') -> dict:
133
136
return d
134
137
135
138
136
- def event_to_trajectory (event : 'Event' ) -> dict :
139
+ def event_to_trajectory (event : 'Event' , include_screenshots : bool = False ) -> dict :
137
140
d = event_to_dict (event )
138
141
if 'extras' in d :
139
- remove_fields (d ['extras' ], DELETE_FROM_TRAJECTORY_EXTRAS )
142
+ remove_fields (
143
+ d ['extras' ],
144
+ DELETE_FROM_TRAJECTORY_EXTRAS
145
+ if include_screenshots
146
+ else DELETE_FROM_TRAJECTORY_EXTRAS_AND_SCREENSHOTS ,
147
+ )
140
148
return d
141
149
142
150
You can’t perform that action at this time.
0 commit comments