Spaces:
Sleeping
Sleeping
| """ | |
| FastAPI application for TriageAgent environment. | |
| Endpoints: | |
| POST /reset β reset the environment | |
| POST /step β execute an action | |
| GET /state β get current environment state | |
| GET /schema β action/observation schemas | |
| WS /ws β WebSocket for persistent sessions | |
| GET / β mission control UI (index.html) | |
| GET /web β mission control UI (HF Space base_path) | |
| Usage: | |
| uvicorn server.app:app --reload --host 0.0.0.0 --port 8000 | |
| """ | |
| import os | |
| try: | |
| from openenv.core.env_server.http_server import create_fastapi_app | |
| except Exception as e: | |
| raise ImportError("openenv-core required. Run: uv sync") from e | |
| try: | |
| from ..models import TriageAction, TriageObservation | |
| from .triage_environment import TriageAgentEnvironment | |
| except ImportError: | |
| from models import TriageAction, TriageObservation | |
| from server.triage_environment import TriageAgentEnvironment | |
| app = create_fastapi_app( | |
| TriageAgentEnvironment, | |
| TriageAction, | |
| TriageObservation, | |
| max_concurrent_envs=16, | |
| ) | |
| # ββ /web prefix rewrite ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # On HuggingFace Spaces the app is served under /web, so the frontend sends API | |
| # calls to /web/health, /web/reset, /web/step, etc. This middleware rewrites | |
| # those paths to their canonical forms before routing, while leaving | |
| # GET /web (the HTML page) and /web/static/* (assets) untouched. | |
| from starlette.middleware.base import BaseHTTPMiddleware | |
| class _StripWebPrefix(BaseHTTPMiddleware): | |
| async def dispatch(self, request, call_next): | |
| path = request.scope["path"] | |
| if path.startswith("/web/") and not path.startswith("/web/static"): | |
| stripped = path[4:] # /web/health β /health | |
| request.scope["path"] = stripped | |
| request.scope["raw_path"] = stripped.encode() | |
| return await call_next(request) | |
| app.add_middleware(_StripWebPrefix) | |
| # ββ Static UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| _STATIC_DIR = os.path.join(os.path.dirname(__file__), "static") | |
| _INDEX_HTML = os.path.join(_STATIC_DIR, "index.html") | |
| if os.path.isdir(_STATIC_DIR): | |
| from fastapi.staticfiles import StaticFiles | |
| from fastapi.responses import FileResponse | |
| # Serve static assets at /static/* and /web/static/* | |
| app.mount("/static", StaticFiles(directory=_STATIC_DIR), name="static") | |
| app.mount("/web/static", StaticFiles(directory=_STATIC_DIR), name="web-static") | |
| async def root(): | |
| return FileResponse(_INDEX_HTML) | |
| async def web_root(): | |
| return FileResponse(_INDEX_HTML) | |
| def main(host: str = "0.0.0.0", port: int = 8000): | |
| import uvicorn | |
| uvicorn.run(app, host=host, port=port) | |
| if __name__ == "__main__": | |
| main() | |