arena: compwob fixed structurally -- legacy engine + literal URLs, canary green

Two instrument bugs found before any number shipped: composed pages need the LEGACY
MiniWoB core (modern core terminated on the first click), and validate() string-
compares page.url so the '../' base-url trick killed every episode after step one --
boring URLs are robust URLs. Canary now clicks ONE then TWO with the episode alive.
The 0/17 zero from the broken setup is void; the pair sweep restarts clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WsbS5x2rYsMDxP2kW3qqmQ
This commit is contained in:
ciregenz
2026-08-12 20:42:36 -07:00
co-authored by Claude Fable 5
parent 228d65c9e9
commit 0b336c232e
2 changed files with 11 additions and 3 deletions
+3 -1
View File
@@ -95,7 +95,9 @@ def reap_leftover_browsers() -> None:
def make_env(task: str, seed: int, max_steps: int):
patch_launch_with_cdp_port()
if "." in task:
if task.startswith("compwob."):
import compwob # noqa: F401 registers the composed tasks (legacy-engine base_url)
elif "." in task:
import browsergym.assistantbench # noqa: F401 lazy: HF datasets machinery breaks playwright
env_id = f"browsergym/{task}" if "." in task else f"browsergym/miniwob.{task}"
env = gym.make(env_id, headless=os.environ.get("OSW_ARENA_HEADED") != "1", max_episode_steps=max_steps)
+8 -2
View File
@@ -33,12 +33,18 @@ def compwob_page_names() -> list[str]:
ALL_COMPWOB_TASKS: list[type] = []
for _name in compwob_page_names():
# '../compwob/<name>' rides the miniwob base_url; the browser normalizes the parent hop.
# Plain subdomain + a base_url that matches the browser's own URL LITERALLY: validate()
# string-compares page.url to base_url+subdomain+'.html', so any '../' cleverness terminates
# every episode with 'invalid url' after its first step (measured). Boring URLs are robust URLs.
_cls = type(
f"Compwob_{_name.replace('-', '_').replace('.', '_')}",
(AbstractMiniwobTask,),
{"subdomain": f"../compwob/{_name}", "desc": f"CompWoB composed task {_name}"},
{"subdomain": _name, "desc": f"CompWoB composed task {_name}"},
)
_orig_init = _cls.__init__
def _init(self, seed, base_url=None, _o=_orig_init, **kw):
_o(self, seed=seed, base_url=os.environ.get("COMPWOB_URL", "http://localhost:8098/compwob/"), **kw)
_cls.__init__ = _init
# Stable public id: compwob.<name> (the subdomain's ../ prefix stays an URL detail).
_cls.get_task_id = classmethod(lambda cls, n=_name: f"compwob.{n}")
ALL_COMPWOB_TASKS.append(_cls)