#!/usr/bin/env python3 """ Patch OpenEnv web_interface.py to add: - Loss/perplexity chart and updateLossChart() - POST /web/run-baseline and GET /web/current-task for baseline comparison Idempotent: safe to run multiple times. """ import sys from pathlib import Path def _apply_routes_patch(text: str) -> str: """Add /web/run-baseline and /web/current-task routes.""" old_routes = ( ' @app.get("/web/state")\n' " async def web_state():\n" ' """State endpoint for web interface."""\n' " return web_manager.get_state()\n" "\n" " return app" ) new_routes = ( ' @app.get("/web/state")\n' " async def web_state():\n" ' """State endpoint for web interface."""\n' " return web_manager.get_state()\n" "\n" ' @app.get("/web/current-task")\n' " async def web_current_task():\n" ' """Current task spec for baseline comparison (if env supports it)."""\n' " get_spec = getattr(web_manager.env, \"get_current_task_spec\", None)\n" " if get_spec is None:\n" " return {}\n" " return get_spec() or {}\n" "\n" ' @app.post("/web/run-baseline")\n' " async def web_run_baseline():\n" ' """Run baseline optimizer for current task; returns loss_trajectory and steps."""\n' " run_bl = getattr(web_manager.env, \"run_baseline\", None)\n" " if run_bl is None:\n" " return {\"loss_trajectory\": [], \"steps\": [], \"error\": \"Env has no run_baseline\"}\n" " return run_bl()\n" "\n" " return app" ) if "web/run-baseline" not in text and "web/state" in text and "return web_manager.get_state()" in text: text = text.replace(old_routes, new_routes, 1) return text def main() -> None: if len(sys.argv) < 2: import openenv.core.env_server.web_interface as m path = Path(m.__file__).resolve() else: path = Path(sys.argv[1]).resolve() if not path.exists(): print(f"File not found: {path}", file=sys.stderr) sys.exit(1) text = path.read_text() # 1) Add Chart.js script in head (after title) chart_script = ' \n' old_head = "