2121import hashlib
2222import json
2323import os
24+ import re
2425from collections .abc import Sequence
2526from pathlib import Path
2627from typing import Any
6768)
6869
6970
71+ def _setup_command_texts (task : dict [str , Any ]) -> tuple [str , ...]:
72+ """Return commands that OSWorld will execute during the task setup."""
73+
74+ config = task .get ("config" )
75+ if not isinstance (config , list ):
76+ return ()
77+
78+ commands : list [str ] = []
79+ for setup_item in config :
80+ if not isinstance (setup_item , dict ):
81+ continue
82+ parameters = setup_item .get ("parameters" )
83+ if not isinstance (parameters , dict ):
84+ continue
85+ command = parameters .get ("command" )
86+ if isinstance (command , str ):
87+ commands .append (command )
88+ elif isinstance (command , list ):
89+ commands .append (" " .join (str (argument ) for argument in command ))
90+ return tuple (commands )
91+
92+
93+ def _validate_chrome_cdp_relay (task : dict [str , Any ], * , line_number : int ) -> None :
94+ """Require OSWorld's guest relay when task setup starts Chrome CDP."""
95+
96+ commands = _setup_command_texts (task )
97+ starts_chrome_cdp = any (
98+ re .search (r"--remote-debugging-port(?:=|\s+)1337(?!\d)" , command , flags = re .IGNORECASE )
99+ for command in commands
100+ )
101+ has_cdp_relay = any (
102+ re .search (r"\bsocat\b" , command , flags = re .IGNORECASE )
103+ and re .search (r"\blisten:9222(?!\d)" , command , flags = re .IGNORECASE )
104+ and re .search (r"\b(?:localhost|127\.0\.0\.1):1337(?!\d)" , command , flags = re .IGNORECASE )
105+ for command in commands
106+ )
107+ if starts_chrome_cdp and not has_cdp_relay :
108+ task_id = str (task .get ("id" ) or "<unknown>" )
109+ raise ValueError (
110+ f"OSWorld row { line_number } task { task_id !r} starts Chrome CDP on guest port 1337 "
111+ "but verifier_metadata.osworld_task.config does not launch the required guest relay. "
112+ "Add ['socat', 'tcp-listen:9222,fork', 'tcp:localhost:1337']; Gym publishes and "
113+ "forwards port 9222 but does not start this task-owned process."
114+ )
115+
116+
70117def prepare (input_jsonl : Path = DEFAULT_INPUT ) -> Path :
71118 """Validate and return an OSWorld JSONL suitable for rollout collection."""
72119
@@ -88,6 +135,7 @@ def prepare(input_jsonl: Path = DEFAULT_INPUT) -> Path:
88135 metadata = row .get ("verifier_metadata" )
89136 if not isinstance (metadata , dict ) or not isinstance (metadata .get ("osworld_task" ), dict ):
90137 raise ValueError (f"OSWorld row { line_number } must contain verifier_metadata.osworld_task" )
138+ _validate_chrome_cdp_relay (metadata ["osworld_task" ], line_number = line_number )
91139 row_count += 1
92140
93141 if row_count == 0 :
0 commit comments