Spaces:
Sleeping
Sleeping
Aryanshh
feat: Full OpenEnv spec compliance — /metadata, /schema, /health, /mcp endpoints + pyproject.toml fix + deterministic 0-1 graders + proper inference.py STDOUT
a95dc70 | from fastapi import FastAPI | |
| from fastapi.responses import RedirectResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from pydantic import BaseModel | |
| from typing import Optional | |
| import os | |
| from netzero_nav.env import NetZeroEnv | |
| from netzero_nav.models import Action, Observation, StepResponse | |
| app = FastAPI(title="NetZero Nav: Eco-Resilient Logistics", version="1.0.0") | |
| _env = NetZeroEnv() | |
| # Mount Static Dashboard | |
| static_path = os.path.join(os.getcwd(), "dashboard") | |
| app.mount("/dashboard", StaticFiles(directory=static_path), name="dashboard") | |
| def root(): | |
| return RedirectResponse(url="/dashboard/index.html") | |
| class ResetRequest(BaseModel): | |
| task: Optional[str] = "easy" | |
| seed: Optional[int] = 42 | |
| # --- OpenEnv Required Endpoints --- | |
| def health(): | |
| return {"status": "healthy"} | |
| def metadata(): | |
| return { | |
| "name": "netzero-nav", | |
| "description": "Autonomous RL logistics agent navigating global disruptions with a Net-Zero carbon mandate.", | |
| "version": "1.0.0", | |
| "tasks": ["easy", "medium", "hard"], | |
| "tags": ["logistics", "esg", "supply-chain", "rl"] | |
| } | |
| def schema(): | |
| return { | |
| "action": { | |
| "action_type": {"type": "string", "enum": ["order_parts", "produce", "offset", "skip", "cancel"]}, | |
| "part_type": {"type": "string", "optional": True}, | |
| "quantity": {"type": "integer", "optional": True}, | |
| "mode": {"type": "string", "enum": ["sea", "air", "rail", "road"], "optional": True}, | |
| "product": {"type": "string", "optional": True}, | |
| "offset_amount": {"type": "number", "optional": True}, | |
| "shipment_id": {"type": "string", "optional": True} | |
| }, | |
| "observation": { | |
| "step": {"type": "integer"}, | |
| "inventory": {"type": "object"}, | |
| "active_shipments": {"type": "array"}, | |
| "pending_orders": {"type": "array"}, | |
| "carbon_total": {"type": "number"}, | |
| "carbon_quota": {"type": "number"}, | |
| "cash_balance": {"type": "number"}, | |
| "news": {"type": "string", "optional": True} | |
| }, | |
| "state": { | |
| "step": {"type": "integer"}, | |
| "inventory": {"type": "object"}, | |
| "carbon_total": {"type": "number"}, | |
| "cash_balance": {"type": "number"}, | |
| "orders": {"type": "array"}, | |
| "active_shipments": {"type": "array"} | |
| } | |
| } | |
| def mcp(body: dict = None): | |
| return { | |
| "jsonrpc": "2.0", | |
| "id": (body or {}).get("id"), | |
| "result": { | |
| "tools": ["reset", "step", "state", "metadata", "schema"], | |
| "env": "netzero-nav" | |
| } | |
| } | |
| # --- Core Env Endpoints --- | |
| def reset(req: ResetRequest = None): | |
| if req is None: | |
| req = ResetRequest() | |
| _env.task = req.task or "easy" | |
| return _env.reset(seed=req.seed) | |
| def step(action: Action): | |
| obs, reward, done, info = _env.step(action) | |
| return StepResponse(observation=obs, reward=reward, done=done, info=info) | |
| def trigger(): | |
| _env.sea_blocked_until = _env.step_count + 7 | |
| return {"status": "Suez Jam Triggered", "duration": 7} | |
| def state(): | |
| return { | |
| "step": _env.step_count, | |
| "inventory": _env.inventory, | |
| "carbon": _env.carbon_total, | |
| "cash": _env.cash_balance, | |
| "orders": _env.pending_orders, | |
| "active_shipments": _env.active_shipments | |
| } | |