NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI
BrowserGym: a gym environment for web task automation in the Chromium browser
Last release 8 months ago
20 Jan 2026
Release timing varies
gaps range from 8 days to 5 months
Most releases are documented
notes for 40 of 46 stable releases
Nothing withdrawn
no release was ever pulled
3 years old
66 releases · first in 2024
Add "BrowserGym Ecosystem" paper in the readme by @xhluca in https://github.com/ServiceNow/BrowserGym/pull/363
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.14.2...v0.14.3
One column per month.
Add "BrowserGym Ecosystem" paper in the readme by @xhluca in https://github.com/ServiceNow/BrowserGym/pull/363
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.14.2...v0.14.3.dev4
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Miniwob zoom by @recursix in https://github.com/ServiceNow/BrowserGym/pull/352
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.14.1...v0.14.2
Some changes in preparation for agentlab's new ToolUseAgent and the new APIs by @TLSDC in https://github.com/ServiceNow/BrowserGym/pull/340
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.13.4...v0.14.1
Nothing published for this version
Nothing published for this version
Optional method AbstractBrowserTask.get_task_id() #281
browsergym-core
AbstractBrowserTask.get_task_id() #281BrowserEnv parameter resizeable_window, now working as expected #281browsergym-experiments
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.13.2...v0.13.3
Experiment traces can now be exported into the TapeAgents format #238
browsergym-experiments
visualwebarena_tiny #271Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.13.1...v0.13.2
webarena / visualwebarena instance massage after reset #248 #250 #254 #259
browsergym-experiments
browsergym-core
INFO to DEBUG#252env.close(), can now be used in a finally block even after reset failure #253AbstractBrowserTask.teardown() method #255register_task() now supports both frozen, non-overrideable task_kwargs as well as overrideable default_task_kwargs arguments #255browsergym-assistantbench
browsergym-webarena
browsergym-visualwebarena
https://github.com/ServiceNow/BrowserGym/compare/v0.13.0...v0.13.1
More robust frame marking with lenient last try #245
browsergym-core
locale and timezone_id #244browsergym-experiments
select_option to webarena / visualwebarena default action set #247browsergym-visualwebarena
browsergym-assistantbench
locale="en-US" and timezone_id="America/New_York"Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.12.0...v0.13.0
Refactors experiment ID generation #236
browsergym-experiments
browsergym-visualwebarena
torch dependency (to run the captioning model) #240Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.11.3...v0.12.0
Fix duplicate depends_on in webarena metadata #228
nltk.download() at import time) #227full_reset() for webarena / visualwebarena #230webarena_tiny #232Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.11.2...v0.11.3
Add incomplete ExpResult.status #225
ExpResult.status #225Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.11.1...v0.11.2
Set max steps to 30 in webarena / visualwenarena benchmarks #214
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.11.0...v0.11.1
New weblinx benchmark 🎉 #208 (thanks @xhluca)
browsergym-experiments
weblinx benchmark 🎉 #208 (thanks @xhluca)ExpResults.status() #219 (thanks @recursix)browsergym-core
hide_all_bids option in flatten_dom_to_str() and flatten_axtree_to_str() #212 (thanks @imenelydiaker)Unicode() gym space #218Benchmark.prepare_backends() fixes #209Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.10.2...v0.11.0
New Benchmark.prepare_backend() method #204
Benchmark.prepare_backend() method #204save_step_info() bugfix when obs==None (truncated episode due to None action) #207Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.10.1...v0.10.2
train / test splits for WorkArena L2 and L3 tasks #203
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.10.0...v0.10.1
New BrowserGym benchmark AssistantBench, packaged as browsergym-assistantbench. Thanks @oriyor ! #186 ```python import browsergym.assistantbench
browsergym-assistantbench. Thanks @oriyor ! #186import browsergym.assistantbench
env = gym.make("browsergym/assistantbench.validation.12")
env = gym.make("browsergym/assistantbench.test.42")
miniwob = DEFAULT_BENCHMARKS["miniwob"] # 125 tasks x 5 seeds
miniwob_train = miniwob.subset_from_split("train") # 62 tasks x 5 seeds
miniwob_test = miniwob.subset_from_split("test") # 63 tasks x 5 seeds
Benchmark class #197 #198 #199Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.9.0...v0.10.0
Benchmarks with default config (tasks x seeds) and metadata #173 #191 ```python from browsergym.experiments import BENCHMARKS, Benchmark
from browsergym.experiments import BENCHMARKS, Benchmark
# make a custom benchmark
benchmark = Benchmark(
name="miniwob_click_test",
high_level_action_set_args=HighLevelActionSetArgs(
subsets=["bid"],
multiaction=False,
strict=False,
retry_with_force=False,
demo_mode="off",
),
env_args_list=[
EnvArgs(
task_name="miniwob.click-test",
task_seed=42,
max_steps=5,
)
],
)
# use a pre-existing benchmark
miniwob = BENCHMARKS["miniwob_all"]()
# use only a task subset
miniwob_original = miniwob.subset_from_glob(
column="miniwob_category", glob="original"
)
import browsergym.core.action
browsergym.core.action.set_global_demo_mode(True) # boolean
Full Changelog: https://github.com/ServiceNow/BrowserGym/compare/v0.8.1...v0.9.0
fixed a bug with set-of-marks line drawing #184 #185
browsergym-core
goal refactor #110 obs["goal_object"] now replaces the old obs["goal_image_urls"] obs["goal"] is now deprecated the new goal_object now contains a lis…
browsergym-core
obs["goal_object"] now replaces the old obs["goal_image_urls"]
obs["goal"] is now deprecated
the new goal_object now contains a list of openai-style messages, which can include an arbitrary mix of text and / or images.browsergym-visualwebarena
Breaking changes
image_url messages.Fixes
browsergym-experiments
other
legacy demo agent has been removedbasic demo agent has been leaned out and upgraded to support the new goal_object format #110playwright dependency bumped from playwright>=1.32,<1.40 to playwright>=1.39,==1.* (fixes problems with 1.32.1) #159
browsergym-core
playwright>=1.32,<1.40 to playwright>=1.39,==1.* (fixes problems with 1.32.1) #159browsergym-experiments
action==None. This was fixed by #163save package versions to a separate file package_versions.txt instead of the logs #152
browsergym-experiments
Breaking change
package_versions.txt instead of the logs #152Bugfixes
fixed bug in Frame has been detached catching #153
browsergym-core
Frame has been detached catching #153ignoring Frame has been detached errors during unmarking #148 #147
browsergym-core
Frame has been detached errors during unmarking #148 #147extract_merged_axtree #148 #146new field html_page: str in AgentInfo to enable agents to send an HTML page for visualization #13
browsergym-experiments
html_page: str in AgentInfo to enable agents to send an HTML page for visualization #13the 26 hard limit on max number of iFrames per page is removed #143
browsergym-core
Frame was detached errors during marking / unmarking #143AbstractAgentArgs.agent_name becomes a field (instead of a property) #138
browsergym-experiments
AbstractAgentArgs.agent_name becomes a field (instead of a property) #138Fixed a bug due to an incompatibility with joblib when running pip list or pip freeze. Python distributions are now extracted using importlib and logg
browsergym-experiments
joblib when running pip list or pip freeze. Python distributions are now extracted using importlib and logged in the regular logfile #135new option tags_to_mark: Literal["all", "default_html"] for all BrowserGym environments #129 When set to "all", all page elements get marked and recei
browsergym-core
New features
tags_to_mark: Literal["all", "default_html"] for all BrowserGym environments #129
When set to "all", all page elements get marked and receive a BID.
When set to "default_html", only standard HTML tags get marked and receive a BID (default behaviour).Improvements
div and span elements will now be available in the AXTree as well as the DOM #119
The aria-description field is now used in addition to the aria-roledescription as a fallback. This allows us to recover the bid of elements with generic role (div, span) for which aria-roledescription is not supported in the AXTree. Thanks @MurtyShikhar for noticing #110browsergym-experiments
pip list and pip freeze is now logged when an experiment is ran #130Nothing published for this version
Nothing published for this version
HighLevelActionSet has a new option retry_with_force #118 When activated, all Playwright actions will be retried with argument force=True if they fail
browsergym-core
HighLevelActionSet has a new option retry_with_force #118
When activated, all Playwright actions will be retried with argument force=True if they fail. For example:def check(bid: str):
...
if retry_with_force:
try:
elem.check(timeout=500)
except Exception as e:
elem.check(force=True, timeout=500)
else:
elem.check(timeout=500)
browsergym-experiments
Improvements
New Features
New convenience namespace bgym, available whenever the browsergym-experiments package is installed ```python import bgym
browsergym-experiments
bgym, available whenever the browsergym-experiments package is installedimport bgym
bgym.Agent
bgym.AgentInfo
bgym.EnvArgs
bgym.ExpArgs
bgym.AbstractAgentArgs
bgym.ExpResult
bgym.StepInfo
bgym.StepTimestamps
bgym.AbstractActionSet
bgym.HighLevelActionSet
bgym.PythonActionSet
New benchmark available!! #100 Bigs thanks to @ljang0 ```python import browsergym.visualwebarena
browsergym-visualwebarena
import browsergym.visualwebarena
env = gym.make("browsergym/visualwebarena.423")
...
<img width="800" alt="VisualWebArena task" src="https://github.com/user-attachments/assets/0b78d4d1-7dc6-4b9f-ac2f-433fa30a1690">browsergym-core
class MyTask(AbstractBrowserTask):
def setup(self, page: playwright.sync_api.Page):
goal = {
"message": "Where can I buy this car?",
"image_urls": ["https://en.wikipedia.org/wiki/Electric_car#/media/File:Nissan_Leaf_2_(45992539055).jpg"]
}
info = {}
return goal, info
BrowserEnv (reset(), step()) now have a new field for goal imagesobs, info = env.reset()
# textual goal as before
print(obs["goal"])
# list of goal images (as urls, possibly using data:image/png;base64,... encoding)
print(obs["goal_image_urls"])
user_image rolebrowsergym-webarena
export WA_SHOPPING=...
export WA_SHOPPING_ADMIN=...
export WA_REDDIT=...
export WA_GITLAB=...
export WA_WIKIPEDIA=...
export WA_MAP=...
export WA_HOMEPAGE=...
browsergym-experiments
AgentInfo #102AbstractAgentArgs methods prepare() and close() #106"infeas" action set now included by default #70 (report_infeasible(reason) action)
browsergym-core
Breaking changes
"infeas" action set now included by default #70 (report_infeasible(reason) action)New features
hide_all_children for the flatten_axtree_to_str() method #88Improvements
_wait_dom_loaded() #77 : now catches all Playwright Errors (was the reason of some crashes with IFrames #76)browsergym-experiments
Nothing published for this version
minor changes in high-level actions description and examples
browsergym-core
Refactors
browsergym-experiments
Bugfixes
action=None now recorded as truncated=Trueoverlay_som() bugfix divide by 0
browsergym-core
Refactors
Bugfixes
overlay_som() bugfix divide by 0browsergym-experiments
New features
StepInfo.task_infoBugfixes
loop should be robust to crashes and interruptsother
demo_agentMakefile :tada: (thanks @imenelydiaker ) `sh make install # local pip install of all packages make install-demo make demo `
browsergym-core
New features
make install # local pip install of all packages
make install-demo
make demo
hide_bid_if_invisible: boolean = False for flatten_axtree_to_str() and flatten_dom_to_str()bugfixes
timeout=500 for high-level click action (was hanging for very long if unsuccessful)report_infeasible(reason) action Adds a message {"role": "infeasible", "message": reason} in the chat, and terminates the episode. Validations functio
browsergym-core
New features
report_infeasible(reason) action
Adds a message {"role": "infeasible", "message": reason} in the chat, and terminates the episode. Validations functions which expect the agent to report a task as infeasible can look for a message with the "infeasible" role, and check for its content if a specific reason is required.
report_infeasible(reason) and action set "infeas"report_infeasible_instructions(reason)terminate_on_infeasible: boolean = TrueBreaking changes
flatten_axtree_to_str() and flatten_dom_to_str() return more compact representations
som, clickable, visible instead of som="1", clickable="1", visible="1"visible="0" is no more printedBugfixes
browsergym.experiment.loopsave the last observation in browsergym.experiments.loop
browsergym-experiment
Bugfixes
browsergym.experiments.loopAgent.action_mapping(action: str) -> str Agent.observation_mapping(obs: dict) -> Any
browsergym-experiments
Breaking changes
Agent API refactor# former API
Agent.action_mapping(action: str) -> str
Agent.observation_mapping(obs: dict) -> Any
# new API
Agent.action_set: AbstractActionSet
Agent.obs_preprocessor(obs: dict) -> Any
a bunch of tools to run and records experiments in browsergym.experiments
browsergym-core
New features
browsergym.experimentsBugfixes
Nothing published for this version
Nothing published for this version
Nothing published for this version
minor fix: high-level action parser now properly handles keyword arguments in Python function calls (were converted to non-keyword arguments before)
browsergym-core
browsergym-webarena
:tada: Set-of-Marks :tada: a new method is available to easily overlay element boxes and bid attributes on top of the screenshot, following ideas from
browsergym-core
New features
:tada: Set-of-Marks :tada: a new method is available to easily overlay element boxes and bid attributes on top of the screenshot, following ideas from WebVoyager and OSWorld
from browsergym.utils.obs import overlay_som
...
obs, info = env.reset()
screenshot_with_som = overlay_som(obs["screenshot"], obs["extra_element_properties"], fontsize = 12, linewidth = 2, tag_margin = 2)
new high-level actions upload_file and mouse_upload_file
new field "extra_element_properties" in each observation. Contains a dict with bid keys, which gives the extra properties computed by browsergym for every element with a bid on the current page. Example:
{
"23": {
"visibility": 0.6, # float between 0 and 1
"bbox": [56, 345, 12, 20], # [x, y, width, height]
"clickable": True, # boolean
"set_of_marks": False, # boolean
}
new set_of_marks property (computed with JS tag browsergym_set_of_marks), following WebVoyager implementation (boolean 0 or 1, whether element should be part of the set-of-marks overlay)
new clickable property, extracted from Chrome's DOMSnapshot's isClickable
new info fields "action_exec_start", "action_exec_timeout" and "action_exec_stop" after each env.step() call, useful for video editing
new resizeable_window parameter in BrowserEnv to switch between setting the viewport size via Chrome (previous behavior, resizeable window and viewport) or via Playwright (new default behaviour, viewport is not resizeable)
Breaking changes
browsergym_is_in_viewport (boolean 0 or 1) to browsergym_visibility_ratio (value between 0.0 and 1.0), extracted as the visibility extra property (see new features)BrowserEnv parameters viewport (viewport size), slow_mo (pause between playwright calls) and timeout (default playwright timeout) are now provided by the task. They can still be set in the environment's constructor to override the value provided by the task, which will display a warning.AbstractBrowserTask must now take a seed at instantiation (in constructor), instead of via the task.setup() method. This is also where each task should decide its desired browser setting by setting its attributes task.viewport, task.slow_mo and task.timeout (see point above)Refactors
21-53 -> a53)absolute -> fixed)IntersectionObserver API, should be more robust to edge cases<embed> tagsbrowsergym-miniwob
browsergym/miniwob/click-menu-2Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →