"""Hugging Face Space entrypoint for ResearchHarness.""" from __future__ import annotations import os from pathlib import Path import uvicorn from frontend.local_server import app, configure_frontend def _int_env(name: str, default: int) -> int: raw = os.getenv(name, "").strip() if not raw: return default try: return int(raw) except ValueError as exc: raise ValueError(f"{name} must be an integer, got {raw!r}") from exc def _bool_env(name: str, default: bool) -> bool: raw = os.getenv(name, "").strip().lower() if not raw: return default if raw in {"1", "true", "yes", "on"}: return True if raw in {"0", "false", "no", "off"}: return False raise ValueError(f"{name} must be a boolean, got {raw!r}") def configure_space() -> None: runs_dir = Path(os.getenv("RH_SPACE_RUNS_DIR", "/tmp/researchharness_space/runs")).expanduser() configure_frontend( managed_runs_dir=str(runs_dir), cleanup_retention_seconds=_int_env("RH_SPACE_RETENTION_SECONDS", 6 * 60 * 60), cleanup_max_runs=_int_env("RH_SPACE_MAX_RUNS", 40), cleanup_interval_seconds=_int_env("RH_SPACE_CLEANUP_INTERVAL_SECONDS", 15 * 60), collection_enabled=_bool_env("RH_COLLECTION_ENABLED", True), collection_dataset_repo=os.getenv("RH_COLLECTION_DATASET_REPO", "InternScience/ResearchHarness-Data"), collection_batch_size=_int_env("RH_COLLECTION_BATCH_SIZE", 5), collection_max_bundle_bytes=_int_env("RH_COLLECTION_MAX_BUNDLE_BYTES", 20 * 1024 * 1024), ) configure_space() def main() -> int: host = os.getenv("HOST", "0.0.0.0") port = _int_env("PORT", 7860) uvicorn.run(app, host=host, port=port, reload=False) return 0 if __name__ == "__main__": raise SystemExit(main())