orbital-thruster-env / validate.py
pixxel-phantom's picture
Upload folder using huggingface_hub
ef87bef verified
import sys
from pathlib import Path
from typing import Any
import requests
import yaml
ROOT = Path(__file__).resolve().parent
class CheckRunner:
def __init__(self) -> None:
self.passed = 0
self.total = 0
def record(self, condition: bool, label: str) -> None:
self.total += 1
marker = "PASS" if condition else "FAIL"
print(f"{marker} {label}")
if condition:
self.passed += 1
def load_manifest() -> dict[str, Any]:
manifest_path = ROOT / "openenv.yaml"
if not manifest_path.exists():
return {}
try:
with manifest_path.open("r", encoding="utf-8") as handle:
data = yaml.safe_load(handle) or {}
return data if isinstance(data, dict) else {}
except Exception:
return {}
def safe_get(url: str) -> tuple[bool, dict[str, Any] | list[Any] | str]:
try:
response = requests.get(url, timeout=20)
response.raise_for_status()
try:
return True, response.json()
except Exception:
return True, response.text
except Exception as exc:
return False, str(exc)
def safe_post(url: str, payload: dict[str, Any]) -> tuple[bool, dict[str, Any] | str]:
try:
response = requests.post(url, json=payload, timeout=20)
response.raise_for_status()
return True, response.json()
except Exception as exc:
return False, str(exc)
def main() -> int:
env_url = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:7860"
env_url = env_url.rstrip("/")
runner = CheckRunner()
manifest = load_manifest()
required_files = [
"openenv.yaml",
"Dockerfile",
"server/requirements.txt",
"inference.py",
"training/qwen3_smoke_sft.py",
"training/qwen3_grpo_train.py",
"training/evaluate_baselines.py",
"pyproject.toml",
"models.py",
"client.py",
"server/app.py",
"server/orbital_thruster_environment.py",
]
for file_name in required_files:
runner.record((ROOT / file_name).exists(), f"{file_name} exists")
runner.record(bool(manifest.get("name")), "openenv.yaml has name")
runner.record(bool(manifest.get("version")), "openenv.yaml has version")
runner.record(isinstance(manifest.get("tasks"), list) and len(manifest["tasks"]) >= 4, "openenv.yaml has at least 4 tasks")
runner.record(manifest.get("reward_range") == [-1.0, 1.0], "reward_range is [-1.0, 1.0]")
runner.record(all(isinstance(task.get("id"), str) and task.get("id") for task in manifest.get("tasks", [])), "all task IDs are non-empty")
ok, health_body = safe_get(f"{env_url}/health")
runner.record(ok and isinstance(health_body, dict) and health_body.get("status") == "healthy", "GET /health returns healthy")
ok, root_body = safe_get(f"{env_url}/")
runner.record(ok and isinstance(root_body, dict) and root_body.get("name") == "orbital-thruster-env", "GET / returns environment metadata")
ok, tasks_body = safe_get(f"{env_url}/tasks")
runner.record(ok and isinstance(tasks_body, list) and len(tasks_body) >= 4, "GET /tasks returns at least 4 tasks")
task_ids = [task["id"] for task in manifest.get("tasks", []) if isinstance(task, dict) and "id" in task]
probe_action = {"action_type": "idle", "control_mode": "safe_hold", "reason": "validation probe"}
for task_id in task_ids:
ok, reset_body = safe_post(f"{env_url}/reset", {"task_id": task_id})
reset_obs = reset_body.get("observation", {}) if ok and isinstance(reset_body, dict) else {}
runner.record(ok and isinstance(reset_obs, dict) and reset_obs.get("task_id") == task_id, f"POST /reset works for {task_id}")
runner.record(
all(
key in reset_obs
for key in (
"difficulty",
"step_budget",
"target_attitude_deg",
"mission_brief",
"active_directive",
"reward_breakdown",
)
),
f"reset observation shape is valid for {task_id}",
)
ok, step_body = safe_post(f"{env_url}/step", {"action": probe_action})
step_obs = step_body.get("observation", {}) if ok and isinstance(step_body, dict) else {}
reward = step_body.get("reward") if ok and isinstance(step_body, dict) else None
done = step_body.get("done") if ok and isinstance(step_body, dict) else None
runner.record(ok and isinstance(step_obs, dict) and isinstance(done, bool), f"POST /step works for {task_id}")
runner.record(isinstance(reward, (int, float)) and -1.0 <= float(reward) <= 1.0, f"step reward is bounded for {task_id}")
runner.record(
isinstance(step_obs.get("reward_breakdown"), dict) and "physical_tracking_reward" in step_obs.get("reward_breakdown", {}),
f"step reward rubric is exposed for {task_id}",
)
ok, state_body = safe_get(f"{env_url}/state")
runner.record(
ok and isinstance(state_body, dict) and bool(state_body.get("episode_id")) and isinstance(state_body.get("reward_columns"), dict),
f"GET /state returns episode for {task_id}",
)
print(f"{runner.passed} / {runner.total} checks passed")
return 0 if runner.passed == runner.total else 1
if __name__ == "__main__":
raise SystemExit(main())