Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +5 -0
- README.md +3 -1
- miniwob-plusplus/.github/FUNDING.yml +1 -0
- miniwob-plusplus/.github/ISSUE_TEMPLATE/bug.md +27 -0
- miniwob-plusplus/.github/ISSUE_TEMPLATE/proposal.md +31 -0
- miniwob-plusplus/.github/ISSUE_TEMPLATE/question.md +12 -0
- miniwob-plusplus/.github/PULL_REQUEST_TEMPLATE.md +45 -0
- miniwob-plusplus/.github/stale.yml +62 -0
- miniwob-plusplus/.github/workflows/build-docs.yml +47 -0
- miniwob-plusplus/.github/workflows/build-publish.yaml +68 -0
- miniwob-plusplus/.github/workflows/build.yml +21 -0
- miniwob-plusplus/.github/workflows/pre-commit.yml +24 -0
- miniwob-plusplus/.gitignore +143 -0
- miniwob-plusplus/.pre-commit-config.yaml +54 -0
- miniwob-plusplus/CODE_OF_CONDUCT.rst +67 -0
- miniwob-plusplus/CONTRIBUTING.md +28 -0
- miniwob-plusplus/LICENSE +23 -0
- miniwob-plusplus/README.md +120 -0
- miniwob-plusplus/docs/.gitignore +3 -0
- miniwob-plusplus/docs/404.md +3 -0
- miniwob-plusplus/docs/README.md +36 -0
- miniwob-plusplus/docs/_scripts/gen_env_list.py +246 -0
- miniwob-plusplus/docs/_scripts/gen_mds.py +96 -0
- miniwob-plusplus/docs/_scripts/move_404.py +16 -0
- miniwob-plusplus/docs/_scripts/utils.py +51 -0
- miniwob-plusplus/docs/_static/img/custom-environment-1.png +0 -0
- miniwob-plusplus/docs/_static/img/example-usage-1.png +0 -0
- miniwob-plusplus/docs/_static/img/example-usage-2.png +0 -0
- miniwob-plusplus/docs/_static/img/favicon.png +0 -0
- miniwob-plusplus/docs/_static/img/miniwobplusplus-github.png +0 -0
- miniwob-plusplus/docs/_static/img/miniwobplusplus-text.png +3 -0
- miniwob-plusplus/docs/_static/img/miniwobplusplus-text.svg +117 -0
- miniwob-plusplus/docs/_static/img/miniwobplusplus-white.svg +0 -0
- miniwob-plusplus/docs/_static/img/miniwobplusplus.svg +0 -0
- miniwob-plusplus/docs/_static/img/showcase-static.png +3 -0
- miniwob-plusplus/docs/_static/img/showcase.gif +3 -0
- miniwob-plusplus/docs/_static/videos/miniwob.mp4 +3 -0
- miniwob-plusplus/docs/conf.py +80 -0
- miniwob-plusplus/docs/content/action_space.md +171 -0
- miniwob-plusplus/docs/content/basic_usage.md +135 -0
- miniwob-plusplus/docs/content/custom_environment.md +164 -0
- miniwob-plusplus/docs/content/demonstrations.md +46 -0
- miniwob-plusplus/docs/content/getting_started.md +43 -0
- miniwob-plusplus/docs/content/javascript_api.md +53 -0
- miniwob-plusplus/docs/content/observation_space.md +98 -0
- miniwob-plusplus/docs/content/reward.md +28 -0
- miniwob-plusplus/docs/content/viewing.md +29 -0
- miniwob-plusplus/docs/environments/.gitkeep +0 -0
- miniwob-plusplus/docs/index.md +80 -0
- miniwob-plusplus/docs/requirements.txt +5 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
miniwob-plusplus/docs/_static/img/miniwobplusplus-text.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
miniwob-plusplus/docs/_static/img/showcase-static.png filter=lfs diff=lfs merge=lfs -text
|
| 38 |
+
miniwob-plusplus/docs/_static/img/showcase.gif filter=lfs diff=lfs merge=lfs -text
|
| 39 |
+
miniwob-plusplus/docs/_static/videos/miniwob.mp4 filter=lfs diff=lfs merge=lfs -text
|
| 40 |
+
miniwob-plusplus/miniwobplusplus-text.png filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
|
@@ -277,7 +277,9 @@ docker build -t openenv-base:latest -f src/core/containers/images/Dockerfile .
|
|
| 277 |
|
| 278 |
```bash
|
| 279 |
# From the OpenEnv repository root
|
| 280 |
-
docker build -t browsergym-env:latest
|
|
|
|
|
|
|
| 281 |
```
|
| 282 |
|
| 283 |
### Run the Server
|
|
|
|
| 277 |
|
| 278 |
```bash
|
| 279 |
# From the OpenEnv repository root
|
| 280 |
+
docker build -t browsergym-env:latest \
|
| 281 |
+
-f envs/browsergym_env/server/Dockerfile \
|
| 282 |
+
envs/browsergym_env
|
| 283 |
```
|
| 284 |
|
| 285 |
### Run the Server
|
miniwob-plusplus/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
github: Farama-Foundation
|
miniwob-plusplus/.github/ISSUE_TEMPLATE/bug.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Bug Report
|
| 3 |
+
about: Submit a bug report
|
| 4 |
+
title: "[Bug Report] Bug title"
|
| 5 |
+
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
If you are submitting a bug report, please fill in the following details and use the tag [bug].
|
| 9 |
+
|
| 10 |
+
**Describe the bug**
|
| 11 |
+
A clear and concise description of what the bug is.
|
| 12 |
+
|
| 13 |
+
**Code example**
|
| 14 |
+
Please try to provide a minimal example to reproduce the bug. Error messages and stack traces are also helpful.
|
| 15 |
+
|
| 16 |
+
**System Info**
|
| 17 |
+
Describe the characteristic of your environment:
|
| 18 |
+
* Describe how miniwob-plusplus was installed (pip, docker, source, ...)
|
| 19 |
+
* What OS/version of Linux you're using. Note that while we will accept PRs to improve Window's support, we do not officially support it.
|
| 20 |
+
* Python version
|
| 21 |
+
|
| 22 |
+
**Additional context**
|
| 23 |
+
Add any other context about the problem here.
|
| 24 |
+
|
| 25 |
+
### Checklist
|
| 26 |
+
|
| 27 |
+
- [ ] I have checked that there is no similar [issue](https://github.com/Farama-Foundation/miniwob-plusplus/issues) in the repo (**required**)
|
miniwob-plusplus/.github/ISSUE_TEMPLATE/proposal.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Proposal
|
| 3 |
+
about: Propose changes that are not fixes bugs
|
| 4 |
+
title: "[Proposal] Proposal title"
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
### Proposal
|
| 8 |
+
|
| 9 |
+
A clear and concise description of the proposal.
|
| 10 |
+
|
| 11 |
+
### Motivation
|
| 12 |
+
|
| 13 |
+
Please outline the motivation for the proposal.
|
| 14 |
+
Is your feature request related to a problem? e.g.,"I'm always frustrated when [...]".
|
| 15 |
+
If this is related to another GitHub issue, please link here too.
|
| 16 |
+
|
| 17 |
+
### Pitch
|
| 18 |
+
|
| 19 |
+
A clear and concise description of what you want to happen.
|
| 20 |
+
|
| 21 |
+
### Alternatives
|
| 22 |
+
|
| 23 |
+
A clear and concise description of any alternative solutions or features you've considered, if any.
|
| 24 |
+
|
| 25 |
+
### Additional context
|
| 26 |
+
|
| 27 |
+
Add any other context or screenshots about the feature request here.
|
| 28 |
+
|
| 29 |
+
### Checklist
|
| 30 |
+
|
| 31 |
+
- [ ] I have checked that there is no similar [issue](https://github.com/Farama-Foundation/miniwob-plusplus/issues) in the repo (**required**)
|
miniwob-plusplus/.github/ISSUE_TEMPLATE/question.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
name: Question
|
| 3 |
+
about: Ask a question
|
| 4 |
+
title: "[Question] Question title"
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
### Question
|
| 9 |
+
|
| 10 |
+
If you're a beginner and have basic questions, please ask on [r/reinforcementlearning](https://www.reddit.com/r/reinforcementlearning/) or in the [RL Discord](https://discord.com/invite/xhfNqQv) (if you're new please use the beginners channel). Basic questions that are not bugs or feature requests will be closed without reply, because GitHub issues are not an appropriate venue for these.
|
| 11 |
+
|
| 12 |
+
Advanced/nontrivial questions, especially in areas where documentation is lacking, are very much welcome.
|
miniwob-plusplus/.github/PULL_REQUEST_TEMPLATE.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Description
|
| 2 |
+
|
| 3 |
+
Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
|
| 4 |
+
|
| 5 |
+
Fixes # (issue)
|
| 6 |
+
|
| 7 |
+
## Type of change
|
| 8 |
+
|
| 9 |
+
Please delete options that are not relevant.
|
| 10 |
+
|
| 11 |
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
| 12 |
+
- [ ] New feature (non-breaking change which adds functionality)
|
| 13 |
+
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
| 14 |
+
- [ ] This change requires a documentation update
|
| 15 |
+
|
| 16 |
+
### Screenshots
|
| 17 |
+
Please attach before and after screenshots of the change if applicable.
|
| 18 |
+
|
| 19 |
+
<!--
|
| 20 |
+
Example:
|
| 21 |
+
|
| 22 |
+
| Before | After |
|
| 23 |
+
| ------ | ----- |
|
| 24 |
+
| _gif/png before_ | _gif/png after_ |
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
To upload images to a PR -- simply drag and drop an image while in edit mode and it should upload the image directly. You can then paste that source into the above before/after sections.
|
| 28 |
+
-->
|
| 29 |
+
|
| 30 |
+
# Checklist:
|
| 31 |
+
|
| 32 |
+
- [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `pre-commit run --all-files` (see `CONTRIBUTING.md` instructions to set it up)
|
| 33 |
+
- [ ] I have commented my code, particularly in hard-to-understand areas
|
| 34 |
+
- [ ] I have made corresponding changes to the documentation
|
| 35 |
+
- [ ] My changes generate no new warnings
|
| 36 |
+
- [ ] I have added tests that prove my fix is effective or that my feature works
|
| 37 |
+
- [ ] New and existing unit tests pass locally with my changes
|
| 38 |
+
|
| 39 |
+
<!--
|
| 40 |
+
As you go through the checklist above, you can mark something as done by putting an x character in it
|
| 41 |
+
|
| 42 |
+
For example,
|
| 43 |
+
- [x] I have done this task
|
| 44 |
+
- [ ] I have not done this task
|
| 45 |
+
-->
|
miniwob-plusplus/.github/stale.yml
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Configuration for probot-stale - https://github.com/probot/stale
|
| 2 |
+
|
| 3 |
+
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
| 4 |
+
daysUntilStale: 60
|
| 5 |
+
|
| 6 |
+
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
| 7 |
+
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
| 8 |
+
daysUntilClose: 14
|
| 9 |
+
|
| 10 |
+
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
| 11 |
+
onlyLabels:
|
| 12 |
+
- more-information-needed
|
| 13 |
+
|
| 14 |
+
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
| 15 |
+
exemptLabels:
|
| 16 |
+
- pinned
|
| 17 |
+
- security
|
| 18 |
+
- "[Status] Maybe Later"
|
| 19 |
+
|
| 20 |
+
# Set to true to ignore issues in a project (defaults to false)
|
| 21 |
+
exemptProjects: true
|
| 22 |
+
|
| 23 |
+
# Set to true to ignore issues in a milestone (defaults to false)
|
| 24 |
+
exemptMilestones: true
|
| 25 |
+
|
| 26 |
+
# Set to true to ignore issues with an assignee (defaults to false)
|
| 27 |
+
exemptAssignees: true
|
| 28 |
+
|
| 29 |
+
# Label to use when marking as stale
|
| 30 |
+
staleLabel: stale
|
| 31 |
+
|
| 32 |
+
# Comment to post when marking as stale. Set to `false` to disable
|
| 33 |
+
markComment: >
|
| 34 |
+
This issue has been automatically marked as stale because it has not had
|
| 35 |
+
recent activity. It will be closed if no further activity occurs. Thank you
|
| 36 |
+
for your contributions.
|
| 37 |
+
|
| 38 |
+
# Comment to post when removing the stale label.
|
| 39 |
+
# unmarkComment: >
|
| 40 |
+
# Your comment here.
|
| 41 |
+
|
| 42 |
+
# Comment to post when closing a stale Issue or Pull Request.
|
| 43 |
+
# closeComment: >
|
| 44 |
+
# Your comment here.
|
| 45 |
+
|
| 46 |
+
# Limit the number of actions per hour, from 1-30. Default is 30
|
| 47 |
+
limitPerRun: 30
|
| 48 |
+
|
| 49 |
+
# Limit to only `issues` or `pulls`
|
| 50 |
+
only: issues
|
| 51 |
+
|
| 52 |
+
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
| 53 |
+
# pulls:
|
| 54 |
+
# daysUntilStale: 30
|
| 55 |
+
# markComment: >
|
| 56 |
+
# This pull request has been automatically marked as stale because it has not had
|
| 57 |
+
# recent activity. It will be closed if no further activity occurs. Thank you
|
| 58 |
+
# for your contributions.
|
| 59 |
+
|
| 60 |
+
# issues:
|
| 61 |
+
# exemptLabels:
|
| 62 |
+
# - confirmed
|
miniwob-plusplus/.github/workflows/build-docs.yml
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Build main branch documentation website
|
| 2 |
+
on:
|
| 3 |
+
push:
|
| 4 |
+
branches: [master]
|
| 5 |
+
permissions:
|
| 6 |
+
contents: write
|
| 7 |
+
jobs:
|
| 8 |
+
docs:
|
| 9 |
+
name: Generate Website
|
| 10 |
+
runs-on: ubuntu-latest
|
| 11 |
+
env:
|
| 12 |
+
SPHINX_GITHUB_CHANGELOG_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
| 13 |
+
steps:
|
| 14 |
+
- uses: actions/checkout@v3
|
| 15 |
+
|
| 16 |
+
- uses: actions/setup-python@v4
|
| 17 |
+
with:
|
| 18 |
+
python-version: '3.9'
|
| 19 |
+
|
| 20 |
+
- name: Install dependencies
|
| 21 |
+
run: pip install -r docs/requirements.txt
|
| 22 |
+
|
| 23 |
+
- name: Install MiniWoB++
|
| 24 |
+
run: pip install -e .
|
| 25 |
+
|
| 26 |
+
- name: Build Envs Docs
|
| 27 |
+
run: python docs/_scripts/gen_mds.py
|
| 28 |
+
|
| 29 |
+
- name: Build List of Environments
|
| 30 |
+
run: python docs/_scripts/gen_env_list.py
|
| 31 |
+
|
| 32 |
+
- name: Build
|
| 33 |
+
run: sphinx-build -b dirhtml -v docs _build
|
| 34 |
+
|
| 35 |
+
- name: Move 404
|
| 36 |
+
run: mv _build/404/index.html _build/404.html
|
| 37 |
+
|
| 38 |
+
- name: Update 404 links
|
| 39 |
+
run: python docs/_scripts/move_404.py _build/404.html
|
| 40 |
+
|
| 41 |
+
- name: Remove .doctrees
|
| 42 |
+
run: rm -r _build/.doctrees
|
| 43 |
+
|
| 44 |
+
- name: Upload to GitHub Pages
|
| 45 |
+
uses: JamesIves/github-pages-deploy-action@v4
|
| 46 |
+
with:
|
| 47 |
+
folder: _build
|
miniwob-plusplus/.github/workflows/build-publish.yaml
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This workflow will build and (if release) publish Python distributions to PyPI
|
| 2 |
+
# For more information see:
|
| 3 |
+
# - https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
| 4 |
+
# - https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
|
| 5 |
+
#
|
| 6 |
+
# derived from https://github.com/Farama-Foundation/PettingZoo/blob/e230f4d80a5df3baf9bd905149f6d4e8ce22be31/.github/workflows/build-publish.yml
|
| 7 |
+
name: build-publish
|
| 8 |
+
|
| 9 |
+
on:
|
| 10 |
+
push:
|
| 11 |
+
branches: [main]
|
| 12 |
+
pull_request:
|
| 13 |
+
branches: [main]
|
| 14 |
+
release:
|
| 15 |
+
types: [published]
|
| 16 |
+
|
| 17 |
+
jobs:
|
| 18 |
+
build-wheels:
|
| 19 |
+
runs-on: ${{ matrix.os }}
|
| 20 |
+
strategy:
|
| 21 |
+
matrix:
|
| 22 |
+
include:
|
| 23 |
+
- os: ubuntu-latest
|
| 24 |
+
python: 37
|
| 25 |
+
platform: manylinux_x86_64
|
| 26 |
+
- os: ubuntu-latest
|
| 27 |
+
python: 38
|
| 28 |
+
platform: manylinux_x86_64
|
| 29 |
+
- os: ubuntu-latest
|
| 30 |
+
python: 39
|
| 31 |
+
platform: manylinux_x86_64
|
| 32 |
+
- os: ubuntu-latest
|
| 33 |
+
python: 310
|
| 34 |
+
platform: manylinux_x86_64
|
| 35 |
+
- os: ubuntu-latest
|
| 36 |
+
python: 311
|
| 37 |
+
platform: manylinux_x86_64
|
| 38 |
+
|
| 39 |
+
steps:
|
| 40 |
+
- uses: actions/checkout@v3
|
| 41 |
+
- name: Set up Python
|
| 42 |
+
uses: actions/setup-python@v4
|
| 43 |
+
with:
|
| 44 |
+
python-version: '3.x'
|
| 45 |
+
- name: Install dependencies
|
| 46 |
+
run: python -m pip install --upgrade pip setuptools build
|
| 47 |
+
- name: Build sdist and wheels
|
| 48 |
+
run: python -m build
|
| 49 |
+
- name: Store wheels
|
| 50 |
+
uses: actions/upload-artifact@v3
|
| 51 |
+
with:
|
| 52 |
+
path: dist
|
| 53 |
+
|
| 54 |
+
publish:
|
| 55 |
+
runs-on: ubuntu-latest
|
| 56 |
+
needs:
|
| 57 |
+
- build-wheels
|
| 58 |
+
if: github.event_name == 'release' && github.event.action == 'published'
|
| 59 |
+
steps:
|
| 60 |
+
- name: Download dists
|
| 61 |
+
uses: actions/download-artifact@v3
|
| 62 |
+
with:
|
| 63 |
+
name: artifact
|
| 64 |
+
path: dist
|
| 65 |
+
- name: Publish
|
| 66 |
+
uses: pypa/gh-action-pypi-publish@release/v1
|
| 67 |
+
with:
|
| 68 |
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
miniwob-plusplus/.github/workflows/build.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: build
|
| 2 |
+
on: [pull_request, push]
|
| 3 |
+
|
| 4 |
+
permissions:
|
| 5 |
+
contents: read # to fetch code (actions/checkout)
|
| 6 |
+
|
| 7 |
+
jobs:
|
| 8 |
+
build:
|
| 9 |
+
runs-on: ubuntu-latest
|
| 10 |
+
timeout-minutes: 15
|
| 11 |
+
strategy:
|
| 12 |
+
matrix:
|
| 13 |
+
python-version: ['3.8', '3.9', '3.10', '3.11']
|
| 14 |
+
steps:
|
| 15 |
+
- uses: actions/checkout@v2
|
| 16 |
+
- run: |
|
| 17 |
+
docker build -f py.Dockerfile \
|
| 18 |
+
--build-arg PYTHON_VERSION=${{ matrix.python-version }} \
|
| 19 |
+
--tag miniwob-plusplus-docker .
|
| 20 |
+
- name: Run tests
|
| 21 |
+
run: docker run --shm-size=256m miniwob-plusplus-docker pytest --timeout=20
|
miniwob-plusplus/.github/workflows/pre-commit.yml
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
# https://pre-commit.com
|
| 3 |
+
# This GitHub Action assumes that the repo contains a valid .pre-commit-config.yaml file.
|
| 4 |
+
name: pre-commit
|
| 5 |
+
on:
|
| 6 |
+
pull_request:
|
| 7 |
+
push:
|
| 8 |
+
branches: [master]
|
| 9 |
+
|
| 10 |
+
permissions:
|
| 11 |
+
contents: read # to fetch code (actions/checkout)
|
| 12 |
+
|
| 13 |
+
jobs:
|
| 14 |
+
pre-commit:
|
| 15 |
+
runs-on: ubuntu-latest
|
| 16 |
+
steps:
|
| 17 |
+
- uses: actions/checkout@v2
|
| 18 |
+
- uses: actions/setup-python@v2
|
| 19 |
+
with:
|
| 20 |
+
python-version: '3.10'
|
| 21 |
+
- run: pip install pre-commit
|
| 22 |
+
- run: pre-commit --version
|
| 23 |
+
- run: pre-commit install
|
| 24 |
+
- run: pre-commit run --all-files
|
miniwob-plusplus/.gitignore
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / DLL files
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[cod]
|
| 4 |
+
*$py.class
|
| 5 |
+
|
| 6 |
+
# C extensions
|
| 7 |
+
*.so
|
| 8 |
+
|
| 9 |
+
# Distribution / packaging
|
| 10 |
+
.Python
|
| 11 |
+
build/
|
| 12 |
+
develop-eggs/
|
| 13 |
+
dist/
|
| 14 |
+
downloads/
|
| 15 |
+
eggs/
|
| 16 |
+
.eggs/
|
| 17 |
+
lib/
|
| 18 |
+
lib64/
|
| 19 |
+
parts/
|
| 20 |
+
sdist/
|
| 21 |
+
var/
|
| 22 |
+
wheels/
|
| 23 |
+
share/python-wheels/
|
| 24 |
+
*.egg-info/
|
| 25 |
+
.installed.cfg
|
| 26 |
+
*.egg
|
| 27 |
+
MANIFEST
|
| 28 |
+
|
| 29 |
+
# PyInstaller
|
| 30 |
+
# Usually these files are written by a python script from a template
|
| 31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 32 |
+
*.manifest
|
| 33 |
+
*.spec
|
| 34 |
+
|
| 35 |
+
# Installer logs
|
| 36 |
+
pip-log.txt
|
| 37 |
+
pip-delete-this-directory.txt
|
| 38 |
+
|
| 39 |
+
# Unit test / coverage reports
|
| 40 |
+
htmlcov/
|
| 41 |
+
.tox/
|
| 42 |
+
.nox/
|
| 43 |
+
.coverage
|
| 44 |
+
.coverage.*
|
| 45 |
+
.cache
|
| 46 |
+
nosetests.xml
|
| 47 |
+
coverage.xml
|
| 48 |
+
*.cover
|
| 49 |
+
*.py,cover
|
| 50 |
+
.hypothesis/
|
| 51 |
+
.pytest_cache/
|
| 52 |
+
cover/
|
| 53 |
+
|
| 54 |
+
# Translations
|
| 55 |
+
*.mo
|
| 56 |
+
*.pot
|
| 57 |
+
|
| 58 |
+
# Django stuff:
|
| 59 |
+
*.log
|
| 60 |
+
local_settings.py
|
| 61 |
+
db.sqlite3
|
| 62 |
+
db.sqlite3-journal
|
| 63 |
+
|
| 64 |
+
# Flask stuff:
|
| 65 |
+
instance/
|
| 66 |
+
.webassets-cache
|
| 67 |
+
|
| 68 |
+
# Scrapy stuff:
|
| 69 |
+
.scrapy
|
| 70 |
+
|
| 71 |
+
# Sphinx documentation
|
| 72 |
+
docs/_build/
|
| 73 |
+
|
| 74 |
+
# PyBuilder
|
| 75 |
+
.pybuilder/
|
| 76 |
+
target/
|
| 77 |
+
|
| 78 |
+
# Jupyter Notebook
|
| 79 |
+
.ipynb_checkpoints
|
| 80 |
+
|
| 81 |
+
# IPython
|
| 82 |
+
profile_default/
|
| 83 |
+
ipython_config.py
|
| 84 |
+
|
| 85 |
+
# pyenv
|
| 86 |
+
# For a library or package, you might want to ignore these files since the code is
|
| 87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
| 88 |
+
# .python-version
|
| 89 |
+
|
| 90 |
+
# pipenv
|
| 91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 94 |
+
# install all needed dependencies.
|
| 95 |
+
#Pipfile.lock
|
| 96 |
+
|
| 97 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
| 98 |
+
__pypackages__/
|
| 99 |
+
|
| 100 |
+
# Celery stuff
|
| 101 |
+
celerybeat-schedule
|
| 102 |
+
celerybeat.pid
|
| 103 |
+
|
| 104 |
+
# SageMath parsed files
|
| 105 |
+
*.sage.py
|
| 106 |
+
|
| 107 |
+
# Environments
|
| 108 |
+
.env
|
| 109 |
+
.venv
|
| 110 |
+
env/
|
| 111 |
+
venv/
|
| 112 |
+
ENV/
|
| 113 |
+
env.bak/
|
| 114 |
+
venv.bak/
|
| 115 |
+
|
| 116 |
+
# Spyder project settings
|
| 117 |
+
.spyderproject
|
| 118 |
+
.spyproject
|
| 119 |
+
|
| 120 |
+
# Rope project settings
|
| 121 |
+
.ropeproject
|
| 122 |
+
|
| 123 |
+
# mkdocs documentation
|
| 124 |
+
/site
|
| 125 |
+
|
| 126 |
+
# mypy
|
| 127 |
+
.mypy_cache/
|
| 128 |
+
.dmypy.json
|
| 129 |
+
dmypy.json
|
| 130 |
+
|
| 131 |
+
# Pyre type checker
|
| 132 |
+
.pyre/
|
| 133 |
+
|
| 134 |
+
# pytype static type analyzer
|
| 135 |
+
.pytype/
|
| 136 |
+
|
| 137 |
+
# Cython debug symbols
|
| 138 |
+
cython_debug/
|
| 139 |
+
|
| 140 |
+
# vi
|
| 141 |
+
*~
|
| 142 |
+
*.swp
|
| 143 |
+
*.swo
|
miniwob-plusplus/.pre-commit-config.yaml
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
repos:
|
| 3 |
+
- repo: https://github.com/python/black
|
| 4 |
+
rev: 23.3.0
|
| 5 |
+
hooks:
|
| 6 |
+
- id: black
|
| 7 |
+
- repo: https://github.com/codespell-project/codespell
|
| 8 |
+
rev: v2.2.4
|
| 9 |
+
hooks:
|
| 10 |
+
- id: codespell
|
| 11 |
+
exclude: ^(miniwob/html/)|(viewer/)|(.*\.svg$)
|
| 12 |
+
args:
|
| 13 |
+
- --ignore-words-list=sur,vally,nam
|
| 14 |
+
- repo: https://github.com/PyCQA/flake8
|
| 15 |
+
rev: 6.0.0
|
| 16 |
+
hooks:
|
| 17 |
+
- id: flake8
|
| 18 |
+
args:
|
| 19 |
+
- '--per-file-ignores=*/__init__.py:F401'
|
| 20 |
+
- --max-complexity=30
|
| 21 |
+
- --max-line-length=456
|
| 22 |
+
- --show-source
|
| 23 |
+
- --statistics
|
| 24 |
+
- repo: https://github.com/PyCQA/isort
|
| 25 |
+
rev: 5.12.0
|
| 26 |
+
hooks:
|
| 27 |
+
- id: isort
|
| 28 |
+
args: ["--profile", "black"]
|
| 29 |
+
- repo: https://github.com/pycqa/pydocstyle
|
| 30 |
+
rev: 6.3.0 # pick a git hash / tag to point to
|
| 31 |
+
hooks:
|
| 32 |
+
- id: pydocstyle
|
| 33 |
+
exclude: ^(tests/)|(miniwob/envs/)
|
| 34 |
+
args:
|
| 35 |
+
- --source
|
| 36 |
+
- --explain
|
| 37 |
+
- --convention=google
|
| 38 |
+
additional_dependencies: ["toml"]
|
| 39 |
+
- repo: https://github.com/asottile/pyupgrade
|
| 40 |
+
rev: v3.4.0
|
| 41 |
+
hooks:
|
| 42 |
+
- id: pyupgrade
|
| 43 |
+
args: ["--py37-plus"]
|
| 44 |
+
- repo: local
|
| 45 |
+
hooks:
|
| 46 |
+
- id: pyright
|
| 47 |
+
name: pyright
|
| 48 |
+
entry: pyright
|
| 49 |
+
language: node
|
| 50 |
+
pass_filenames: false
|
| 51 |
+
types: [python]
|
| 52 |
+
additional_dependencies: ["pyright@1.1.308"]
|
| 53 |
+
args:
|
| 54 |
+
- --project=pyproject.toml
|
miniwob-plusplus/CODE_OF_CONDUCT.rst
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
=================================
|
| 2 |
+
Farama Foundation Code of Conduct
|
| 3 |
+
=================================
|
| 4 |
+
|
| 5 |
+
The Farama Foundation is dedicated to providing a harassment-free experience for
|
| 6 |
+
everyone, regardless of gender, gender identity and expression, sexual
|
| 7 |
+
orientation, disability, physical appearance, body size, age, race, or
|
| 8 |
+
religion. We do not tolerate harassment of participants in any form.
|
| 9 |
+
|
| 10 |
+
This code of conduct applies to all Farama Foundation repositories (including Gist
|
| 11 |
+
comments) both online and off. Anyone who violates this code of
|
| 12 |
+
conduct may be sanctioned or expelled from these spaces at the
|
| 13 |
+
discretion of the moderators.
|
| 14 |
+
|
| 15 |
+
We may add additional rules over time, which will be made clearly
|
| 16 |
+
available to participants. Participants are responsible for knowing
|
| 17 |
+
and abiding by these rules.
|
| 18 |
+
|
| 19 |
+
-------------
|
| 20 |
+
Our Standards
|
| 21 |
+
-------------
|
| 22 |
+
Members of the Farama Foundation community are **open**, **inclusive**, and **respectful**.
|
| 23 |
+
Examples of behavior that contributes to a positive environment for our community include:
|
| 24 |
+
|
| 25 |
+
* **Being open**. Members of the community are open to collaboration, whether it's on issues, PRs, problems, or otherwise
|
| 26 |
+
* **Focusing on what is best for the community**. We're respectful of the processes set forth in the community, and we work within them to
|
| 27 |
+
improve the community.
|
| 28 |
+
* **Being respectful of differing viewpoints and experiences.** We're receptive to constructive comments and criticism,
|
| 29 |
+
as the experiences and skill sets of other members contribute to the whole of our efforts.
|
| 30 |
+
* **Showing empathy.** We're attentive in our communications, and we're tactful when approaching differing views.
|
| 31 |
+
* **Being respectful.** We're respectful of differing opinions, viewpoints, experiences, and efforts.
|
| 32 |
+
* **Gracefully accepting constructive criticism.** When we disagree, we are courteous in raising our issues.
|
| 33 |
+
* **Using welcoming and inclusive language.** We're accepting of all who wish to take part in our activities, fostering
|
| 34 |
+
an environment where anyone can participate and everyone can make a difference.
|
| 35 |
+
|
| 36 |
+
Examples of unacceptable behavior include:
|
| 37 |
+
|
| 38 |
+
* Harassment of any participants in any form.
|
| 39 |
+
* The use of sexual language or imagery, and sexual attention or advances of any kind.
|
| 40 |
+
* Insults, put downs, or jokes that are based upon stereotypes, that are exclusionary, or that hold others up for ridicule.
|
| 41 |
+
* Publishing others' private information, such as a physical or email address, without explicit permission.
|
| 42 |
+
* Incitement of violence or harassment towards any individual, including encouraging a person to commit suicide or to engage in self-harm.
|
| 43 |
+
* Sustained disruption of online community discussions, in-person presentations, or other in-person events.
|
| 44 |
+
* Creating additional online accounts in order to harass another person or circumvent a ban
|
| 45 |
+
* Other conduct which could reasonably be considered inappropriate in a professional setting including people of many different backgrounds.
|
| 46 |
+
|
| 47 |
+
Members asked to stop any inappropriate behavior are expected to comply immediately.
|
| 48 |
+
|
| 49 |
+
------------
|
| 50 |
+
Consequences
|
| 51 |
+
------------
|
| 52 |
+
If a participant engages in behavior that violates this code of conduct, the Farama Foundation team may take any action they deem
|
| 53 |
+
appropriate, including warning the offender or expulsion from the community.
|
| 54 |
+
|
| 55 |
+
Thank you for helping make this a welcoming, friendly community for everyone.
|
| 56 |
+
|
| 57 |
+
-------
|
| 58 |
+
License
|
| 59 |
+
-------
|
| 60 |
+
This Code of Conduct is licensed under the `Creative Commons Attribution-ShareAlike 3.0 Unported License
|
| 61 |
+
<https://creativecommons.org/licenses/by-sa/3.0/>`_.
|
| 62 |
+
|
| 63 |
+
-----------
|
| 64 |
+
Attribution
|
| 65 |
+
-----------
|
| 66 |
+
This Code of Conduct is adapted from `Python's Code of Conduct <https://www.python.org/psf/conduct/>`_, which is under a `Creative Commons License
|
| 67 |
+
<https://creativecommons.org/licenses/by-sa/3.0/>`_.
|
miniwob-plusplus/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MiniWoB++ Contribution Guidelines
|
| 2 |
+
|
| 3 |
+
We welcome:
|
| 4 |
+
|
| 5 |
+
- Bug reports
|
| 6 |
+
- Pull requests for bug fixes
|
| 7 |
+
- Documentation improvements
|
| 8 |
+
|
| 9 |
+
## Contributing to the codebase
|
| 10 |
+
|
| 11 |
+
### Coding
|
| 12 |
+
|
| 13 |
+
Contributing code is done through standard github methods:
|
| 14 |
+
|
| 15 |
+
1. Fork this repo
|
| 16 |
+
2. Commit your code
|
| 17 |
+
3. Submit a pull request. It will be reviewed by maintainers and they'll give feedback or make requests as applicable
|
| 18 |
+
|
| 19 |
+
### Considerations
|
| 20 |
+
- Make sure your new code is properly tested and fully-covered
|
| 21 |
+
- Any fixes to environments should include fixes to the appropriate documentation
|
| 22 |
+
|
| 23 |
+
### Git hooks
|
| 24 |
+
The CI will run several checks on the new code pushed to the MiniWoB++ repository. These checks can also be run locally without waiting for the CI by following the steps below:
|
| 25 |
+
1. [install `pre-commit`](https://pre-commit.com/#install),
|
| 26 |
+
2. install the Git hooks by running `pre-commit install`.
|
| 27 |
+
|
| 28 |
+
Once those two steps are done, the Git hooks will be run automatically at every new commit. The Git hooks can also be run manually with `pre-commit run --all-files`, and if needed they can be skipped (not recommended) with `git commit --no-verify`. **Note:** you may have to run `pre-commit run --all-files` manually a couple of times to make it pass when you commit, as each formatting tool will first format the code and fail the first time but should pass the second time.
|
miniwob-plusplus/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
The MIT License
|
| 2 |
+
|
| 3 |
+
Copyright 2016 OpenAI (as part of https://github.com/openai/universe)
|
| 4 |
+
Copyright 2018 The Board of Trustees of The Leland Stanford Junior University
|
| 5 |
+
Copyright 2022 Farama Foundation
|
| 6 |
+
|
| 7 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 8 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 9 |
+
in the Software without restriction, including without limitation the rights
|
| 10 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 11 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 12 |
+
furnished to do so, subject to the following conditions:
|
| 13 |
+
|
| 14 |
+
The above copyright notice and this permission notice shall be included in
|
| 15 |
+
all copies or substantial portions of the Software.
|
| 16 |
+
|
| 17 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 18 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 19 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 20 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 21 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 22 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
| 23 |
+
THE SOFTWARE.
|
miniwob-plusplus/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<p align="center">
|
| 2 |
+
<img src="https://raw.githubusercontent.com/Farama-Foundation/miniwob-plusplus/master/miniwobplusplus-text.png" width="500px"/>
|
| 3 |
+
</p>
|
| 4 |
+
|
| 5 |
+
[](https://pre-commit.com/)
|
| 6 |
+
[](https://github.com/psf/black)
|
| 7 |
+
|
| 8 |
+
<p align="center">
|
| 9 |
+
<img src="https://raw.githubusercontent.com/Farama-Foundation/miniwob-plusplus/master/docs/_static/img/showcase-static.png" width="100%"/>
|
| 10 |
+
</p>
|
| 11 |
+
|
| 12 |
+
The MiniWoB++ (Mini World of Bits++) library contains a collection of over 100 **web interaction environments**,
|
| 13 |
+
along with JavaScript and Python interfaces for programmatically interacting with them.
|
| 14 |
+
The Python interface follows the [Gymnasium](https://gymnasium.farama.org/) API
|
| 15 |
+
and uses [Selenium WebDriver](https://www.selenium.dev/documentation/webdriver/)
|
| 16 |
+
to perform actions on the web browser.
|
| 17 |
+
|
| 18 |
+
MiniWoB++ is an extension of the
|
| 19 |
+
[OpenAI MiniWoB benchmark](http://proceedings.mlr.press/v70/shi17a/shi17a.pdf),
|
| 20 |
+
and was introduced in the paper
|
| 21 |
+
[Reinforcement Learning on Web Interfaces using Workflow-Guided
|
| 22 |
+
Exploration](https://arxiv.org/abs/1802.08802).
|
| 23 |
+
|
| 24 |
+
The documentation website is at [miniwob.farama.org](https://miniwob.farama.org/).
|
| 25 |
+
Development on MiniWoB++ is currently ongoing to bring it up to [Farama Standards](https://farama.org/project_standards.html) for mature projects, and will be maintained long term after this point. See the [Project Roadmap](https://github.com/Farama-Foundation/miniwob-plusplus/issues/58) for more details. If you'd like to help out, you can join our discord server here: <https://discord.gg/PfR7a79FpQ>.
|
| 26 |
+
|
| 27 |
+
# Installation
|
| 28 |
+
|
| 29 |
+
MiniWoB++ supports Python 3.8+ on Linux and macOS.
|
| 30 |
+
|
| 31 |
+
## Installing the MiniWoB++ Library
|
| 32 |
+
|
| 33 |
+
To install the MiniWoB++ library, use `pip install miniwob`.
|
| 34 |
+
|
| 35 |
+
## Installing Chrome/Chromium and ChromeDriver
|
| 36 |
+
|
| 37 |
+
We strongly recommend using Chrome or Chromium as the web browser,
|
| 38 |
+
as other browsers may render the environments differently.
|
| 39 |
+
|
| 40 |
+
The MiniWoB++ Python interface uses [Selenium](https://www.selenium.dev/documentation/webdriver/),
|
| 41 |
+
which interacts with the browser via the [WebDriver API](https://w3c.github.io/webdriver/).
|
| 42 |
+
Follow one of the
|
| 43 |
+
[instruction methods](https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/)
|
| 44 |
+
to install ChromeDriver. The simplest method is to
|
| 45 |
+
[download](https://chromedriver.chromium.org/downloads) ChromeDriver with the matching version,
|
| 46 |
+
unzip it, and then add the directory containing the `chromedriver` executable to the `PATH` environment variable:
|
| 47 |
+
|
| 48 |
+
```sh
|
| 49 |
+
export PATH=$PATH:/path/to/chromedriver
|
| 50 |
+
```
|
| 51 |
+
|
| 52 |
+
For Chromium, the driver may also be available in a software package; for example, in Debian/Ubuntu:
|
| 53 |
+
|
| 54 |
+
```sh
|
| 55 |
+
sudo apt install chromium-driver
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
# Example Usage
|
| 59 |
+
|
| 60 |
+
The following code performs a deterministic action on the
|
| 61 |
+
[`click-test-2`](http://miniwob.farama.org/environments/click-test-2/) environment.
|
| 62 |
+
|
| 63 |
+
```python
|
| 64 |
+
import time
|
| 65 |
+
import gymnasium
|
| 66 |
+
import miniwob
|
| 67 |
+
from miniwob.action import ActionTypes
|
| 68 |
+
|
| 69 |
+
gymnasium.register_envs(miniwob)
|
| 70 |
+
|
| 71 |
+
env = gymnasium.make('miniwob/click-test-2-v1', render_mode='human')
|
| 72 |
+
|
| 73 |
+
# Wrap the code in try-finally to ensure proper cleanup.
|
| 74 |
+
try:
|
| 75 |
+
# Start a new episode.
|
| 76 |
+
obs, info = env.reset()
|
| 77 |
+
assert obs["utterance"] == "Click button ONE."
|
| 78 |
+
assert obs["fields"] == (("target", "ONE"),)
|
| 79 |
+
time.sleep(2) # Only here to let you look at the environment.
|
| 80 |
+
|
| 81 |
+
# Find the HTML element with text "ONE".
|
| 82 |
+
for element in obs["dom_elements"]:
|
| 83 |
+
if element["text"] == "ONE":
|
| 84 |
+
break
|
| 85 |
+
|
| 86 |
+
# Click on the element.
|
| 87 |
+
action = env.unwrapped.create_action(ActionTypes.CLICK_ELEMENT, ref=element["ref"])
|
| 88 |
+
obs, reward, terminated, truncated, info = env.step(action)
|
| 89 |
+
|
| 90 |
+
# Check if the action was correct.
|
| 91 |
+
print(reward) # Should be around 0.8 since 2 seconds has passed.
|
| 92 |
+
assert terminated is True
|
| 93 |
+
time.sleep(2)
|
| 94 |
+
|
| 95 |
+
finally:
|
| 96 |
+
env.close()
|
| 97 |
+
```
|
| 98 |
+
|
| 99 |
+
See [the documentation](http://miniwob.farama.org/content/basic_usage/) for more information.
|
| 100 |
+
|
| 101 |
+
# Environments
|
| 102 |
+
|
| 103 |
+
The list of the environments that were included in the MiniWoB++ library can be found in the
|
| 104 |
+
[documentation](http://miniwob.farama.org/environments/list/).
|
| 105 |
+
All environments share the same [observation space](http://miniwob.farama.org/content/observation_space/),
|
| 106 |
+
while the [action space](http://miniwob.farama.org/content/action_space/) can be configured during environment construction.
|
| 107 |
+
|
| 108 |
+
# Citation
|
| 109 |
+
|
| 110 |
+
To cite this project please use:
|
| 111 |
+
|
| 112 |
+
```bibtex
|
| 113 |
+
@inproceedings{liu2018reinforcement,
|
| 114 |
+
author = {Evan Zheran Liu and Kelvin Guu and Panupong Pasupat and Tianlin Shi and Percy Liang},
|
| 115 |
+
title = {Reinforcement Learning on Web Interfaces using Workflow-Guided Exploration},
|
| 116 |
+
booktitle = {International Conference on Learning Representations ({ICLR})},
|
| 117 |
+
url = {https://arxiv.org/abs/1802.08802},
|
| 118 |
+
year = {2018},
|
| 119 |
+
}
|
| 120 |
+
```
|
miniwob-plusplus/docs/.gitignore
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
environments/*.md
|
| 2 |
+
_build/
|
| 3 |
+
demos/
|
miniwob-plusplus/docs/404.md
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 404 - Page Not Found
|
| 2 |
+
|
| 3 |
+
## The requested page could not be found.
|
miniwob-plusplus/docs/README.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# MiniWoB++ documentation
|
| 2 |
+
|
| 3 |
+
This directory contains the documentation for MiniWoB++.
|
| 4 |
+
|
| 5 |
+
For more information about how to contribute to the documentation go to our [CONTRIBUTING.md](https://github.com/Farama-Foundation/Celshast/blob/main/CONTRIBUTING.md)
|
| 6 |
+
|
| 7 |
+
## Build the Documentation
|
| 8 |
+
|
| 9 |
+
Install the required packages and Gymnasium (or your fork):
|
| 10 |
+
|
| 11 |
+
```
|
| 12 |
+
pip install -r docs/requirements.txt
|
| 13 |
+
pip install -e .
|
| 14 |
+
```
|
| 15 |
+
|
| 16 |
+
To generate the environment pages:
|
| 17 |
+
|
| 18 |
+
```
|
| 19 |
+
python docs/_scripts/gen_mds.py
|
| 20 |
+
python docs/_scripts/gen_env_list.py
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
To build the documentation once:
|
| 24 |
+
|
| 25 |
+
```
|
| 26 |
+
cd docs
|
| 27 |
+
sphinx-build . _build
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
To rebuild the documentation automatically every time a change is made:
|
| 31 |
+
|
| 32 |
+
```
|
| 33 |
+
pip install sphinx-autobuild
|
| 34 |
+
cd docs
|
| 35 |
+
sphinx-autobuild . _build
|
| 36 |
+
```
|
miniwob-plusplus/docs/_scripts/gen_env_list.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Generate Environments List page content."""
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
import gymnasium as gym
|
| 5 |
+
import pandas as pd
|
| 6 |
+
|
| 7 |
+
import miniwob
|
| 8 |
+
from utils import extract_description_from_docstring, get_all_registered_miniwob_envs
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
gym.register_envs(miniwob)
|
| 12 |
+
gym.logger.set_level(gym.logger.DISABLED)
|
| 13 |
+
|
| 14 |
+
ENV_TYPES = [
|
| 15 |
+
{
|
| 16 |
+
"name": "Original Tasks",
|
| 17 |
+
"description": "These are the original MiniWoB tasks.",
|
| 18 |
+
"envs": [
|
| 19 |
+
"bisect-angle",
|
| 20 |
+
"book-flight",
|
| 21 |
+
"choose-date",
|
| 22 |
+
"choose-list",
|
| 23 |
+
"circle-center",
|
| 24 |
+
"click-button",
|
| 25 |
+
"click-button-sequence",
|
| 26 |
+
"click-checkboxes",
|
| 27 |
+
"click-collapsible",
|
| 28 |
+
"click-collapsible-2",
|
| 29 |
+
"click-color",
|
| 30 |
+
"click-dialog",
|
| 31 |
+
"click-dialog-2",
|
| 32 |
+
"click-link",
|
| 33 |
+
"click-menu",
|
| 34 |
+
"click-menu-2",
|
| 35 |
+
"click-option",
|
| 36 |
+
"click-pie",
|
| 37 |
+
"click-scroll-list",
|
| 38 |
+
"click-shades",
|
| 39 |
+
"click-shape",
|
| 40 |
+
"click-tab",
|
| 41 |
+
"click-tab-2",
|
| 42 |
+
"click-test",
|
| 43 |
+
"click-test-2",
|
| 44 |
+
"click-widget",
|
| 45 |
+
"copy-paste",
|
| 46 |
+
"copy-paste-2",
|
| 47 |
+
"count-shape",
|
| 48 |
+
"count-sides",
|
| 49 |
+
"drag-box",
|
| 50 |
+
"drag-circle",
|
| 51 |
+
"drag-cube",
|
| 52 |
+
"drag-items",
|
| 53 |
+
"drag-items-grid",
|
| 54 |
+
"drag-shapes",
|
| 55 |
+
"drag-sort-numbers",
|
| 56 |
+
"email-inbox",
|
| 57 |
+
"enter-date",
|
| 58 |
+
"enter-password",
|
| 59 |
+
"enter-text",
|
| 60 |
+
"enter-text-2",
|
| 61 |
+
"enter-text-dynamic",
|
| 62 |
+
"enter-time",
|
| 63 |
+
"find-midpoint",
|
| 64 |
+
"find-word",
|
| 65 |
+
"focus-text",
|
| 66 |
+
"focus-text-2",
|
| 67 |
+
"grid-coordinate",
|
| 68 |
+
"guess-number",
|
| 69 |
+
"highlight-text",
|
| 70 |
+
"highlight-text-2",
|
| 71 |
+
"identify-shape",
|
| 72 |
+
"login-user",
|
| 73 |
+
"navigate-tree",
|
| 74 |
+
"number-checkboxes",
|
| 75 |
+
"read-table",
|
| 76 |
+
"read-table-2",
|
| 77 |
+
"resize-textarea",
|
| 78 |
+
"right-angle",
|
| 79 |
+
"scroll-text",
|
| 80 |
+
"scroll-text-2",
|
| 81 |
+
"search-engine",
|
| 82 |
+
"simple-algebra",
|
| 83 |
+
"simple-arithmetic",
|
| 84 |
+
"social-media",
|
| 85 |
+
"terminal",
|
| 86 |
+
"text-editor",
|
| 87 |
+
"text-transform",
|
| 88 |
+
"tic-tac-toe",
|
| 89 |
+
"use-autocomplete",
|
| 90 |
+
"use-colorwheel",
|
| 91 |
+
"use-colorwheel-2",
|
| 92 |
+
"use-slider",
|
| 93 |
+
"use-slider-2",
|
| 94 |
+
"use-spinner",
|
| 95 |
+
"visual-addition",
|
| 96 |
+
],
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"name": "No-delay Tasks",
|
| 100 |
+
"description": """The UI elements in some tasks have animation delays
|
| 101 |
+
or change the state when the browser is defocused.
|
| 102 |
+
We provide the "no-delay" version without these issues.""",
|
| 103 |
+
"envs": [
|
| 104 |
+
"book-flight-nodelay",
|
| 105 |
+
"choose-date-nodelay",
|
| 106 |
+
"click-collapsible-nodelay",
|
| 107 |
+
"click-collapsible-2-nodelay",
|
| 108 |
+
"click-pie-nodelay",
|
| 109 |
+
"use-autocomplete-nodelay",
|
| 110 |
+
],
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"name": "Additional Tasks",
|
| 114 |
+
"description": """These tasks were introduced in MiniWoB++.
|
| 115 |
+
Some are harder versions of the existing tasks, while some are completely new.""",
|
| 116 |
+
"envs": [
|
| 117 |
+
"click-checkboxes-large",
|
| 118 |
+
"click-checkboxes-soft",
|
| 119 |
+
"click-checkboxes-transfer",
|
| 120 |
+
"click-tab-2-hard",
|
| 121 |
+
"login-user-popup",
|
| 122 |
+
"multi-layouts",
|
| 123 |
+
"multi-orderings",
|
| 124 |
+
"social-media-all",
|
| 125 |
+
"social-media-some",
|
| 126 |
+
"email-inbox-forward-nl",
|
| 127 |
+
"email-inbox-forward-nl-turk",
|
| 128 |
+
"email-inbox-nl-turk",
|
| 129 |
+
],
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"name": "Debug Tasks",
|
| 133 |
+
"description": "These are easier versions of existing tasks, suitable for debugging.",
|
| 134 |
+
"envs": [
|
| 135 |
+
"choose-date-easy",
|
| 136 |
+
"choose-date-medium",
|
| 137 |
+
"click-tab-2-easy",
|
| 138 |
+
"click-tab-2-medium",
|
| 139 |
+
"click-test-transfer",
|
| 140 |
+
"email-inbox-delete",
|
| 141 |
+
"email-inbox-forward",
|
| 142 |
+
"email-inbox-important",
|
| 143 |
+
"email-inbox-noscroll",
|
| 144 |
+
"email-inbox-reply",
|
| 145 |
+
"email-inbox-star-reply",
|
| 146 |
+
"unicode-test",
|
| 147 |
+
],
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"name": "Flight Search Tasks",
|
| 151 |
+
"description": """These are ports of the FormWoB tasks in the original World of Bits paper.,
|
| 152 |
+
* The prompt is a list of key-value pairs (e.g., Departure City: New York).
|
| 153 |
+
* If the required fields are not filled, or if the agent navigates away from the page, the reward is -1.,
|
| 154 |
+
* Otherwise, the reward is the fraction of key-value pairs that are satisfied.""",
|
| 155 |
+
"envs": ["flight.Alaska", "flight.Alaska-auto", "flight.AA"],
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"name": "Hidden Test Tasks",
|
| 159 |
+
"description": "These are tasks intended to be used as the hidden test set. They were originally not available from the OpenAI website.",
|
| 160 |
+
"envs": [
|
| 161 |
+
"ascending-numbers",
|
| 162 |
+
"buy-ticket",
|
| 163 |
+
"daily-calendar",
|
| 164 |
+
"drag-single-shape",
|
| 165 |
+
"drag-shapes-2",
|
| 166 |
+
"draw-circle",
|
| 167 |
+
"draw-line",
|
| 168 |
+
"find-greatest",
|
| 169 |
+
"form-sequence",
|
| 170 |
+
"form-sequence-2",
|
| 171 |
+
"form-sequence-3",
|
| 172 |
+
"generate-number",
|
| 173 |
+
"hot-cold",
|
| 174 |
+
"odd-or-even",
|
| 175 |
+
"order-food",
|
| 176 |
+
"phone-book",
|
| 177 |
+
"sign-agreement",
|
| 178 |
+
"stock-market",
|
| 179 |
+
],
|
| 180 |
+
},
|
| 181 |
+
]
|
| 182 |
+
|
| 183 |
+
|
| 184 |
+
# Get environment descriptions
|
| 185 |
+
ENVS_DESCRIPTIONS = {}
|
| 186 |
+
filtered_envs = get_all_registered_miniwob_envs()
|
| 187 |
+
for env_spec in filtered_envs:
|
| 188 |
+
try:
|
| 189 |
+
env_spec = gym.spec(env_spec.id)
|
| 190 |
+
|
| 191 |
+
split = env_spec.entry_point.split(":")
|
| 192 |
+
mod = __import__(split[0], fromlist=[split[1]])
|
| 193 |
+
env_class = getattr(mod, split[1])
|
| 194 |
+
docstring = env_class.__doc__
|
| 195 |
+
|
| 196 |
+
if not docstring:
|
| 197 |
+
docstring = env_class.__class__.__doc__
|
| 198 |
+
|
| 199 |
+
description = extract_description_from_docstring(docstring)
|
| 200 |
+
ENVS_DESCRIPTIONS[env_spec.name] = description
|
| 201 |
+
except Exception as e:
|
| 202 |
+
print(e)
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
file_start_content = """# Environments List
|
| 206 |
+
|
| 207 |
+
```{toctree}
|
| 208 |
+
:hidden:
|
| 209 |
+
:glob:
|
| 210 |
+
|
| 211 |
+
../environments/*
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
"""
|
| 215 |
+
|
| 216 |
+
list_md_path = os.path.join(os.path.dirname(__file__), "..", "environments", "list.md")
|
| 217 |
+
with open(list_md_path, "w") as fp:
|
| 218 |
+
content = file_start_content
|
| 219 |
+
for env_type in ENV_TYPES:
|
| 220 |
+
df = pd.DataFrame(
|
| 221 |
+
{
|
| 222 |
+
"Name": [f"[{env}](./{env})" for env in env_type["envs"]],
|
| 223 |
+
"Description": [ENVS_DESCRIPTIONS[env] for env in env_type["envs"]],
|
| 224 |
+
}
|
| 225 |
+
)
|
| 226 |
+
type_name = env_type["name"]
|
| 227 |
+
type_desc = env_type["description"]
|
| 228 |
+
content += f"## {type_name}\n\n"
|
| 229 |
+
content += f"{type_desc}\n\n"
|
| 230 |
+
content += df.to_markdown(index=False) + "\n\n"
|
| 231 |
+
|
| 232 |
+
content += """
|
| 233 |
+
## Excluded Tasks
|
| 234 |
+
|
| 235 |
+
The following tasks require the agent to wait for events to happen before acting,
|
| 236 |
+
and a 'no-delay' version is impossible to make.
|
| 237 |
+
|
| 238 |
+
| Name | Description |
|
| 239 |
+
|:------------ |:---------------------------------------------------------------- |
|
| 240 |
+
| chase-circle | Keep your mouse inside a moving circle. |
|
| 241 |
+
| moving-items | Click moving items before they disappear. |
|
| 242 |
+
| simon-says | Push the buttons in the order shown. |
|
| 243 |
+
| button-delay | Wait a certain period of time before clicking the second button. |
|
| 244 |
+
| hover-shape | Hover over the colored shape. |
|
| 245 |
+
"""
|
| 246 |
+
fp.write(content)
|
miniwob-plusplus/docs/_scripts/gen_mds.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Generate markdown files for the environments."""
|
| 2 |
+
import os
|
| 3 |
+
import shutil
|
| 4 |
+
|
| 5 |
+
import gymnasium as gym
|
| 6 |
+
|
| 7 |
+
import miniwob
|
| 8 |
+
from utils import get_all_registered_miniwob_envs, trim_docstring
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
LAYOUT = "env"
|
| 12 |
+
|
| 13 |
+
gym.register_envs(miniwob)
|
| 14 |
+
gym.logger.set_level(gym.logger.DISABLED)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
# Copy MiniWoB-plusplus/miniwob/html to /docs/demos/
|
| 18 |
+
source_path = os.path.join(
|
| 19 |
+
os.path.dirname(__file__),
|
| 20 |
+
"..",
|
| 21 |
+
"..",
|
| 22 |
+
"miniwob",
|
| 23 |
+
"html",
|
| 24 |
+
)
|
| 25 |
+
# Sphinx copies everything inside the first demos/ directory to the root
|
| 26 |
+
# So to ensure that the final path is /demos/** we need another demos folder
|
| 27 |
+
destination_path = os.path.join(os.path.dirname(__file__), "..", "demos", "demos")
|
| 28 |
+
shutil.copytree(source_path, destination_path)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
# Update Docs
|
| 32 |
+
filtered_envs = get_all_registered_miniwob_envs()
|
| 33 |
+
for i, env_spec in enumerate(filtered_envs):
|
| 34 |
+
print("ID:", env_spec.id)
|
| 35 |
+
try:
|
| 36 |
+
env_spec = gym.spec(env_spec.id)
|
| 37 |
+
|
| 38 |
+
split = env_spec.entry_point.split(":")
|
| 39 |
+
mod = __import__(split[0], fromlist=[split[1]])
|
| 40 |
+
env_class = getattr(mod, split[1])
|
| 41 |
+
docstring = env_class.__doc__
|
| 42 |
+
|
| 43 |
+
if not docstring:
|
| 44 |
+
docstring = env_class.__class__.__doc__
|
| 45 |
+
|
| 46 |
+
docstring = trim_docstring(docstring)
|
| 47 |
+
|
| 48 |
+
env_type = "miniwob"
|
| 49 |
+
env_name = env_spec.name
|
| 50 |
+
title_env_name = env_name
|
| 51 |
+
|
| 52 |
+
# path for saving the markdown file
|
| 53 |
+
md_path = os.path.join(
|
| 54 |
+
os.path.dirname(__file__),
|
| 55 |
+
"..",
|
| 56 |
+
"environments",
|
| 57 |
+
env_name + ".md",
|
| 58 |
+
)
|
| 59 |
+
os.makedirs(os.path.dirname(md_path), exist_ok=True)
|
| 60 |
+
|
| 61 |
+
front_matter = f"""---
|
| 62 |
+
autogenerated:
|
| 63 |
+
title: {title_env_name}
|
| 64 |
+
---
|
| 65 |
+
"""
|
| 66 |
+
title = f"# {title_env_name}"
|
| 67 |
+
if env_name.startswith("flight."):
|
| 68 |
+
url = f'../../demos/{env_name.replace(".", "/")}/wrapper.html'
|
| 69 |
+
info = f"""
|
| 70 |
+
<center>
|
| 71 |
+
<a href="{url}" target="_blank"><button>Open demo in a separate tab.</button></a>
|
| 72 |
+
</center>
|
| 73 |
+
"""
|
| 74 |
+
else:
|
| 75 |
+
url = f"../../demos/miniwob/{env_name}.html"
|
| 76 |
+
info = f"""
|
| 77 |
+
<center>
|
| 78 |
+
<iframe src="{url}" width="325" height="210" scrolling="no" style="overflow:hidden;">
|
| 79 |
+
</iframe><br>
|
| 80 |
+
<a href="{url}" target="_blank"><button>Open demo in a separate tab.</button></a>
|
| 81 |
+
</center>
|
| 82 |
+
"""
|
| 83 |
+
if docstring is None:
|
| 84 |
+
docstring = "No information provided"
|
| 85 |
+
all_text = f"""{front_matter}
|
| 86 |
+
{title}
|
| 87 |
+
|
| 88 |
+
{info}
|
| 89 |
+
|
| 90 |
+
{docstring}
|
| 91 |
+
"""
|
| 92 |
+
file = open(md_path, "w", encoding="utf-8")
|
| 93 |
+
file.write(all_text)
|
| 94 |
+
file.close()
|
| 95 |
+
except Exception as e:
|
| 96 |
+
print(e)
|
miniwob-plusplus/docs/_scripts/move_404.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Move 404.md to the _build directory."""
|
| 2 |
+
import sys
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
if __name__ == "__main__":
|
| 6 |
+
if len(sys.argv) < 2:
|
| 7 |
+
print("Provide a path")
|
| 8 |
+
filePath = sys.argv[1]
|
| 9 |
+
|
| 10 |
+
with open(filePath, "r+") as fp:
|
| 11 |
+
content = fp.read()
|
| 12 |
+
content = content.replace('href="../', 'href="/').replace('src="../', 'src="/')
|
| 13 |
+
fp.seek(0)
|
| 14 |
+
fp.truncate()
|
| 15 |
+
|
| 16 |
+
fp.write(content)
|
miniwob-plusplus/docs/_scripts/utils.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Utilities for documentation generation."""
|
| 2 |
+
import logging
|
| 3 |
+
|
| 4 |
+
import gymnasium as gym
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
def get_all_registered_miniwob_envs():
|
| 8 |
+
"""Return all registered MiniWoB environments."""
|
| 9 |
+
envs = []
|
| 10 |
+
for env_spec in gym.registry.values():
|
| 11 |
+
if env_spec.namespace == "miniwob":
|
| 12 |
+
envs.append(env_spec)
|
| 13 |
+
return sorted(envs, key=lambda x: x.name)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def trim_docstring(docstring):
|
| 17 |
+
"""Format whitespaces in the docstring."""
|
| 18 |
+
if not docstring:
|
| 19 |
+
return ""
|
| 20 |
+
# Convert tabs to spaces (following the normal Python rules)
|
| 21 |
+
# and split into a list of lines:
|
| 22 |
+
lines = docstring.expandtabs().splitlines()
|
| 23 |
+
# Determine minimum indentation (first line doesn't count):
|
| 24 |
+
indent = 232323
|
| 25 |
+
for line in lines[1:]:
|
| 26 |
+
stripped = line.lstrip()
|
| 27 |
+
if stripped:
|
| 28 |
+
indent = min(indent, len(line) - len(stripped))
|
| 29 |
+
# Remove indentation (first line is special):
|
| 30 |
+
trimmed = [lines[0].strip()]
|
| 31 |
+
if indent < 232323:
|
| 32 |
+
for line in lines[1:]:
|
| 33 |
+
trimmed.append(line[indent:].rstrip())
|
| 34 |
+
# Strip off trailing and leading blank lines:
|
| 35 |
+
while trimmed and not trimmed[-1]:
|
| 36 |
+
trimmed.pop()
|
| 37 |
+
while trimmed and not trimmed[0]:
|
| 38 |
+
trimmed.pop(0)
|
| 39 |
+
# Return a single string:
|
| 40 |
+
return "\n".join(trimmed)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
def extract_description_from_docstring(docstring):
|
| 44 |
+
"""Extract the task description for the docstring."""
|
| 45 |
+
if not docstring:
|
| 46 |
+
return ""
|
| 47 |
+
lines = [line.strip() for line in docstring.splitlines() if line.strip()]
|
| 48 |
+
if lines[0] != "## Description":
|
| 49 |
+
logging.warning(f"Invalid docstring header: {lines[0]}")
|
| 50 |
+
return ""
|
| 51 |
+
return lines[1]
|
miniwob-plusplus/docs/_static/img/custom-environment-1.png
ADDED
|
miniwob-plusplus/docs/_static/img/example-usage-1.png
ADDED
|
miniwob-plusplus/docs/_static/img/example-usage-2.png
ADDED
|
miniwob-plusplus/docs/_static/img/favicon.png
ADDED
|
|
miniwob-plusplus/docs/_static/img/miniwobplusplus-github.png
ADDED
|
miniwob-plusplus/docs/_static/img/miniwobplusplus-text.png
ADDED
|
Git LFS Details
|
miniwob-plusplus/docs/_static/img/miniwobplusplus-text.svg
ADDED
|
|
miniwob-plusplus/docs/_static/img/miniwobplusplus-white.svg
ADDED
|
|
miniwob-plusplus/docs/_static/img/miniwobplusplus.svg
ADDED
|
|
miniwob-plusplus/docs/_static/img/showcase-static.png
ADDED
|
Git LFS Details
|
miniwob-plusplus/docs/_static/img/showcase.gif
ADDED
|
Git LFS Details
|
miniwob-plusplus/docs/_static/videos/miniwob.mp4
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:880884a37094c4b81fd122c49a17d77d72f05449da449d6a577d4e9608e80366
|
| 3 |
+
size 1428063
|
miniwob-plusplus/docs/conf.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Configuration file for the Sphinx documentation builder."""
|
| 2 |
+
# This file only contains a selection of the most common options. For a full
|
| 3 |
+
# list see the documentation:
|
| 4 |
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
| 5 |
+
|
| 6 |
+
# -- Path setup --------------------------------------------------------------
|
| 7 |
+
|
| 8 |
+
# If extensions (or modules to document with autodoc) are in another directory,
|
| 9 |
+
# add these directories to sys.path here. If the directory is relative to the
|
| 10 |
+
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
| 11 |
+
#
|
| 12 |
+
# import os
|
| 13 |
+
# import sys
|
| 14 |
+
# sys.path.insert(0, os.path.abspath('.'))
|
| 15 |
+
|
| 16 |
+
# -- Project information -----------------------------------------------------
|
| 17 |
+
import miniwob
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
project = "MiniWoB++"
|
| 21 |
+
copyright = "2023 Farama Foundation"
|
| 22 |
+
author = "Farama Foundation"
|
| 23 |
+
|
| 24 |
+
# The full version, including alpha/beta/rc tags
|
| 25 |
+
release = miniwob.__version__
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
# -- General configuration ---------------------------------------------------
|
| 29 |
+
|
| 30 |
+
# Add any Sphinx extension module names here, as strings. They can be
|
| 31 |
+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
| 32 |
+
# ones.
|
| 33 |
+
extensions = [
|
| 34 |
+
"sphinx.ext.napoleon",
|
| 35 |
+
"sphinx.ext.doctest",
|
| 36 |
+
"sphinx.ext.autodoc",
|
| 37 |
+
"sphinx.ext.githubpages",
|
| 38 |
+
"sphinx.ext.viewcode",
|
| 39 |
+
"myst_parser",
|
| 40 |
+
]
|
| 41 |
+
|
| 42 |
+
# Add any paths that contain templates here, relative to this directory.
|
| 43 |
+
templates_path = ["_templates"]
|
| 44 |
+
|
| 45 |
+
# List of patterns, relative to source directory, that match files and
|
| 46 |
+
# directories to ignore when looking for source files.
|
| 47 |
+
# This pattern also affects html_static_path and html_extra_path.
|
| 48 |
+
exclude_patterns = []
|
| 49 |
+
|
| 50 |
+
# Napoleon settings
|
| 51 |
+
napoleon_use_ivar = True
|
| 52 |
+
napoleon_use_admonition_for_references = True
|
| 53 |
+
# See https://github.com/sphinx-doc/sphinx/issues/9119
|
| 54 |
+
napoleon_custom_sections = [("Returns", "params_style")]
|
| 55 |
+
|
| 56 |
+
# -- Options for HTML output -------------------------------------------------
|
| 57 |
+
|
| 58 |
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
| 59 |
+
# a list of builtin themes.
|
| 60 |
+
#
|
| 61 |
+
html_theme = "furo"
|
| 62 |
+
html_title = "MiniWoB++ Documentation"
|
| 63 |
+
html_baseurl = "https://miniwob.farama.org"
|
| 64 |
+
html_copy_source = False
|
| 65 |
+
html_favicon = "_static/img/favicon.png"
|
| 66 |
+
html_theme_options = {
|
| 67 |
+
"light_logo": "img/miniwobplusplus.svg",
|
| 68 |
+
"dark_logo": "img/miniwobplusplus-white.svg",
|
| 69 |
+
"description": "A collection of over 100 web interaction environments, along with JavaScript and Python interfaces.",
|
| 70 |
+
"image": "img/miniwobplusplus-github.png",
|
| 71 |
+
"source_repository": "https://github.com/Farama-Foundation/miniwob-plusplus/",
|
| 72 |
+
"source_branch": "master",
|
| 73 |
+
"source_directory": "docs/",
|
| 74 |
+
"versioning": True,
|
| 75 |
+
"gtag": "G-PR9ZPS99C2",
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
html_static_path = ["_static"]
|
| 79 |
+
html_extra_path = ["demos"]
|
| 80 |
+
html_css_files = []
|
miniwob-plusplus/docs/content/action_space.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Action Space
|
| 2 |
+
|
| 3 |
+
An action is specified by an **action type** (e.g., `CLICK_COORDS`)
|
| 4 |
+
and the necessary fields for that action type (e.g., `coords=[30, 60]`).
|
| 5 |
+
|
| 6 |
+
## Supported Action Types
|
| 7 |
+
|
| 8 |
+
MiniWoB++ environments support the following action types:
|
| 9 |
+
|
| 10 |
+
```{list-table}
|
| 11 |
+
:header-rows: 1
|
| 12 |
+
* - Name
|
| 13 |
+
- Description
|
| 14 |
+
* - `NONE`
|
| 15 |
+
- Do nothing for the current step.
|
| 16 |
+
* - `MOVE_COORDS`
|
| 17 |
+
- Move the cursor to the specified coordinates.
|
| 18 |
+
* - `CLICK_COORDS`
|
| 19 |
+
- Click on the specified coordinates.
|
| 20 |
+
* - `DBLCLICK_COORDS`
|
| 21 |
+
- Double-click on the specified coordinates.
|
| 22 |
+
* - `MOUSEDOWN_COORDS`
|
| 23 |
+
- Start dragging on the specified coordinates.
|
| 24 |
+
* - `MOUSEUP_COORDS`
|
| 25 |
+
- Stop dragging on the specified coordinates.
|
| 26 |
+
* - `SCROLL_UP_COORDS`
|
| 27 |
+
- Scroll up on the mouse wheel at the specified coordinates.
|
| 28 |
+
* - `SCROLL_DOWN_COORDS`
|
| 29 |
+
- Scroll down on the mouse wheel at the specified coordinates.
|
| 30 |
+
* - `CLICK_ELEMENT`
|
| 31 |
+
- Click on the specified element using JavaScript.
|
| 32 |
+
* - `PRESS_KEY`
|
| 33 |
+
- Press the specified [key or key combination](#key-combinations).
|
| 34 |
+
* - `TYPE_TEXT`
|
| 35 |
+
- Type the specified string.
|
| 36 |
+
* - `TYPE_FIELD`
|
| 37 |
+
- Type the value of the specified task field.
|
| 38 |
+
* - `FOCUS_ELEMENT_AND_TYPE_TEXT`
|
| 39 |
+
- Click on the specified element using JavaScript, and then type the specified string.
|
| 40 |
+
* - `FOCUS_ELEMENT_AND_TYPE_FIELD`
|
| 41 |
+
- Click on the specified element using JavaScript, and then type the value of the specified task field.
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
There are action types that perform similar actions (e.g., `CLICK_COORDS` and `CLICK_ELEMENT`).
|
| 45 |
+
A common practice is to specify a subset of action types that the agent can use in the config, as described below.
|
| 46 |
+
|
| 47 |
+
(action-configs)=
|
| 48 |
+
## Action Configs
|
| 49 |
+
|
| 50 |
+
The list of selected action types, along with other configurations, can be customized
|
| 51 |
+
by passing a `miniwob.action.ActionSpaceConfig` object to the `action_space_config` argument
|
| 52 |
+
during environment construction.
|
| 53 |
+
|
| 54 |
+
An `ActionSpaceConfig` object has the following fields:
|
| 55 |
+
|
| 56 |
+
```{list-table}
|
| 57 |
+
:header-rows: 1
|
| 58 |
+
* - Key
|
| 59 |
+
- Type
|
| 60 |
+
- Description
|
| 61 |
+
* - `action_types`
|
| 62 |
+
- `Sequence[ActionTypes]`
|
| 63 |
+
- An ordered sequence of action types to include.
|
| 64 |
+
* - `screen_width`
|
| 65 |
+
- `float`
|
| 66 |
+
- Screen width. Will be overridden by the environment constructor.
|
| 67 |
+
* - `screen_height`
|
| 68 |
+
- `float`
|
| 69 |
+
- Screen height. Will be overridden by the environment constructor.
|
| 70 |
+
* - `coord_bins`
|
| 71 |
+
- `tuple[int, int]`
|
| 72 |
+
- If specified, bin the x and y coordinates to these numbers of bins.
|
| 73 |
+
Mouse actions will be executed at the middle of the specified partition.
|
| 74 |
+
* - `scroll_amount`
|
| 75 |
+
- `int`
|
| 76 |
+
- The amount to scroll for scroll actions.
|
| 77 |
+
* - `scroll_time`
|
| 78 |
+
- `int`
|
| 79 |
+
- Time in milliseconds to wait for scroll action animation.
|
| 80 |
+
* - `allowed_keys`
|
| 81 |
+
- `Sequence[str]`
|
| 82 |
+
- An ordered sequence of allowed [keys and key combinations](#key-combinations) for the `PRESS_KEY` action.
|
| 83 |
+
* - `text_max_len`
|
| 84 |
+
- `int`
|
| 85 |
+
- Maximum text length for the `TYPE_TEXT` action.
|
| 86 |
+
* - `text_charset`
|
| 87 |
+
- `str` or `set[str]`
|
| 88 |
+
- Character set for the `TYPE_TEXT` action.
|
| 89 |
+
```
|
| 90 |
+
|
| 91 |
+
(presets)=
|
| 92 |
+
### Presets
|
| 93 |
+
|
| 94 |
+
The following preset names can be specified in place of the `ActionSpaceConfig` object:
|
| 95 |
+
|
| 96 |
+
* `"all_supported"`: Select all supported actions, including redundant ones.
|
| 97 |
+
* `"shi17"`: The action space from (Shi et al., 2017)
|
| 98 |
+
[World of Bits: An Open-Domain Platform for Web-Based Agents](http://proceedings.mlr.press/v70/shi17a/shi17a.pdf).
|
| 99 |
+
* `"liu18"`: The action space from (Liu et al., 2018)
|
| 100 |
+
[Reinforcement Learning on Web Interfaces Using Workflow-Guided Exploration](https://arxiv.org/abs/1802.08802).
|
| 101 |
+
* `"humphreys22"`: The action space from (Humphreys et al., 2022)
|
| 102 |
+
[A data-driven approach for learning to control computers](https://arxiv.org/abs/2202.08137).
|
| 103 |
+
|
| 104 |
+
Adding `"_mac_os"` to the preset name will change the key modifiers in `allowed_keys`
|
| 105 |
+
from Control to Meta.
|
| 106 |
+
|
| 107 |
+
(key-combinations)=
|
| 108 |
+
### Key combinations
|
| 109 |
+
|
| 110 |
+
The `PRESS_KEY` action type issues a key combination via Selenium.
|
| 111 |
+
Each key combination in the `allowed_keys` config follow the rules:
|
| 112 |
+
|
| 113 |
+
* Modifiers are specified using prefixes "C-" (Control), "S-" (Shift),
|
| 114 |
+
"A-" (Alternate), or "M-" (Meta).
|
| 115 |
+
* Printable character keys (a, 1, etc.) are specified directly.
|
| 116 |
+
Shifted characters (A, !, etc.) are equivalent to "S-" + non-shifted counterpart.
|
| 117 |
+
* Special keys are inclosed in "<...>". The list of valid names is specified in
|
| 118 |
+
`miniwob.constants.WEBDRIVER_SPECIAL_KEYS`.
|
| 119 |
+
|
| 120 |
+
Example valid key combinations:`"7"`, `"<Enter>"`, `"C-S-<ArrowLeft>"`.
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
## Action Object
|
| 124 |
+
|
| 125 |
+
The action passed to the [`step`](https://gymnasium.farama.org/api/env/#gymnasium.Env.step) method
|
| 126 |
+
should be a `dict` whose field inclusion depends on the selected action types in the config:
|
| 127 |
+
|
| 128 |
+
```{list-table}
|
| 129 |
+
:header-rows: 1
|
| 130 |
+
* - Key
|
| 131 |
+
- Type
|
| 132 |
+
- Description
|
| 133 |
+
- Inclusion
|
| 134 |
+
* - `action_type`
|
| 135 |
+
- `int`
|
| 136 |
+
- Action type index from the `action_types` list in the config.
|
| 137 |
+
- Always.
|
| 138 |
+
* - `coords`
|
| 139 |
+
- `np.ndarray` of shape `(2,)`
|
| 140 |
+
- Left and top coordinates.
|
| 141 |
+
Depending on the `coord_bins` config, the values can be of type `int8` (binned) or `float32` (unbinned).
|
| 142 |
+
- When any `*COORDS` action type is selected.
|
| 143 |
+
* - `ref`
|
| 144 |
+
- `int`
|
| 145 |
+
- Element `ref` ID. If no element has the specified `ref`, the action becomes a no-op.
|
| 146 |
+
- When any `*_ELEMENT*` action type is selected.
|
| 147 |
+
* - `key`
|
| 148 |
+
- `int`
|
| 149 |
+
- Key index from the `allowed_keys` list in the config.
|
| 150 |
+
- When the `PRESS_KEY` action type is selected.
|
| 151 |
+
* - `text`
|
| 152 |
+
- `str`
|
| 153 |
+
- Text to type.
|
| 154 |
+
- When any `*_TYPE_TEXT` action type is selected.
|
| 155 |
+
* - `field`
|
| 156 |
+
- `int`
|
| 157 |
+
- Index from the task field list `obs["fields"]`. If the index is out of bound, no text will be typed.
|
| 158 |
+
- When any `*_TYPE_FIELD` action type is selected.
|
| 159 |
+
```
|
| 160 |
+
|
| 161 |
+
For instance, if the config only contains action types `CLICK_COORDS` and `PRESS_KEY`,
|
| 162 |
+
the action object can be
|
| 163 |
+
|
| 164 |
+
```python
|
| 165 |
+
action = {
|
| 166 |
+
"action_type": 0, # CLICK_COORDS
|
| 167 |
+
"coords": np.array([100, 50]),
|
| 168 |
+
"key": 0, # Ignored by the action CLICK_COORDS
|
| 169 |
+
}
|
| 170 |
+
```
|
| 171 |
+
|
miniwob-plusplus/docs/content/basic_usage.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Basic Usage
|
| 2 |
+
|
| 3 |
+
## Simple Example
|
| 4 |
+
|
| 5 |
+
The following code performs a deterministic action on the
|
| 6 |
+
[`click-test-2`](/environments/click-test-2) environment.
|
| 7 |
+
|
| 8 |
+
```python
|
| 9 |
+
import time
|
| 10 |
+
import gymnasium
|
| 11 |
+
import miniwob
|
| 12 |
+
from miniwob.action import ActionTypes
|
| 13 |
+
|
| 14 |
+
gymnasium.register_envs(miniwob)
|
| 15 |
+
|
| 16 |
+
env = gymnasium.make('miniwob/click-test-2-v1', render_mode='human')
|
| 17 |
+
|
| 18 |
+
# Wrap the code in try-finally to ensure proper cleanup.
|
| 19 |
+
try:
|
| 20 |
+
# Start a new episode.
|
| 21 |
+
observation, info = env.reset()
|
| 22 |
+
assert observation["utterance"] == "Click button ONE."
|
| 23 |
+
assert observation["fields"] == (("target", "ONE"),)
|
| 24 |
+
time.sleep(2) # Only here to let you look at the environment.
|
| 25 |
+
|
| 26 |
+
# Find the HTML element with text "ONE".
|
| 27 |
+
for element in observation["dom_elements"]:
|
| 28 |
+
if element["text"] == "ONE":
|
| 29 |
+
break
|
| 30 |
+
|
| 31 |
+
# Click on the element.
|
| 32 |
+
action = env.unwrapped.create_action(ActionTypes.CLICK_ELEMENT, ref=element["ref"])
|
| 33 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 34 |
+
|
| 35 |
+
# Check if the action was correct.
|
| 36 |
+
print(reward) # Should be around 0.8 since 2 seconds has passed.
|
| 37 |
+
assert terminated is True
|
| 38 |
+
time.sleep(2)
|
| 39 |
+
|
| 40 |
+
finally:
|
| 41 |
+
env.close()
|
| 42 |
+
```
|
| 43 |
+
|
| 44 |
+
The output should look something like this:
|
| 45 |
+
|
| 46 |
+
```{image} /_static/img/example-usage-1.png
|
| 47 |
+
:width: 50%
|
| 48 |
+
:align: center
|
| 49 |
+
```
|
| 50 |
+
|
| 51 |
+
After 2 seconds:
|
| 52 |
+
|
| 53 |
+
```{image} /_static/img/example-usage-2.png
|
| 54 |
+
:width: 50%
|
| 55 |
+
:align: center
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
## Environment Initialization
|
| 59 |
+
|
| 60 |
+
An environment can be created using
|
| 61 |
+
[`gymnasium.make`](https://gymnasium.farama.org/api/registry/#gymnasium.make):
|
| 62 |
+
|
| 63 |
+
```python
|
| 64 |
+
env = gymnasium.make('miniwob/click-test-2-v1', render_mode='human')
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
Common arguments include:
|
| 68 |
+
|
| 69 |
+
* **`render_mode`:** Render mode. Supported values are:
|
| 70 |
+
- `None` (default): Headless Chrome, which does not show the browser window.
|
| 71 |
+
- `"human"`: Show the browser window.
|
| 72 |
+
* **`action_space_config`:** Configuration for the action space.
|
| 73 |
+
Supported values are:
|
| 74 |
+
- An [`ActionSpaceConfig`](/content/action_space.md#action-configs) object.
|
| 75 |
+
- A [preset name](/content/action_space.md#presets), which will instantiate an `ActionSpaceConfig` object.
|
| 76 |
+
|
| 77 |
+
## Observation Space
|
| 78 |
+
|
| 79 |
+
```python
|
| 80 |
+
observation, info = env.reset(seed=42)
|
| 81 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 82 |
+
```
|
| 83 |
+
|
| 84 |
+
The [`reset`](https://gymnasium.farama.org/api/env/#gymnasium.Env.reset)
|
| 85 |
+
and [`step`](https://gymnasium.farama.org/api/env/#gymnasium.Env.step) methods
|
| 86 |
+
return an observation, which is a `dict` with the following fields:
|
| 87 |
+
|
| 88 |
+
* **`utterance`:** Task instruction string, such as `"Click button ONE."`.
|
| 89 |
+
* **`fields`:** Environment-specific key-value pairs extracted from the utterance, such as `(("target", "ONE"),)`.
|
| 90 |
+
* **`screenshot`:** A numpy array of shape `(height, width, 3)` containing the RGB values.
|
| 91 |
+
* **`dom_elements`:** A tuple of dicts, each listing properties like the geometry and HTML attributes of a visible DOM element.
|
| 92 |
+
|
| 93 |
+
For example, the `observation` from the `reset` command above is
|
| 94 |
+
```python
|
| 95 |
+
{
|
| 96 |
+
'utterance': 'Click button ONE.',
|
| 97 |
+
'fields': (('target', 'ONE'),),
|
| 98 |
+
'screenshot': array([[[255, 255, 0], ...], ...], dtype=uint8),
|
| 99 |
+
'dom_elements': (
|
| 100 |
+
{'ref': 1, 'parent': 0, 'tag': 'body', ...},
|
| 101 |
+
{'ref': 2, 'parent': 1, 'tag': 'div', ...},
|
| 102 |
+
{'ref': 3, 'parent': 2, 'tag': 'div', ...},
|
| 103 |
+
{'ref': 4, 'parent': 3, 'tag': 'button', 'text': 'ONE', ...},
|
| 104 |
+
{'ref': 5, 'parent': 3, 'tag': 'button', 'text': 'TWO', ...},
|
| 105 |
+
),
|
| 106 |
+
}
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
See the [Observation Space](/content/observation_space) page for more details.
|
| 110 |
+
|
| 111 |
+
## Action Space
|
| 112 |
+
|
| 113 |
+
```python
|
| 114 |
+
action = env.unwrapped.create_action(ActionTypes.CLICK_ELEMENT, ref=element["ref"])
|
| 115 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 116 |
+
```
|
| 117 |
+
|
| 118 |
+
The [`step`](https://gymnasium.farama.org/api/env/#gymnasium.Env.step) method
|
| 119 |
+
takes an `action` object, which should be a `dict` with the following fields:
|
| 120 |
+
|
| 121 |
+
* **`action_type`:** The action type index from `env.unwrapped.action_space_config.action_types`.
|
| 122 |
+
* Other fields such as `ref`, `coords`, `text`, etc. should be specified based on the action type.
|
| 123 |
+
The action space `env.unwrapped.action_space` specifies which fields should be included.
|
| 124 |
+
|
| 125 |
+
For example, the `action` from the `create_action` command above is
|
| 126 |
+
```python
|
| 127 |
+
{
|
| 128 |
+
'action_type': 8, # ActionTypes.CLICK_ELEMENT in the default action config.
|
| 129 |
+
'ref': 4, # The button with text 'ONE' from observation['dom_elements'].
|
| 130 |
+
... # Other fields are ignored for CLICK_ELEMENT.
|
| 131 |
+
}
|
| 132 |
+
```
|
| 133 |
+
In actual code, the web agent should generate an action based on the observation.
|
| 134 |
+
|
| 135 |
+
See the [Action Space](/content/action_space) page for more details.
|
miniwob-plusplus/docs/content/custom_environment.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Creating a Custom Environment
|
| 2 |
+
|
| 3 |
+
Creating a custom MiniWoB++ environment is as simple as creating a new task HTML page, and then specifying the URL to the HTML file when registering the environment.
|
| 4 |
+
|
| 5 |
+
The following tutorial illustrates how to create a custom environment with the standard [observation space](/content/observation_space) and [action space](/content/action_space). For more advanced needs (customizing the spaces, creating a package, etc.), see this [Gymnasium tutorial](https://gymnasium.farama.org/tutorials/gymnasium_basics/environment_creation/).
|
| 6 |
+
|
| 7 |
+
## Creating the Task HTML Page
|
| 8 |
+
|
| 9 |
+
```{image} /_static/img/custom-environment-1.png
|
| 10 |
+
:width: 50%
|
| 11 |
+
:align: center
|
| 12 |
+
```
|
| 13 |
+
|
| 14 |
+
To properly interface with the MiniWoB++ library, the HTML file must include
|
| 15 |
+
[`core.css`](https://github.com/Farama-Foundation/miniwob-plusplus/blob/master/miniwob/html/core/core.css)
|
| 16 |
+
and
|
| 17 |
+
[`core.js`](https://github.com/Farama-Foundation/miniwob-plusplus/blob/master/miniwob/html/core/core.js).
|
| 18 |
+
These files are also available from the Python package (under `html/core/`).
|
| 19 |
+
|
| 20 |
+
Here is an example HTML file (`custom.html`):
|
| 21 |
+
|
| 22 |
+
```html
|
| 23 |
+
<!DOCTYPE html>
|
| 24 |
+
<html>
|
| 25 |
+
<head>
|
| 26 |
+
<title>Custom Task</title>
|
| 27 |
+
<!-- The following CSS and JS are required. -->
|
| 28 |
+
<link rel="stylesheet" type="text/css" href="core.css">
|
| 29 |
+
<script src="core.js"></script>
|
| 30 |
+
<script>
|
| 31 |
+
// genProblem() will be called at the start of each episode.
|
| 32 |
+
var genProblem = function() {
|
| 33 |
+
// core.randi(a, b) (from core.js) samples an integer between a and b (inclusive).
|
| 34 |
+
let targetAmount = core.randi(2, 5), clickedAmount = 0;
|
| 35 |
+
|
| 36 |
+
// Set the task utterance. This will become the "utterance" in the observation.
|
| 37 |
+
document.getElementById("query").textContent =
|
| 38 |
+
`Click Hello ${targetAmount} times, then click Submit.`;
|
| 39 |
+
|
| 40 |
+
// Create the task UI.
|
| 41 |
+
let hello = document.createElement("button");
|
| 42 |
+
let submit = document.createElement("button");
|
| 43 |
+
let amount = document.createElement("span");
|
| 44 |
+
document.getElementById("area").replaceChildren(hello, submit, amount);
|
| 45 |
+
|
| 46 |
+
hello.textContent = "Hello";
|
| 47 |
+
hello.addEventListener("click", () => {
|
| 48 |
+
clickedAmount++;
|
| 49 |
+
amount.textContent = clickedAmount;
|
| 50 |
+
});
|
| 51 |
+
|
| 52 |
+
submit.textContent = "Submit";
|
| 53 |
+
submit.addEventListener("click", () => {
|
| 54 |
+
if (clickedAmount === targetAmount) {
|
| 55 |
+
// core.endEpisode(reward, timeProportional) ends the episode and sets
|
| 56 |
+
// the reward (which can be read by Selenium). If timeProportional is
|
| 57 |
+
// true, then the reward is scaled by the amount of time left.
|
| 58 |
+
core.endEpisode(1.0, true);
|
| 59 |
+
} else {
|
| 60 |
+
core.endEpisode(-1.0, false);
|
| 61 |
+
}
|
| 62 |
+
});
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
window.onload = function() {
|
| 66 |
+
// core.startEpisode() prepares the web page for an episode by showing the "START"
|
| 67 |
+
// screen (it does not actually start the episode until "START" is clicked).
|
| 68 |
+
// core.startEpisode() will also be automatically called at the end of each episode.
|
| 69 |
+
core.startEpisode();
|
| 70 |
+
}
|
| 71 |
+
</script>
|
| 72 |
+
</head>
|
| 73 |
+
<body>
|
| 74 |
+
<!-- The following 3 divs are required. -->
|
| 75 |
+
<div id="wrap">
|
| 76 |
+
<div id="query"></div>
|
| 77 |
+
<div id="area"></div>
|
| 78 |
+
</div>
|
| 79 |
+
</body>
|
| 80 |
+
</html>
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
## Registering the Environment
|
| 84 |
+
|
| 85 |
+
The generic environment class `MiniWoBEnvironment` from `miniwob.environment` can be used as the entry point for the environment.
|
| 86 |
+
The following keyword arguments should be specified:
|
| 87 |
+
|
| 88 |
+
* `subdomain`: This should match the HTML filename.
|
| 89 |
+
* `base_url`: This should point to where the HTML is; the URL `{base_url}/{subdomain}.html` should point to the task page.
|
| 90 |
+
* `field_extractor`: This should be a function that takes the utterance string (that appears in the yellow box) and returns a list of fields as key-value tuples. One option is to not produce any field by specifying `lambda x: []`.
|
| 91 |
+
|
| 92 |
+
Here is example code (`custom_registry.py`):
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
```python
|
| 96 |
+
import pathlib
|
| 97 |
+
from gymnasium.envs.registration import register
|
| 98 |
+
from miniwob.fields import create_regex_field_extractor
|
| 99 |
+
|
| 100 |
+
register(
|
| 101 |
+
id='miniwob/custom-v0',
|
| 102 |
+
entry_point='miniwob.environment:MiniWoBEnvironment',
|
| 103 |
+
kwargs={
|
| 104 |
+
'subdomain': 'custom',
|
| 105 |
+
# Assuming that this file is in the same directory as `custom.html`:
|
| 106 |
+
'base_url': 'file://{}/'.format(pathlib.Path(__file__).parent),
|
| 107 |
+
# This helper method will produce a function that takes a string and returns
|
| 108 |
+
# [('amount', ___)], where ___ is from the capturing group in the regex.
|
| 109 |
+
'field_extractor': create_regex_field_extractor(
|
| 110 |
+
r'Click Hello (\d+) times, then click Submit\.', ['amount'],
|
| 111 |
+
)
|
| 112 |
+
},
|
| 113 |
+
)
|
| 114 |
+
```
|
| 115 |
+
|
| 116 |
+
## Using the Environment
|
| 117 |
+
|
| 118 |
+
The following code is adapted from the example in the [Basic Usage](/content/basic_usage) page:
|
| 119 |
+
|
| 120 |
+
```python
|
| 121 |
+
import time
|
| 122 |
+
import gymnasium
|
| 123 |
+
from miniwob.action import ActionTypes
|
| 124 |
+
from miniwob.fields import field_lookup
|
| 125 |
+
|
| 126 |
+
# Import `custom_registry.py` above to register the task.
|
| 127 |
+
import custom_registry
|
| 128 |
+
gymnasium.register_envs(custom_registry)
|
| 129 |
+
|
| 130 |
+
# Create an environment.
|
| 131 |
+
env = gymnasium.make('miniwob/custom-v0', render_mode='human')
|
| 132 |
+
|
| 133 |
+
# Wrap the code in try-finally to ensure proper cleanup.
|
| 134 |
+
try:
|
| 135 |
+
# Start a new episode.
|
| 136 |
+
observation, info = env.reset()
|
| 137 |
+
|
| 138 |
+
# Find the relevant HTML elements.
|
| 139 |
+
for hello_button in observation["dom_elements"]:
|
| 140 |
+
if hello_button["text"] == "Hello":
|
| 141 |
+
break
|
| 142 |
+
for submit_button in observation["dom_elements"]:
|
| 143 |
+
if submit_button["text"] == "Submit":
|
| 144 |
+
break
|
| 145 |
+
|
| 146 |
+
amount = int(field_lookup(observation['fields'], 'amount'))
|
| 147 |
+
for _ in range(amount):
|
| 148 |
+
# Click Hello.
|
| 149 |
+
action = env.unwrapped.create_action(ActionTypes.CLICK_ELEMENT, ref=hello_button["ref"])
|
| 150 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 151 |
+
time.sleep(0.5)
|
| 152 |
+
|
| 153 |
+
# Click Submit.
|
| 154 |
+
action = env.unwrapped.create_action(ActionTypes.CLICK_ELEMENT, ref=submit_button["ref"])
|
| 155 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 156 |
+
|
| 157 |
+
# Check if the action was correct.
|
| 158 |
+
assert reward >= 0
|
| 159 |
+
assert terminated is True
|
| 160 |
+
time.sleep(0.5)
|
| 161 |
+
|
| 162 |
+
finally:
|
| 163 |
+
env.close()
|
| 164 |
+
```
|
miniwob-plusplus/docs/content/demonstrations.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Demonstrations
|
| 2 |
+
|
| 3 |
+
We have recorded demonstrations from Mechanical Turk and put them in a [separate repository](https://github.com/stanfordnlp/miniwob-plusplus-demos).
|
| 4 |
+
|
| 5 |
+
## Demonstration Format
|
| 6 |
+
|
| 7 |
+
Each demonstration is saved as a JSON file. The root object generated by `core/record.js` contains the following fields:
|
| 8 |
+
|
| 9 |
+
* `taskName` (string)
|
| 10 |
+
* `utterance` (string)
|
| 11 |
+
* `reward` (number): Reward as defined by the task
|
| 12 |
+
* `rawReward` (number): 1 if succeeded and -1 if failed
|
| 13 |
+
* `states`: a list of state objects
|
| 14 |
+
* One state is recorded for the initial state
|
| 15 |
+
* Two states are recorded for each event, one before the event resolves and one after the event resolves
|
| 16 |
+
|
| 17 |
+
Each state object has the following fields:
|
| 18 |
+
|
| 19 |
+
* `time` (number): Time elapsed since the episode started
|
| 20 |
+
* `action`: An action-specific object (not present for the initial state) with the following common keys:
|
| 21 |
+
* `type` (string)
|
| 22 |
+
* `timing` (number): the `eventPhase` property of the JS event object.
|
| 23 |
+
This is 1 before the event resolves (capturing state) and 3 after the event resolves (bubbling state).
|
| 24 |
+
* `dom`: The DOM info as generated by `getDOMInfo()`
|
| 25 |
+
* The event target will have a special key `recordingTarget` set to `true`.
|
| 26 |
+
|
| 27 |
+
## Recording Your Own Demonstrations
|
| 28 |
+
|
| 29 |
+
1. Start the recording server:
|
| 30 |
+
```
|
| 31 |
+
# Create an output directory
|
| 32 |
+
mkdir out/
|
| 33 |
+
python -m miniwob.record out/
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
2. Append `?record=true` to the URL of the task you want to record. For example, for the `click-test` task, go to
|
| 37 |
+
```
|
| 38 |
+
file:///path/to/miniwob-plusplus/html/miniwob/click-test.html?record=true
|
| 39 |
+
```
|
| 40 |
+
(Note: For recent versions of Chrome, you might have to retype the whole URL instead of just appending `?record=true`.)
|
| 41 |
+
|
| 42 |
+
3. To view the results, open `viewer/viewer.html` while the recording server is running. The URL should be like
|
| 43 |
+
```
|
| 44 |
+
file:///path/to/miniwob-plusplus/html/viewer/viewer.html
|
| 45 |
+
```
|
| 46 |
+
|
miniwob-plusplus/docs/content/getting_started.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Getting Started
|
| 2 |
+
|
| 3 |
+
## Install the MiniWoB++ Library
|
| 4 |
+
|
| 5 |
+
To install the MiniWoB++ library, use `pip install miniwob`.
|
| 6 |
+
|
| 7 |
+
Alternatively, clone the repository from GitHub:
|
| 8 |
+
|
| 9 |
+
```sh
|
| 10 |
+
git clone https://github.com/Farama-Foundation/miniwob-plusplus.git
|
| 11 |
+
cd miniwob-plusplus
|
| 12 |
+
pip install -e .
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
If this gives you problems, try again and add pip's `--ignore-installed` flag.
|
| 16 |
+
|
| 17 |
+
## Install Chrome/Chromium and ChromeDriver
|
| 18 |
+
|
| 19 |
+
We strongly recommend using Chrome or Chromium as the web browser,
|
| 20 |
+
as other browsers may render the environments differently.
|
| 21 |
+
|
| 22 |
+
The MiniWoB++ Python interface uses [Selenium](https://www.selenium.dev/documentation/webdriver/),
|
| 23 |
+
which interacts with the browser via the [WebDriver API](https://w3c.github.io/webdriver/).
|
| 24 |
+
Follow one of the
|
| 25 |
+
[instruction methods](https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/)
|
| 26 |
+
to install ChromeDriver. The simplest method is to
|
| 27 |
+
[download](https://chromedriver.chromium.org/downloads) ChromeDriver with the matching version,
|
| 28 |
+
unzip it, and then add the directory containing the `chromedriver` executable to the `PATH` environment variable:
|
| 29 |
+
|
| 30 |
+
```sh
|
| 31 |
+
export PATH=$PATH:/path/to/chromedriver
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
For Chromium, the driver may also be available in a software package; for example, in Debian/Ubuntu:
|
| 35 |
+
|
| 36 |
+
```sh
|
| 37 |
+
sudo apt install chromium-driver
|
| 38 |
+
```
|
| 39 |
+
|
| 40 |
+
## Development Environment
|
| 41 |
+
|
| 42 |
+
For information about setting up a development environment,
|
| 43 |
+
see [`CONTRIBUTING.md`](https://github.com/Farama-Foundation/miniwob-plusplus/blob/master/CONTRIBUTING.md).
|
miniwob-plusplus/docs/content/javascript_api.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Javascript API
|
| 2 |
+
|
| 3 |
+
MiniWoB++ environments incorporate a few JavaScript utilities,
|
| 4 |
+
many of which are used by the Python interface.
|
| 5 |
+
|
| 6 |
+
## `Math.seedrandom([seed])`
|
| 7 |
+
|
| 8 |
+
Sets the global random seed of the environment. The optional argument `seed` can be any object.
|
| 9 |
+
|
| 10 |
+
## `getDOMInfo()`
|
| 11 |
+
|
| 12 |
+
Returns a nested object containing information about the current DOM states.
|
| 13 |
+
The returned object corresponds to the `<body>` element. Its children can be accessed under the `children` field.
|
| 14 |
+
|
| 15 |
+
Each visible DOM element is converted into an object with the following fields:
|
| 16 |
+
|
| 17 |
+
* `tag` (string): Tag name
|
| 18 |
+
* For normal elements, this is the uppercased tag name (e.g., `"DIV"`)
|
| 19 |
+
* For `<input>` elements, the input type is appended (e.g., `"INPUT_text"`)
|
| 20 |
+
* Each non-empty text node is converted into pseudo-elements with tag `"t"`,
|
| 21 |
+
where each pseudo-element represents one line of text.
|
| 22 |
+
However, if the text node is the only child of the parent. The text pseudo-element is not created,
|
| 23 |
+
and its text is assigned to the parent element instead.
|
| 24 |
+
* `ref` (number): Reference number
|
| 25 |
+
* Within each episode, the `ref` number of the same object stays the same
|
| 26 |
+
* For the same random seed, the `ref` number of the same object should be the same
|
| 27 |
+
* `ref` for normal elements start from 1, while `ref` for text psuedo-elements counts down from -1
|
| 28 |
+
* `children` (list): Recursive list of objects corresponding to the children
|
| 29 |
+
* `left`, `top`, `width`, `height` (number): Geometry of the element
|
| 30 |
+
* `id` (string): Element's `id`
|
| 31 |
+
* `classes` (string): Element's `class`es (space-separated)
|
| 32 |
+
* `bgColor`, `fgColor` (string): Background and foreground colors
|
| 33 |
+
* `focused` (boolean): Indicates if the element is being focused on
|
| 34 |
+
* `tampered` (boolean): Indicates if the element is tampered (clicked, focused, typed, etc.)
|
| 35 |
+
* `value`: For `<input>`, this contains the input value
|
| 36 |
+
* For `checkbox` and `radio` types, this contains a boolean whether the input is selected
|
| 37 |
+
* For other input types, this contains a text value
|
| 38 |
+
* `text` (string): For child nodes and text pseudo-elements, this contains the text content
|
| 39 |
+
|
| 40 |
+
## `flattenDOMInfo(rootDomInfo)`
|
| 41 |
+
|
| 42 |
+
Can be called on the result of `getDOMInfo()` to get a flattened representation.
|
| 43 |
+
Useful for debugging in Chrome console.
|
| 44 |
+
|
| 45 |
+
## `elementClick(ref)`
|
| 46 |
+
|
| 47 |
+
Clicks on an element regardless of its location and visibility.
|
| 48 |
+
The argument `ref` is the ref value generated by the previous call to `getDOMInfo()`.
|
| 49 |
+
|
| 50 |
+
## `visualizeAttention(values)`
|
| 51 |
+
|
| 52 |
+
Visualizes the attention weights on the screen.
|
| 53 |
+
The argument `values` is a 2D array of shape 20 × 20.
|
miniwob-plusplus/docs/content/observation_space.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Observation Space
|
| 2 |
+
|
| 3 |
+
## Observation Object
|
| 4 |
+
|
| 5 |
+
In all MiniWoB++ environments, an observation is a `dict` with the following fields:
|
| 6 |
+
|
| 7 |
+
```{list-table}
|
| 8 |
+
:header-rows: 1
|
| 9 |
+
* - Key
|
| 10 |
+
- Type
|
| 11 |
+
- Description
|
| 12 |
+
* - `utterance`
|
| 13 |
+
- `str`
|
| 14 |
+
- Task instruction string.
|
| 15 |
+
* - `fields`
|
| 16 |
+
- `tuple[tuple[str, str]]`
|
| 17 |
+
- Environment-specific key-value pairs extracted from the utterance;
|
| 18 |
+
e.g., "Click on the OK button" → `(("target", "OK"),)`.
|
| 19 |
+
The fields are guaranteed to be the same during the same episode.
|
| 20 |
+
* - `screenshot`
|
| 21 |
+
- `np.ndarray` with shape `(height, width, 3)` and type `uint8`
|
| 22 |
+
- Screenshot as RGB values for each pixel.
|
| 23 |
+
* - `dom_elements`
|
| 24 |
+
- `tuple[dict]`
|
| 25 |
+
- Tuple of dicts, each listing properties of a *visible* DOM elements (see below).
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
## DOM Element Properties
|
| 29 |
+
|
| 30 |
+
Each dict in `dom_elements` has the following fields:
|
| 31 |
+
|
| 32 |
+
```{list-table}
|
| 33 |
+
:header-rows: 1
|
| 34 |
+
* - Key
|
| 35 |
+
- Type
|
| 36 |
+
- Description
|
| 37 |
+
* - `ref`
|
| 38 |
+
- `int`
|
| 39 |
+
- Non-zero integer ID.
|
| 40 |
+
* The `ref` for normal HTML elements start from 1.
|
| 41 |
+
* Each HTML element retains the same `ref` during the same episode.
|
| 42 |
+
* Non-empty text nodes are converted into pseudo-elements with `ref` counting down from -1.[^1]
|
| 43 |
+
* - `parent`
|
| 44 |
+
- `int`
|
| 45 |
+
- `ref` of the parent. For the root DOM element, `parent` will be 0.
|
| 46 |
+
* - `left`
|
| 47 |
+
- `np.ndarray` with shape `(1,)` and type `float32`
|
| 48 |
+
- Left coordinate relative to the screen (can be negative).
|
| 49 |
+
* - `top`
|
| 50 |
+
- `np.ndarray` with shape `(1,)` and type `float32`
|
| 51 |
+
- Top coordinate relative to the screen (can be negative).
|
| 52 |
+
* - `width`
|
| 53 |
+
- `np.ndarray` with shape `(1,)` and type `float32`
|
| 54 |
+
- Element width.
|
| 55 |
+
* - `height`
|
| 56 |
+
- `np.ndarray` with shape `(1,)` and type `float32`
|
| 57 |
+
- Element height.
|
| 58 |
+
* - `tag`
|
| 59 |
+
- `str`
|
| 60 |
+
- HTML tag.
|
| 61 |
+
* For normal elements, this is the lowercased tag name (e.g., `"div"`).
|
| 62 |
+
* For `<input>` elements, the input type is appended (e.g., `"input_text"`).
|
| 63 |
+
* Non-empty text nodes become pseudo-elements with tag `"t"`.[^1]
|
| 64 |
+
* - `text`
|
| 65 |
+
- `str`
|
| 66 |
+
- Text content, which is non-empty only for leaf elements.[^1]
|
| 67 |
+
* - `value`
|
| 68 |
+
- `str`
|
| 69 |
+
- HTML `value` attribute (for an `<input>` element).
|
| 70 |
+
* - `id`
|
| 71 |
+
- `str`
|
| 72 |
+
- HTML `id` attribute.
|
| 73 |
+
* - `classes`
|
| 74 |
+
- `str`
|
| 75 |
+
- HTML `class` attribute (multiple classes are separated by spaces).
|
| 76 |
+
* - `bg_color`
|
| 77 |
+
- `np.ndarray` with shape `(4,)` and type `float32`
|
| 78 |
+
- Background color as RGBA value.
|
| 79 |
+
* - `fg_color`
|
| 80 |
+
- `np.ndarray` with shape `(4,)` and type `float32`
|
| 81 |
+
- Foreground color as RGBA value.
|
| 82 |
+
* - `flags`
|
| 83 |
+
- `np.ndarray` with shape `(4,)` and type `int8`
|
| 84 |
+
- Binary flags:
|
| 85 |
+
* (`focused`) Whether the element is being focused on.
|
| 86 |
+
* (`tampered`) Whether the element has been tampered (clicked, focused, typed, etc.).
|
| 87 |
+
* (`targeted`) Whether the element is an event target (for recorded demonstrations).
|
| 88 |
+
* (`is_leaf`) Whether the element is a leaf.
|
| 89 |
+
```
|
| 90 |
+
|
| 91 |
+
[^1]: **Note:** Regarding text nodes:
|
| 92 |
+
* For an element with a single text node as its child (e.g., `<button>Submit</button>`),
|
| 93 |
+
a text pseudo-element will not be created. The element will become a leaf with the
|
| 94 |
+
`text` feature filled in.
|
| 95 |
+
* For an element with a text node as one of its children (e.g., `<button>Submit <b>NOW</b></button>`),
|
| 96 |
+
a text pseudo-element (negative `ref` and `tag = "t"`) will be created for each line of text
|
| 97 |
+
in the text node.
|
| 98 |
+
|
miniwob-plusplus/docs/content/reward.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Reward
|
| 2 |
+
|
| 3 |
+
In all environments, the reward is 0 during the episode, and a value in the range -1 to 1 (inclusive)
|
| 4 |
+
when the episode terminates.
|
| 5 |
+
|
| 6 |
+
## Reward processor
|
| 7 |
+
|
| 8 |
+
Originally, any positive reward is scaled by the remaining time on the timer.
|
| 9 |
+
Some environments also give partial rewards for partially correct answers
|
| 10 |
+
(see the documentation or docstring of each environment for details).
|
| 11 |
+
|
| 12 |
+
A **reward processor** can be used to returns custom rewards that ignore
|
| 13 |
+
the time penalty or partial rewards. A reward processor can be specified during
|
| 14 |
+
environment initialization:
|
| 15 |
+
|
| 16 |
+
```python
|
| 17 |
+
import gymnasium
|
| 18 |
+
from miniwob.reward import get_binary_reward
|
| 19 |
+
|
| 20 |
+
env = gymnasium.make('miniwob/ascending-numbers-v1', reward_processor=get_binary_reward)
|
| 21 |
+
```
|
| 22 |
+
|
| 23 |
+
The available reward processors include:
|
| 24 |
+
|
| 25 |
+
* `get_original_reward`: Returns the original reward. This is the default.
|
| 26 |
+
* `get_raw_reward`: Returns the raw reward without time penalty.
|
| 27 |
+
* `get_binary_reward`: Returns the binary reward without time penalty or partial reward. The terminal reward will be either -1 or 1. This is used in most previous publications.
|
| 28 |
+
* `get_thresholded_reward`: Returns the binary reward without time penalty or partial reward, but with any partial reward ≥ the specified threshold being treated as 1. This is needed for tasks that give continuous-valued partial rewards depending on how close the answer is to the correct answer. To specify this method as the reward processor, use `lambda metadata: get_thresholded_reward(metadata, threshold=VALUE)` or `functools.partial(get_thresholded_reward, threshold=VALUE)`.
|
miniwob-plusplus/docs/content/viewing.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Viewing the Environments
|
| 2 |
+
|
| 3 |
+
There are 2 ways to view the environments:
|
| 4 |
+
|
| 5 |
+
* **Run a simple server:**
|
| 6 |
+
|
| 7 |
+
* **Node.js:** Install and run `http-server` using
|
| 8 |
+
```
|
| 9 |
+
npm install http-server -g # Requires Node.js
|
| 10 |
+
cd miniwob/html/
|
| 11 |
+
http-server
|
| 12 |
+
```
|
| 13 |
+
The tasks should now be accessible at `http://localhost:8080/miniwob/`.
|
| 14 |
+
|
| 15 |
+
* **Python:**
|
| 16 |
+
```
|
| 17 |
+
cd miniwob/html/
|
| 18 |
+
python -m http.server 8080
|
| 19 |
+
```
|
| 20 |
+
We found this method to be less stable with a large amount of access,
|
| 21 |
+
which is required by reinforcement learning.
|
| 22 |
+
|
| 23 |
+
* **Use the `file://` protocol:** open `miniwob/html/miniwob/` in the browser.
|
| 24 |
+
* The URL should now be something like
|
| 25 |
+
|
| 26 |
+
file:///path/to/miniwob/html/miniwob/
|
| 27 |
+
|
| 28 |
+
* This should show the directory listing of all task HTML files.
|
| 29 |
+
|
miniwob-plusplus/docs/environments/.gitkeep
ADDED
|
File without changes
|
miniwob-plusplus/docs/index.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
hide-toc: true
|
| 3 |
+
firstpage:
|
| 4 |
+
lastpage:
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
```{project-logo} _static/img/miniwobplusplus-text.png
|
| 9 |
+
:alt: MiniWoB logo
|
| 10 |
+
```
|
| 11 |
+
|
| 12 |
+
```{image} _static/img/showcase.gif
|
| 13 |
+
:width: 100%
|
| 14 |
+
:align: center
|
| 15 |
+
```
|
| 16 |
+
|
| 17 |
+
The MiniWoB++ library contains a collection of over 100 **web interaction environments**,
|
| 18 |
+
along with JavaScript and Python interfaces for programmatically interacting with them.
|
| 19 |
+
The Python interface follows the [Gymnasium](https://gymnasium.farama.org/) API
|
| 20 |
+
and uses [Selenium WebDriver](https://www.selenium.dev/documentation/webdriver/)
|
| 21 |
+
to perform actions on the web browser.
|
| 22 |
+
|
| 23 |
+
MiniWoB++ is an extension of the
|
| 24 |
+
[OpenAI MiniWoB benchmark](http://proceedings.mlr.press/v70/shi17a/shi17a.pdf),
|
| 25 |
+
and was introduced in the paper
|
| 26 |
+
[Reinforcement Learning on Web Interfaces using Workflow-Guided
|
| 27 |
+
Exploration](https://arxiv.org/abs/1802.08802).
|
| 28 |
+
|
| 29 |
+
The Gymnasium interface allows an agent to initialize and interact with a MiniWoB++ environment as follows:
|
| 30 |
+
```python
|
| 31 |
+
import gymnasium
|
| 32 |
+
import miniwob
|
| 33 |
+
gymnasium.register_envs(miniwob)
|
| 34 |
+
env = gymnasium.make('miniwob/click-test-2-v1', render_mode='human')
|
| 35 |
+
try:
|
| 36 |
+
observation, info = env.reset(seed=42)
|
| 37 |
+
for _ in range(1000):
|
| 38 |
+
action = policy(observation) # User-defined policy function
|
| 39 |
+
observation, reward, terminated, truncated, info = env.step(action)
|
| 40 |
+
if terminated:
|
| 41 |
+
observation, info = env.reset()
|
| 42 |
+
finally:
|
| 43 |
+
env.close()
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
```{toctree}
|
| 47 |
+
:hidden:
|
| 48 |
+
:caption: Introduction
|
| 49 |
+
|
| 50 |
+
content/getting_started
|
| 51 |
+
content/basic_usage
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
```{toctree}
|
| 55 |
+
:hidden:
|
| 56 |
+
:caption: API
|
| 57 |
+
|
| 58 |
+
content/observation_space
|
| 59 |
+
content/action_space
|
| 60 |
+
content/reward
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
```{toctree}
|
| 64 |
+
:hidden:
|
| 65 |
+
:caption: Environments
|
| 66 |
+
|
| 67 |
+
content/viewing
|
| 68 |
+
environments/list
|
| 69 |
+
content/custom_environment
|
| 70 |
+
content/javascript_api
|
| 71 |
+
content/demonstrations
|
| 72 |
+
```
|
| 73 |
+
|
| 74 |
+
```{toctree}
|
| 75 |
+
:hidden:
|
| 76 |
+
:caption: Development
|
| 77 |
+
|
| 78 |
+
Github <https://github.com/Farama-Foundation/miniwob-plusplus>
|
| 79 |
+
Contribute to the Docs <https://github.com/Farama-Foundation/miniwob-plusplus/blob/master/docs/README.md>
|
| 80 |
+
```
|
miniwob-plusplus/docs/requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
sphinx
|
| 2 |
+
myst-parser
|
| 3 |
+
git+https://github.com/Farama-Foundation/Celshast#egg=furo
|
| 4 |
+
pandas
|
| 5 |
+
tabulate
|