-
Notifications
You must be signed in to change notification settings - Fork 241
Expand file tree
/
Copy pathminimal_example.py
More file actions
169 lines (143 loc) · 4.97 KB
/
minimal_example.py
File metadata and controls
169 lines (143 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python3
# type: ignore
import json
import os
import re
import subprocess
import time
SLEEP = 1.5
# Check if environment variables are set, if not provide helpful error message
required_env_vars = [
"SHOPPING",
"SHOPPING_ADMIN",
"REDDIT",
"GITLAB",
"MAP",
"WIKIPEDIA",
"HOMEPAGE",
]
missing_vars = []
for var in required_env_vars:
if not os.environ.get(var):
missing_vars.append(var)
if missing_vars:
print(
f"ERROR: Missing required environment variables: {', '.join(missing_vars)}"
)
print("\nPlease set the following environment variables before running:")
print("export SHOPPING='http://YOUR_WEBARENA_SERVER:7770'")
print("export SHOPPING_ADMIN='http://YOUR_WEBARENA_SERVER:7780/admin'")
print("export REDDIT='http://YOUR_WEBARENA_SERVER:9999'")
print("export GITLAB='http://YOUR_WEBARENA_SERVER:8023'")
print("export MAP='http://YOUR_WEBARENA_SERVER:3000'")
print(
"export WIKIPEDIA='http://YOUR_WEBARENA_SERVER:8888/wikipedia_en_all_maxi_2022-05/A/User:The_other_Kiwix_guy/Landing'"
)
print("export HOMEPAGE='PASS'")
print(
"\nReplace YOUR_WEBARENA_SERVER with your WebArena server's IP address."
)
print(
"Note: 18.208.187.221 is the map backend server, not the WebArena frontend server."
)
exit(1)
print("Environment variables are properly configured")
# First, run `python scripts/generate_test_data.py` to generate the config files
p = subprocess.run(
["python", "scripts/generate_test_data.py"], capture_output=True
)
# It will generate individual config file for each test example in config_files
assert os.path.exists("config_files/0.json")
# Make sure the URLs in the config files are replaced properly
with open("config_files/0.json", "r") as f:
config = json.load(f)
assert os.environ["SHOPPING_ADMIN"] in config["start_url"], (
os.environ["SHOPPING_ADMIN"],
config["start_url"],
)
print("Done generating config files with the correct URLs")
# run bash prepare.sh to save all account cookies, this only needs to be done once
subprocess.run(["bash", "prepare.sh"])
print("Done saving account cookies")
# Init an environment
from browser_env import (
Action,
ActionTypes,
ObservationMetadata,
ScriptBrowserEnv,
StateInfo,
Trajectory,
action2str,
create_id_based_action,
create_stop_action,
)
from evaluation_harness.evaluators import evaluator_router
# Init the environment
env = ScriptBrowserEnv(
headless=False,
slow_mo=100,
observation_type="accessibility_tree",
current_viewport_only=True,
viewport_size={"width": 1280, "height": 720},
)
# example 156 as an example
config_file = "config_files/156.json"
# maintain a trajectory
trajectory: Trajectory = []
# set the environment for the current example
obs, info = env.reset(options={"config_file": config_file})
actree_obs = obs["text"]
print(actree_obs)
# You should see some output like this:
"""
[4] RootWebArea 'Projects · Dashboard · GitLab' focused: True
[12] link 'Skip to content'
[28] link 'Dashboard'
[2266] button '' hasPopup: menu expanded: False
[63] textbox 'Search GitLab' required: False
[61] generic 'Use the shortcut key <kbd>/</kbd> to start a search'
[79] link 'Create new...'
[95] link 'Issues'
[97] generic '13 assigned issues'
[101] link 'Merge requests'
[104] generic '8 merge requests'"""
# save the state info to the trajectory
state_info: StateInfo = {"observation": obs, "info": info}
trajectory.append(state_info)
# Now let's try to perform the action of clicking the "Merge request" link
# As the element ID is dynamic each time, we use regex to match the element as the demo
match = re.search(r"\[(\d+)\] link 'Merge requests'", actree_obs).group(1)
# Create the action click [ELEMENT_ID]
click_action = create_id_based_action(f"click [{match}]")
# Add the action to the trajectory
trajectory.append(click_action)
# Step and get the new observation
obs, _, terminated, _, info = env.step(click_action)
# New observation
actree_obs = obs["text"]
print(actree_obs)
time.sleep(SLEEP)
state_info = {"observation": obs, "info": info}
trajectory.append(state_info)
# Next click "assign to you"
match = re.search(r"\[(\d+)\] link 'Assigned to you", actree_obs).group(1)
click_action = create_id_based_action(f"click [{match}]")
trajectory.append(click_action)
obs, _, terminated, _, info = env.step(click_action)
actree_obs = obs["text"]
print(actree_obs)
time.sleep(SLEEP)
state_info = {"observation": obs, "info": info}
trajectory.append(state_info)
# add a stop action to mark the end of the trajectory
trajectory.append(create_stop_action(""))
# Demo evaluation
evaluator = evaluator_router(config_file)
score = evaluator(
trajectory=trajectory,
config_file=config_file,
page=env.page,
client=env.get_page_client(env.page),
)
# as we manually perform the task, the task should be judged as correct
assert score == 1.0