diff --git a/pyproject.toml b/pyproject.toml index c8a6b634f..8f838d2cd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "mettagrid==0.26.17", + "mettagrid==0.26.19", "softmax-cli==0.26.7", "packaging>=24.0.0", "pydantic>=2.11.5", @@ -89,8 +89,8 @@ testpaths = ["tests"] source = ["cogames"] [tool.uv.sources] -mettagrid = { workspace = true } -softmax-cli = { workspace = true } +mettagrid = {git = "https://github.com/Metta-AI/mettagrid.git"} +softmax-cli = {git = "https://github.com/Metta-AI/softmax-cli.git"} diplomacog = { git = "https://github.com/Metta-AI/cogame-diplomacog.git" } hungercog = { git = "https://github.com/Metta-AI/cogame-hungercog.git" } overcogged = { git = "https://github.com/Metta-AI/cogame-overcogged.git" } diff --git a/src/cogames/cli/submit.py b/src/cogames/cli/submit.py index 67d5ae0ee..e1aa17b44 100644 --- a/src/cogames/cli/submit.py +++ b/src/cogames/cli/submit.py @@ -67,6 +67,33 @@ def observatory_home_url(*, login_server_url: str) -> str: ) +def observatory_policy_url(*, login_server_url: str, policy_name: str, season_name: str) -> str: + """Build a URL to the policy's profile page in Observatory.""" + parsed = urlsplit(login_server_url) + hostname = (parsed.hostname or "").removeprefix("api.") + if parsed.port is None: + netloc = hostname + else: + netloc = f"{hostname}:{parsed.port}" if hostname else str(parsed.port) + + browser_path = parsed.path.rstrip("/") + if "/api/" in browser_path: + browser_path = browser_path.split("/api/", 1)[0] + else: + browser_path = browser_path.removesuffix("/api") + + fragment = f"tab=policies&season={season_name}&policy={policy_name}" + return urlunsplit( + ( + parsed.scheme, + netloc, + f"{browser_path}/observatory/v2", + "", + fragment, + ) + ) + + def _resolve_path_within_cwd(path_str: str, cwd: Path) -> Path: """Resolve a path and return it relative to CWD. Raises if path escapes CWD.""" raw_path = Path(path_str).expanduser() diff --git a/src/cogames/main.py b/src/cogames/main.py index a3ec3f56b..5a8622fda 100644 --- a/src/cogames/main.py +++ b/src/cogames/main.py @@ -67,6 +67,7 @@ create_bundle, ensure_docker_daemon_access, observatory_home_url, + observatory_policy_url, upload_policy, validate_bundle_docker, ) @@ -171,13 +172,17 @@ def _print_async_submission_follow_up( season_name: str, login_server_url: str, ) -> None: - observatory_url = observatory_home_url(login_server_url=login_server_url) + policy_url = observatory_policy_url( + login_server_url=login_server_url, + policy_name=policy_name, + season_name=season_name, + ) browser_skip_reason = _submit_browser_launch_skip_reason() if browser_skip_reason is None: - webbrowser.open(observatory_url) + webbrowser.open(policy_url) else: console.print(f"[dim]Browser launch skipped: {browser_skip_reason}[/dim]") - console.print(f"[dim]Observatory:[/dim] {observatory_url}") + console.print(f"[dim]Policy page:[/dim] {policy_url}") console.print("[dim]Evaluation runs asynchronously. Check status with:[/dim]") console.print(f"[dim] cogames submissions --season {season_name} --policy {policy_name}[/dim]") console.print(f"[dim] cogames leaderboard {season_name} --policy {policy_name}[/dim]") @@ -1953,13 +1958,17 @@ def submit_cmd( console.print(f"\n[bold green]Submitted to season '{season_name}'[/bold green]") if result.pools: console.print(f"[dim]Added to pools: {', '.join(result.pools)}[/dim]") - observatory_url = observatory_home_url(login_server_url=login_server) + policy_url = observatory_policy_url( + login_server_url=login_server, + policy_name=name, + season_name=season_name, + ) browser_skip_reason = _submit_browser_launch_skip_reason() if browser_skip_reason is None: - webbrowser.open(observatory_url) + webbrowser.open(policy_url) else: console.print(f"[dim]Browser launch skipped: {browser_skip_reason}[/dim]") - console.print(f"[dim]Observatory:[/dim] {observatory_url}") + console.print(f"[dim]Policy page:[/dim] {policy_url}") console.print(f"[dim]CLI:[/dim] cogames leaderboard --season {season_name}")