"""FastAPI application for the Engineer Manager OpenEnv server.""" from __future__ import annotations from textwrap import dedent import uvicorn from fastapi.responses import HTMLResponse, JSONResponse, PlainTextResponse, RedirectResponse, Response from openenv.core.env_server.http_server import create_fastapi_app from pydantic import BaseModel from graders import grade_task_0, grade_task_1, grade_task_2 from tasks import TASKS try: from ..models import EngineerManagerAction, EngineerManagerObservation from .engineer_manager_environment import EngineerManagerEnvironment except ImportError: import sys from pathlib import Path repo_root = Path(__file__).resolve().parents[1] if str(repo_root) not in sys.path: sys.path.insert(0, str(repo_root)) from models import EngineerManagerAction, EngineerManagerObservation from server.engineer_manager_environment import EngineerManagerEnvironment app = create_fastapi_app( EngineerManagerEnvironment, EngineerManagerAction, EngineerManagerObservation, max_concurrent_envs=2, ) class GraderRequest(BaseModel): task_id: str state: dict reward: float WEB_CSS = dedent( """\ :root { color-scheme: dark; --bg: #07111f; --panel: rgba(10, 21, 38, 0.88); --panel-2: rgba(14, 28, 48, 0.96); --line: rgba(124, 231, 255, 0.18); --text: #eaf4ff; --muted: #99abc7; --accent: #7ce7ff; --accent-2: #86f0ca; --meeting: #f5c76a; --empty: rgba(255, 255, 255, 0.06); --danger: #ff8d8d; --shell-max: 1180px; --sidebar-width: 300px; --content-min: 620px; } * { box-sizing: border-box; } html { min-height: 100%; background: #07111f; } body { margin: 0; min-height: 100%; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color: var(--text); background: radial-gradient(circle at top, rgba(124, 231, 255, 0.12), transparent 30rem), linear-gradient(180deg, #09111d 0%, #07111f 100%); } .shell { width: min(100%, var(--shell-max)); margin: 0 auto; padding: 32px 20px 40px; } .hero { padding: 24px; border: 1px solid var(--line); border-radius: 24px; background: linear-gradient(135deg, rgba(9, 20, 38, 0.95), rgba(12, 31, 54, 0.92)); box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28); } .eyebrow { color: var(--accent); font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; margin-bottom: 10px; } h1 { margin: 0 0 10px; font-size: clamp(2rem, 5vw, 3.8rem); line-height: 0.95; } .sub { margin: 0; color: var(--muted); max-width: 62ch; line-height: 1.5; } .grid { display: grid; grid-template-columns: minmax(260px, var(--sidebar-width)) minmax(var(--content-min), 1fr); align-items: start; gap: 18px; margin-top: 18px; } .panel { border: 1px solid var(--line); border-radius: 22px; background: var(--panel); box-shadow: 0 12px 36px rgba(0, 0, 0, 0.22); backdrop-filter: blur(10px); } .panel-inner { padding: 18px; } .section-title { margin: 0 0 14px; font-size: 0.92rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent); } .metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 16px; } .metric { padding: 14px; border-radius: 18px; border: 1px solid var(--line); background: var(--panel-2); } .metric small { display: block; color: var(--muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.7rem; } .metric strong { font-size: 1.35rem; } label { display: block; margin-bottom: 10px; color: var(--muted); font-size: 0.92rem; } input, select, button { width: 100%; border-radius: 14px; border: 1px solid var(--line); background: rgba(255, 255, 255, 0.04); color: var(--text); padding: 12px 14px; font: inherit; } button { cursor: pointer; transition: transform 120ms ease, background 120ms ease; background: linear-gradient(135deg, rgba(124, 231, 255, 0.22), rgba(134, 240, 202, 0.16)); } button:hover { transform: translateY(-1px); } .actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 12px; } .actions button[data-op="0"] { grid-column: span 2; } .timeline { display: grid; grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); gap: 8px; } .slot { border-radius: 16px; min-height: 84px; padding: 10px 8px; border: 1px solid transparent; background: var(--empty); display: flex; flex-direction: column; justify-content: space-between; } .slot.current { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(124, 231, 255, 0.25) inset; } .slot.work { background: linear-gradient(180deg, rgba(124, 240, 202, 0.22), rgba(124, 240, 202, 0.10)); } .slot.meeting { background: linear-gradient(180deg, rgba(245, 199, 106, 0.28), rgba(245, 199, 106, 0.10)); } .slot small { color: var(--muted); } .slot strong { font-size: 0.82rem; } .task-list, pre { margin: 0; padding: 14px; border-radius: 18px; border: 1px solid var(--line); background: rgba(255, 255, 255, 0.03); } .task-list li { margin: 0 0 8px; color: var(--muted); } .task-list li:last-child { margin-bottom: 0; } pre { overflow: auto; max-height: 260px; color: #d7e6ff; } .details-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin-top: 16px; } .status { margin-top: 12px; min-height: 24px; color: var(--muted); } .status.error { color: var(--danger); } @media (max-width: 1040px) { :root { --content-min: 0px; } .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (max-width: 760px) { .grid, .metrics, .details-grid { grid-template-columns: 1fr; } .actions { grid-template-columns: 1fr; } .actions button[data-op="0"] { grid-column: span 1; } } """ ) WEB_JS = dedent( """\ const statusEl = document.getElementById("status"); const targetSlotEl = document.getElementById("targetSlot"); const timelineEl = document.getElementById("timeline"); const tasksEl = document.getElementById("tasks"); const payloadEl = document.getElementById("payload"); const metrics = { time: document.getElementById("m-time"), slot: document.getElementById("m-slot"), flow: document.getElementById("m-flow"), debt: document.getElementById("m-debt"), }; function setStatus(message, isError = false) { statusEl.textContent = message; statusEl.className = isError ? "status error" : "status"; } function kindLabel(value) { if (value === 1) return "Deep Work"; if (value === 2) return "Meeting"; return "Open"; } function renderObservation(response) { const obs = response.observation || {}; metrics.time.textContent = obs.current_time ?? "-"; metrics.slot.textContent = String(obs.current_slot ?? "-"); metrics.flow.textContent = Number(obs.flow_score ?? 0).toFixed(2); metrics.debt.textContent = Number(obs.social_debt ?? 0).toFixed(2); targetSlotEl.max = Math.max(0, (obs.timeline || []).length - 1); timelineEl.innerHTML = ""; (obs.timeline || []).forEach((value, index) => { const slot = document.createElement("div"); slot.className = "slot " + (value === 1 ? "work" : value === 2 ? "meeting" : ""); if (index === obs.current_slot) slot.classList.add("current"); slot.innerHTML = "Slot " + index + "" + kindLabel(value) + ""; timelineEl.appendChild(slot); }); tasksEl.innerHTML = ""; const tasks = obs.task_buffer || []; if (!tasks.length) { const empty = document.createElement("li"); empty.textContent = "No queued tasks."; tasksEl.appendChild(empty); } else { tasks.forEach((task, index) => { const item = document.createElement("li"); item.textContent = "Task " + (index + 1) + ": " + task.duration + " slots, complexity " + task.hidden_complexity; tasksEl.appendChild(item); }); } payloadEl.textContent = JSON.stringify(response, null, 2); } async function callJson(url, body) { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); const data = await response.json(); if (!response.ok) throw new Error(JSON.stringify(data)); return data; } async function resetEnv() { setStatus("Resetting environment..."); try { const data = await callJson("/reset", {}); renderObservation(data); setStatus("Environment reset."); } catch (error) { setStatus("Reset failed: " + error.message, true); } } async function stepEnv(operation) { setStatus("Applying action..."); try { const payload = { action: { target_slot: Number(targetSlotEl.value || 0), operation: Number(operation), }, }; const data = await callJson("/step", payload); renderObservation(data); setStatus("Action applied."); } catch (error) { setStatus("Action failed: " + error.message, true); } } document.getElementById("resetBtn").addEventListener("click", resetEnv); document.querySelectorAll("[data-op]").forEach((button) => { button.addEventListener("click", () => stepEnv(button.dataset.op)); }); resetEnv(); """ ) WEB_PAGE = dedent( """\ Engineer Manager
Engineer Manager Simulator

Run the day before the day runs you.

This is a direct native UI for the Space. It talks to the environment API without the Gradio bridge, so it avoids the Hugging Face wrapper errors that were breaking the previous page.

Current Time-
Current Slot-
Flow Score-
Social Debt-

Timeline

Task Buffer

    Last Response

    {}
    """ ) @app.get("/", include_in_schema=False) def root() -> RedirectResponse: return RedirectResponse(url="/web/") @app.get("/web", include_in_schema=False) def web_root() -> RedirectResponse: return RedirectResponse(url="/web/") @app.get("/web/", include_in_schema=False) def web_ui() -> HTMLResponse: return HTMLResponse(WEB_PAGE) @app.get("/assets/app.css", include_in_schema=False) def web_css() -> PlainTextResponse: return PlainTextResponse(WEB_CSS, media_type="text/css") @app.get("/assets/app.js", include_in_schema=False) def web_js() -> PlainTextResponse: return PlainTextResponse(WEB_JS, media_type="application/javascript") @app.get("/favicon.ico", include_in_schema=False) def favicon() -> Response: return Response(status_code=204) @app.get("/manifest.json", include_in_schema=False) def manifest() -> JSONResponse: return JSONResponse( { "name": "Engineer Manager", "short_name": "Engineer Manager", "start_url": "/web/", "display": "standalone", "background_color": "#0b1224", "theme_color": "#0b1224", "icons": [], } ) @app.get("/tasks", include_in_schema=False) def tasks() -> list[dict]: return TASKS @app.post("/grader", include_in_schema=False) def grader(request: GraderRequest) -> JSONResponse: task_index_map = { "quiet-morning": 0, "engineer_manager_task_0": 0, "meeting-surgery": 1, "engineer_manager_task_1": 1, "delivery-triage": 2, "engineer_manager_task_2": 2, } grader_fn_map = { "quiet-morning": grade_task_0, "meeting-surgery": grade_task_1, "delivery-triage": grade_task_2, "engineer_manager_task_0": grade_task_0, "engineer_manager_task_1": grade_task_1, "engineer_manager_task_2": grade_task_2, } grader_fn = grader_fn_map.get(request.task_id) if grader_fn is None: return JSONResponse( {"error": f"Unknown task_id: {request.task_id}", "score": 0.0, "passed": False}, status_code=400, ) state = dict(request.state) if "task_id" not in state or state["task_id"] is None: state["task_id"] = task_index_map[request.task_id] score = float(grader_fn(state, request.reward)) return JSONResponse({"task_id": request.task_id, "score": score, "passed": score >= 0.0, "reward": score}) def run(host: str = "0.0.0.0", port: int = 8000) -> None: """Run the OpenEnv HTTP server.""" uvicorn.run(app, host=host, port=port) def main() -> None: """CLI entrypoint expected by the OpenEnv validator.""" import argparse parser = argparse.ArgumentParser() parser.add_argument("--host", default="0.0.0.0") parser.add_argument("--port", type=int, default=8000) args = parser.parse_args() run(host=args.host, port=args.port) if __name__ == "__main__": main()