browsergym-workarena 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. browsergym/workarena/__init__.py +13 -1
  2. browsergym/workarena/api/category.py +74 -0
  3. browsergym/workarena/api/change_request.py +87 -0
  4. browsergym/workarena/api/computer_asset.py +90 -0
  5. browsergym/workarena/api/cost_center.py +19 -0
  6. browsergym/workarena/api/expense_line.py +89 -0
  7. browsergym/workarena/api/incident.py +45 -0
  8. browsergym/workarena/api/knowledge.py +29 -0
  9. browsergym/workarena/api/problem.py +90 -0
  10. browsergym/workarena/api/report.py +183 -0
  11. browsergym/workarena/api/requested_items.py +63 -0
  12. browsergym/workarena/api/user.py +11 -8
  13. browsergym/workarena/api/utils.py +47 -3
  14. browsergym/workarena/config.py +21 -1
  15. browsergym/workarena/data_files/setup_files/forms/expected_incident_form_fields.json +1 -1
  16. browsergym/workarena/data_files/setup_files/forms/expected_request_item_form_fields.json +1 -0
  17. browsergym/workarena/data_files/setup_files/knowledge/protocols.json +46 -0
  18. browsergym/workarena/data_files/setup_files/knowledge/test.html +1 -0
  19. browsergym/workarena/data_files/setup_files/lists/expected_asset_list_columns.json +2 -24
  20. browsergym/workarena/data_files/setup_files/lists/expected_change_request_list_columns.json +4 -40
  21. browsergym/workarena/data_files/setup_files/lists/expected_expense_line_list_columns.json +12 -0
  22. browsergym/workarena/data_files/setup_files/lists/expected_hardware_list_columns.json +1 -42
  23. browsergym/workarena/data_files/setup_files/lists/expected_incident_list_columns.json +2 -18
  24. browsergym/workarena/data_files/setup_files/lists/expected_problem_list_columns.json +12 -0
  25. browsergym/workarena/data_files/setup_files/lists/expected_requested_items_list_columns.json +12 -0
  26. browsergym/workarena/data_files/setup_files/lists/expected_service_catalog_list_columns.json +2 -19
  27. browsergym/workarena/data_files/setup_files/lists/expected_user_list_columns.json +3 -50
  28. browsergym/workarena/data_files/task_configs/all_menu.json +95 -95
  29. browsergym/workarena/data_files/task_configs/dashboard_retrieval_minmax_task.json +1 -1
  30. browsergym/workarena/data_files/task_configs/dashboard_retrieval_value_task.json +1 -1
  31. browsergym/workarena/data_files/task_configs/filter_service_catalog_item_list_task.json +7986 -7982
  32. browsergym/workarena/data_files/task_configs/impersonation_users.json +3 -3
  33. browsergym/workarena/data_files/task_configs/report_retrieval_minmax_task.json +1 -1
  34. browsergym/workarena/data_files/task_configs/report_retrieval_value_task.json +1 -1
  35. browsergym/workarena/human_eval/console.js +176 -0
  36. browsergym/workarena/human_eval/tool.py +366 -0
  37. browsergym/workarena/install.py +81 -20
  38. browsergym/workarena/tasks/base.py +55 -20
  39. browsergym/workarena/tasks/comp_building_block.py +4 -0
  40. browsergym/workarena/tasks/compositional/__init__.py +76 -0
  41. browsergym/workarena/tasks/compositional/base.py +364 -0
  42. browsergym/workarena/tasks/compositional/dash_do_base.py +1366 -0
  43. browsergym/workarena/tasks/compositional/dash_do_catalog.py +1127 -0
  44. browsergym/workarena/tasks/compositional/dash_do_catalog_infeasible.py +2047 -0
  45. browsergym/workarena/tasks/compositional/dash_do_create_incident.py +403 -0
  46. browsergym/workarena/tasks/compositional/dash_do_create_incident_infeasible.py +278 -0
  47. browsergym/workarena/tasks/compositional/dash_do_create_problem.py +336 -0
  48. browsergym/workarena/tasks/compositional/dash_do_create_problem_infeasible.py +235 -0
  49. browsergym/workarena/tasks/compositional/dash_do_filter.py +1600 -0
  50. browsergym/workarena/tasks/compositional/dash_do_request_item.py +1315 -0
  51. browsergym/workarena/tasks/compositional/dash_do_request_item_infeasible.py +693 -0
  52. browsergym/workarena/tasks/compositional/delete_record.py +341 -0
  53. browsergym/workarena/tasks/compositional/edit_knowledge_base.py +457 -0
  54. browsergym/workarena/tasks/compositional/expense_management.py +598 -0
  55. browsergym/workarena/tasks/compositional/filter_and_do.py +139 -0
  56. browsergym/workarena/tasks/compositional/find_and_order_item.py +345 -0
  57. browsergym/workarena/tasks/compositional/manage_change_request_schedule.py +1417 -0
  58. browsergym/workarena/tasks/compositional/mark_duplicate_problems.py +499 -0
  59. browsergym/workarena/tasks/compositional/maximize_investment_return.py +1763 -0
  60. browsergym/workarena/tasks/compositional/navigate_and_do.py +1151 -0
  61. browsergym/workarena/tasks/compositional/navigate_and_do_infeasible.py +2100 -0
  62. browsergym/workarena/tasks/compositional/offboard_user.py +207 -0
  63. browsergym/workarena/tasks/compositional/onboard_user.py +226 -0
  64. browsergym/workarena/tasks/compositional/update_task.py +145 -0
  65. browsergym/workarena/tasks/compositional/utils/curriculum.py +215 -0
  66. browsergym/workarena/tasks/compositional/utils/infeasible_configs.py +151 -0
  67. browsergym/workarena/tasks/compositional/utils/knapsack.py +192 -0
  68. browsergym/workarena/tasks/compositional/warranty_check.py +227 -0
  69. browsergym/workarena/tasks/compositional/work_assignment.py +804 -0
  70. browsergym/workarena/tasks/compositional/workload_balancing.py +396 -0
  71. browsergym/workarena/tasks/dashboard.py +188 -8
  72. browsergym/workarena/tasks/form.py +1024 -232
  73. browsergym/workarena/tasks/knowledge.py +216 -25
  74. browsergym/workarena/tasks/list.py +519 -102
  75. browsergym/workarena/tasks/mark_duplicate_problem.py +171 -0
  76. browsergym/workarena/tasks/navigation.py +55 -13
  77. browsergym/workarena/tasks/scripts/extract_all_menu_items.py +9 -2
  78. browsergym/workarena/tasks/scripts/generate_dashboard_configs.py +6 -5
  79. browsergym/workarena/tasks/scripts/service_catalog.py +2 -1
  80. browsergym/workarena/tasks/scripts/validate.py +8 -2
  81. browsergym/workarena/tasks/send_chat_message.py +90 -0
  82. browsergym/workarena/tasks/service_catalog.py +94 -26
  83. browsergym/workarena/tasks/utils/form.py +1 -4
  84. browsergym/workarena/tasks/utils/private_tasks.py +63 -0
  85. browsergym/workarena/tasks/utils/utils.py +13 -0
  86. {browsergym_workarena-0.2.0.dist-info → browsergym_workarena-0.3.0.dist-info}/METADATA +27 -20
  87. browsergym_workarena-0.3.0.dist-info/RECORD +138 -0
  88. {browsergym_workarena-0.2.0.dist-info → browsergym_workarena-0.3.0.dist-info}/entry_points.txt +1 -0
  89. browsergym_workarena-0.2.0.dist-info/RECORD +0 -85
  90. {browsergym_workarena-0.2.0.dist-info → browsergym_workarena-0.3.0.dist-info}/WHEEL +0 -0
  91. {browsergym_workarena-0.2.0.dist-info → browsergym_workarena-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,227 @@
1
+ import json
2
+ import time
3
+ from faker import Faker
4
+
5
+ fake = Faker()
6
+
7
+ from playwright.sync_api._generated import Page
8
+
9
+ from .base import CompositionalTask, HumanEvalTask
10
+
11
+ from ..base import AbstractServiceNowTask
12
+ from ..knowledge import KnowledgeBaseSearchTask
13
+ from ..list import ExtractListInfoTask, FilterHardwareListTask
14
+ from ..navigation import AllMenuTask
15
+
16
+ from ...api.computer_asset import create_computer_asset
17
+ from ...api.user import create_user
18
+ from ...api.utils import db_delete_from_table, table_api_call
19
+ from ...instance import SNowInstance
20
+
21
+
22
+ class GetWarrantyExpirationDateTask(CompositionalTask, HumanEvalTask):
23
+ def __init__(
24
+ self,
25
+ seed: int = None,
26
+ instance: SNowInstance = None,
27
+ fixed_config: list[AbstractServiceNowTask] = None,
28
+ level: int = 2,
29
+ ) -> None:
30
+ """
31
+ Create a compositional task with specific subtasks
32
+
33
+ Parameters:
34
+ -----------
35
+ instance: SNowInstance
36
+ The ServiceNow instance to run the task on.
37
+ fixed_config: list[AbstractServiceNowTask]
38
+ A list of subtasks
39
+ level: int
40
+ The level of the task; choice between 2 and 3. L2 will have all the info in the the goal and start in the SNOW home page.
41
+ L3 will start in a private task page describing the information needed to complete the task and the related company protocol
42
+ to complete it.
43
+ Attributes:
44
+ -----------
45
+ task_description: str
46
+ The start of the task description to be completed. e.g. "Referring to company protocol '[company_protocol]', onboard user with the following information: \n"
47
+ short_description: str
48
+ A short description of the task to be completed. e.g. "Find the warranty expiration date for John Doe's laptop"
49
+ """
50
+ assert level in [2, 3], "Level must be either 2 or 3"
51
+ self.level = level
52
+ self.protocol_name = "Finding the warranty expiration for a user's laptop"
53
+ super().__init__(
54
+ seed=seed,
55
+ instance=instance,
56
+ fixed_config=fixed_config,
57
+ level=level,
58
+ protocol_name=self.protocol_name,
59
+ )
60
+ self.task_description = None
61
+ self.short_description = None
62
+ self.user_sys_id = None
63
+ self.user_name = None
64
+ self.user_full_name = None
65
+ self.laptop_sys_id = None
66
+ self.warranty_expiration_date = None
67
+
68
+ def setup_goal(self, page: Page) -> tuple[str, dict]:
69
+ # Create a user and a laptop for the user
70
+ self._create_user_and_laptop()
71
+
72
+ # Sample a configuration
73
+ config = self.fixed_config if self.fixed_config else self._get_config()
74
+
75
+ # Get the task description
76
+ self.short_description = (
77
+ f"Find the warranty expiration date for {self.user_full_name}'s laptop"
78
+ )
79
+ self.task_description = f'Refer to company protocol "{self.protocol_name}" (located in the "Company Protocols" knowledge base) for the steps to find the Warranty expiration date for {self.user_full_name}\'s laptop.\n \n'
80
+
81
+ goal, info = super().setup_goal(page=page, config=config)
82
+
83
+ return goal, info
84
+
85
+ def _get_config(self) -> list[AbstractServiceNowTask]:
86
+ navigate_to_protocol_subtask = [
87
+ # Navigate to the KB
88
+ AllMenuTask(
89
+ instance=self.instance,
90
+ fixed_config={
91
+ "application": "Self-Service",
92
+ "module": "Knowledge",
93
+ "url": "/now/nav/ui/classic/params/target/%24knowledge.do",
94
+ },
95
+ is_validated=False,
96
+ used_in_level_2=False,
97
+ ),
98
+ # Find the protocol for on-boarding a new user
99
+ KnowledgeBaseSearchTask(
100
+ instance=self.instance,
101
+ fixed_config={
102
+ "alternative_answers": [],
103
+ "item": f"{self.protocol_name}",
104
+ "question": f'Can you find the "{self.protocol_name}" Protocol in the Knowledge Base?',
105
+ "value": "",
106
+ },
107
+ is_validated=False,
108
+ used_in_level_2=False,
109
+ ),
110
+ ]
111
+ navigate_to_hardware_asset_and_filter = [
112
+ # Navigate to the hardware asset list
113
+ AllMenuTask(
114
+ instance=self.instance,
115
+ fixed_config={
116
+ "application": "Asset",
117
+ "module": "Portfolios > Hardware Assets",
118
+ "url": "/now/nav/ui/classic/params/target/alm_hardware_list.do",
119
+ },
120
+ is_validated=False,
121
+ used_in_level_2=True,
122
+ ),
123
+ # Filter the hardware asset list
124
+ FilterHardwareListTask(
125
+ instance=self.instance,
126
+ fixed_config={
127
+ "filter_columns": ["assigned_to"],
128
+ "filter_kind": "AND",
129
+ "filter_values": [f"{self.user_full_name}"],
130
+ },
131
+ is_validated=False,
132
+ used_in_level_2=True,
133
+ ),
134
+ ]
135
+ extract_warranty_subtask = [
136
+ ExtractListInfoTask(
137
+ instance=self.instance,
138
+ unique_field_name="assigned_to",
139
+ fixed_config={
140
+ "start_rel_url": "",
141
+ "fields": {
142
+ "assigned_to": "Assigned to",
143
+ "warranty_expiration": "Warranty expiration",
144
+ },
145
+ "expected_values": [
146
+ {
147
+ "assigned_to": f"{self.user_full_name}",
148
+ "warranty_expiration": f"{self.warranty_expiration_date}",
149
+ }
150
+ ],
151
+ },
152
+ list_name="Hardware Assets",
153
+ list_url="/now/nav/ui/classic/params/target/alm_hardware_list.do",
154
+ table_name="alm_hardware",
155
+ is_validated=True,
156
+ used_in_level_2=True,
157
+ ),
158
+ ]
159
+
160
+ config = (
161
+ navigate_to_protocol_subtask
162
+ + navigate_to_hardware_asset_and_filter
163
+ + extract_warranty_subtask
164
+ )
165
+
166
+ return config
167
+
168
+ def _create_user_and_laptop(self) -> None:
169
+ """
170
+ Creates a user and a laptop for the user. The laptop model is randomly selected from the available computer models.
171
+ Sets the user_sys_id, laptop_sys_id, user_name and warranty_expiration_date attributes.
172
+ """
173
+ # Generate random name for the user
174
+ first_name = fake.first_name() + "-" + fake.first_name()
175
+ last_name = fake.last_name() + "-" + fake.last_name()
176
+ self.user_full_name = first_name + " " + last_name
177
+ # Create user
178
+ self.user_name, _, self.user_sys_id = create_user(
179
+ instance=self.instance, first_name=first_name, last_name=last_name, random=self.random
180
+ )
181
+
182
+ assert self.user_sys_id, f"Failed to create user {first_name} {last_name}"
183
+ self.warranty_expiration_date = str(fake.date_between(start_date="-1y", end_date="+1y"))
184
+ asset_tag = "P" + str(id(self) % (10**8)).zfill(8)
185
+ (
186
+ computer_sys_id,
187
+ _,
188
+ _,
189
+ ) = create_computer_asset(
190
+ instance=self.instance,
191
+ asset_tag=asset_tag,
192
+ warranty_expiration_date=self.warranty_expiration_date,
193
+ user_sys_id=self.user_sys_id,
194
+ random=self.random,
195
+ )
196
+
197
+ assert computer_sys_id, f"Failed to create hardware asset {asset_tag}"
198
+ self.laptop_sys_id = computer_sys_id
199
+
200
+ def teardown(self) -> None:
201
+ # Delete the user and the laptop
202
+ user_record_exists = table_api_call(
203
+ instance=self.instance,
204
+ table="sys_user",
205
+ params={"sysparm_query": f"sys_id={self.user_sys_id}"},
206
+ )
207
+ laptop_record_exists = table_api_call(
208
+ instance=self.instance,
209
+ table="alm_hardware",
210
+ params={"sysparm_query": f"sys_id={self.laptop_sys_id}"},
211
+ )
212
+ if user_record_exists:
213
+ db_delete_from_table(
214
+ instance=self.instance,
215
+ table="sys_user",
216
+ sys_id=self.user_sys_id,
217
+ )
218
+ if laptop_record_exists:
219
+ db_delete_from_table(
220
+ instance=self.instance,
221
+ table="alm_hardware",
222
+ sys_id=self.laptop_sys_id,
223
+ )
224
+ super().teardown()
225
+
226
+
227
+ __TASKS__ = [GetWarrantyExpirationDateTask]