Install WorkArena
mainTo install WorkArena in a BrowserGym environment, install the Python package and the required Playwright dependencies.
pip install browsergym-workarena
playwright installrepository·main·Indexed 42 days ago
https://github.com/servicenow/workarenaA benchmark suite of browser-based tasks designed to evaluate web agents performing routine knowledge work on the ServiceNow platform. It includes WorkArena-L1 for atomic tasks and WorkArena++ for compositional tasks evaluating planning, reasoning, and memorization. The suite provides tools for knowledge base generation, task validation, and API utilities for managing ServiceNow requests and items.
To install WorkArena in a BrowserGym environment, install the Python package and the required Playwright dependencies.
pip install browsergym-workarena
playwright installThe tasks/scripts/ directory contains utility scripts for managing WorkArena task configurations. These scripts are used to:
validate.py script performs parallel validation of existing configurations against their corresponding tasks to ensure consistency.Note: There is one script provided per task type. These scripts are intended for development and maintenance and are not part of the official released package.
WorkArena requires access to gated ServiceNow instances hosted on Hugging Face. Follow these steps to obtain access:
huggingface-cli login or setting the HUGGING_FACE_HUB_TOKEN environment variable).SNOW_INSTANCE_URL.The AbstractServiceNowTask provides a structured lifecycle for tasks:
setup(page, do_start=True): Configures the Playwright page, sets timeouts, creates a new ServiceNow user with the specified user_roles, injects utility scripts (SNOW_JS_UTILS_FILEPATH), and executes start() if do_start is True.start(page): Handles authentication via url_login and navigates the browser to the start_url.teardown(): Performs cleanup. If the task created a user during setup (delete_user_on_teardown is True), this method automatically deletes that user from the ServiceNow instance using the table_api_call on the sys_user table.Dashboard retrieval tasks follow a specific lifecycle to ensure data is accurately extracted from ServiceNow's Highcharts visualizations:
seed, a SNowInstance, and an optional fixed_config.setup_goal method determines the task's objective (e.g., "What is the maximum value in the 'Incident' chart?") based on the sampled configuration._wait_for_ready to ensure the gsft_main iframe, the Highcharts API, and the WORKARENA_HIGHCHARTS_ALL_LOADED flag are all present._get_charts to find available charts and _read_chart to extract series data, including labels, counts, and percentages.validate method compares the agent's response against the ground truth extracted from the chart data, supporting various question types like value, max, min, mean, median, and mode.These tasks are designed for evaluating agents on scenarios where they must retrieve information from a ServiceNow dashboard (e.g., finding max, mean, median, or mode values from incident charts) and then attempt to order a specific catalog item. These tasks are labeled as 'infeasible' because the ordering step is intentionally designed to fail or be problematic in the benchmark context.
Available catalog items for these tasks include:
Apple WatchApple MacBook Pro 15Development Laptop (PC)Loaner LaptopEach task class typically follows a pattern of retrieving a statistical value (max, mean, median, or mode) and then attempting an order. Some classes include a WithReason suffix, which sets provide_reason=True, requiring the agent to provide reasoning for its actions.
WorkArena provides compositional tasks that combine dashboard data retrieval with service catalog ordering. These tasks typically follow a pattern: retrieve a specific metric (max, mean, median, or mode) from a dashboard chart related to incidents, and then use that information to order a specific item from the service catalog.
Common task families include:
SingleChartMinMaxRetrievalTask to find a maximum value and then orders an item.SingleChartMeanMedianModeRetrievalTask to compute statistical metrics from dashboard data before ordering.Available catalog items for these tasks include:
Developer Laptop (Mac)iPad miniiPad proSales LaptopStandard LaptopApple WatchApple MacBook Pro 15Development Laptop (PC)Loaner LaptopInfeasible tasks are designed to evaluate how agents handle scenarios where a requested action (like ordering a specific catalog item) cannot be completed based on information retrieved from a ServiceNow dashboard. These tasks typically follow a pattern:
SingleChartMinMaxRetrievalTask or SingleChartMeanMedianModeRetrievalTask) to answer a question (e.g., 'max', 'mean', 'median', 'mode') regarding incidents.Common task variations include:
...InfeasibleTask: The base task for a specific item....InfeasibleWithReasonTask: A variation that requires the agent to provide a reason for its actions or failure....MaxOrder...Task: Specifically targets the 'max' value from dashboard charts....MeanOrder...Task: Specifically targets the 'mean' value....MedianOrder...Task: Specifically targets the 'median' value....ModeOrder...Task: Specifically targets the 'mode' value.To run the knowledge base generation notebook, you need the openai Python library and an environment variable OPENAI_API_KEY configured.
pip install openai!pip install openaiThe installation process can be managed using the following modes:
--fresh flag. This clears existing installation progress and resets report filters (via patch_report_filters(fresh=True)) to ensure a clean state.--resume flag or by choosing the resume option during the interactive prompt. This skips steps that are already marked as completed in the installation progress tracker.--fresh nor --resume is provided, the CLI will check for existing progress and prompt the user to either [r]esume or [s]tart fresh.WorkArena-L1 consists of atomic tasks covering main ServiceNow UI components. The following example uses the env.task.cheat() method to automatically solve tasks using Playwright.
Note: To evaluate a real agent instead of using the oracle/cheat function, you must use env.step() instead of env.task.cheat().
import random
from browsergym.core.env import BrowserEnv
from browsergym.workarena import ATOMIC_TASKS
from time import sleep
random.shuffle(ATOMIC_TASKS)
for task in ATOMIC_TASKS:
print("Task:", task)
# Instantiate a new environment
env = BrowserEnv(task_entrypoint=task,
headless=False)
env.reset()
# Cheat functions use Playwright to automatically solve the task
env.chat.add_message(role="assistant", msg="On it. Please wait...")
cheat_messages = []
env.task.cheat(env.page, cheat_messages)
# Send cheat messages to chat
for cheat_msg in cheat_messages:
env.chat.add_message(role=cheat_msg["role"], msg=cheat_msg["message"])
# Post solution to chat
env.chat.add_message(role="assistant", msg="I'm done!")
# Validate the solution
reward, stop, message, info = env.task.validate(env.page, cheat_messages)
if reward == 1:
env.chat.add_message(role="user", msg="Yes, that works. Thanks!")
else:
env.chat.add_message(role="user", msg=f"No, that doesn't work. {info.get('message', '')}")
sleep(3)
env.close()WorkArena++ (L2/L3) contains compositional tasks that evaluate planning, reasoning, and memorization. Use get_all_tasks_agents to sample tasks.
Note: This example uses the oracle/cheat function. For agent evaluation, use env.step().
import random
from browsergym.core.env import BrowserEnv
from browsergym.workarena import get_all_tasks_agents
AGENT_L2_SAMPLED_SET = get_all_tasks_agents(filter="l2")
AGENT_L2_SAMPLED_TASKS, AGENT_L2_SEEDS = [sampled_set[0] for sampled_set in AGENT_L2_SAMPLED_SET], [
sampled_set[1] for sampled_set in AGENT_L2_SAMPLED_SET
]
from time import sleep
for (task, seed) in zip(AGENT_L2_SAMPLED_TASKS, AGENT_L2_SEEDS):
print("Task:", task)
# Instantiate a new environment
env = BrowserEnv(task_entrypoint=task,
headless=False)
env.reset()
# Cheat functions use Playwright to automatically solve the task
env.chat.add_message(role="assistant", msg="On it. Please wait...")
for i in range(len(env.task)):
sleep(1)
env.task.cheat(page=env.page, chat_messages=env.chat.messages, subtask_idx=i)
sleep(1)
reward, done, message, info = env.task.validate(page=env.page, chat_messages=env.chat.messages)
if reward == 1:
env.chat.add_message(role="user", msg="Yes, that works. Thanks!")
else:
env.chat.add_message(role="user", msg=f"No, that doesn't work. {info.get('message', '')}")
sleep(3)
env.close()