akhiilll's picture
forgeenv source snapshot for training job
b0fbec3 verified
"""FastAPI server for ForgeEnv (OpenEnv-compliant).
Exposes /reset, /step, /state HTTP endpoints via OpenEnv's `create_app`.
HF Spaces sets PORT=7860 automatically.
"""
from __future__ import annotations
import os
from fastapi.responses import HTMLResponse
from openenv.core import create_app
from forgeenv.env.actions import ForgeAction
from forgeenv.env.forge_environment import ForgeEnvironment
from forgeenv.env.observations import ForgeObservation
app = create_app(
env=ForgeEnvironment,
action_cls=ForgeAction,
observation_cls=ForgeObservation,
env_name="forgeenv",
)
_LANDING_HTML = """<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ForgeEnv — OpenEnv server</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
:root { color-scheme: light dark; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
max-width: 760px; margin: 2.5rem auto; padding: 0 1.25rem;
line-height: 1.55; color: #1f2937; background: #fafafa; }
@media (prefers-color-scheme: dark) { body { color: #e5e7eb; background: #0f172a; } }
h1 { font-size: 1.65rem; margin-bottom: 0.25rem; }
.sub { color: #6b7280; margin-top: 0; }
code, pre { font-family: ui-monospace, "SF Mono", Menlo, monospace; }
pre { background: rgba(127,127,127,0.12); padding: 0.9rem; border-radius: 8px;
overflow-x: auto; }
table { border-collapse: collapse; width: 100%; margin: 0.75rem 0 1.25rem; }
td, th { text-align: left; padding: 0.5rem 0.75rem;
border-bottom: 1px solid rgba(127,127,127,0.25); }
th { font-weight: 600; }
a { color: #2563eb; text-decoration: none; } a:hover { text-decoration: underline; }
.ok { color: #16a34a; font-weight: 600; }
.muted { color: #6b7280; font-size: 0.9rem; }
.pill { display: inline-block; padding: 0.1rem 0.5rem; border-radius: 999px;
background: rgba(34,197,94,0.15); color: #16a34a; font-size: 0.85rem; }
</style>
</head>
<body>
<h1>ForgeEnv 🔧 <span class="pill">running</span></h1>
<p class="sub">OpenEnv-compliant RL environment for HuggingFace
ecosystem repair under library version drift.</p>
<p>This URL serves the environment over HTTP. It is not a UI — it's the
runtime that <strong>training notebooks connect to</strong>. Open one of
the endpoints below, or use the demo Space to try the trained Repair
Agent in a browser.</p>
<h2>Endpoints</h2>
<table>
<tr><th>Method</th><th>Path</th><th>Purpose</th></tr>
<tr><td>GET </td><td><a href="/health">/health</a></td><td>Health probe</td></tr>
<tr><td>POST</td><td><code>/reset</code></td><td>Sample task, return drift-gen observation</td></tr>
<tr><td>POST</td><td><code>/step</code></td><td>Apply <code>ForgeAction</code> (breakage or repair)</td></tr>
<tr><td>GET </td><td><a href="/state">/state</a></td><td>Current internal state</td></tr>
<tr><td>GET </td><td><a href="/metadata">/metadata</a></td><td>Env name + version + schema URLs</td></tr>
<tr><td>GET </td><td><a href="/schema">/schema</a></td><td>Action / observation JSON schemas</td></tr>
<tr><td>GET </td><td><a href="/docs">/docs</a></td><td>Interactive Swagger UI</td></tr>
</table>
<h2>Quick start (Python)</h2>
<pre><code>import asyncio
from openenv.core import GenericEnvClient
async def go():
client = GenericEnvClient(base_url="https://akhiilll-forgeenv.hf.space")
obs = await client.reset()
print(obs.observation["current_phase"], obs.observation["task_id"])
asyncio.run(go())</code></pre>
<h2>Project links</h2>
<ul>
<li>Space card &amp; README:
<a href="https://huggingface.co/spaces/akhiilll/forgeenv" target="_blank" rel="noopener noreferrer">huggingface.co/spaces/akhiilll/forgeenv</a></li>
<li>Gradio demo:
<a href="https://huggingface.co/spaces/akhiilll/forgeenv-demo" target="_blank" rel="noopener noreferrer">huggingface.co/spaces/akhiilll/forgeenv-demo</a></li>
<li>Trained model (LoRA) <span class="muted">— published after the Colab training run finishes</span>:
<a href="https://huggingface.co/akhiilll/forgeenv-repair-agent" target="_blank" rel="noopener noreferrer">huggingface.co/akhiilll/forgeenv-repair-agent</a></li>
</ul>
<p class="muted">Tip: if links don't open from inside the embedded Space frame,
right-click and choose <em>Open in new tab</em>, or open this URL directly
at <a href="https://akhiilll-forgeenv.hf.space/" target="_blank" rel="noopener noreferrer">akhiilll-forgeenv.hf.space</a>.</p>
</body>
</html>"""
def _attach_supplementary_routes(_app) -> None:
"""Add /health and a friendly GET / landing page if not present."""
existing = {
getattr(r, "path", None) for r in getattr(_app, "routes", [])
}
if "/health" not in existing:
@_app.get("/health")
def _health() -> dict:
return {"status": "ok", "env": "forgeenv"}
if "/" not in existing:
@_app.get("/", response_class=HTMLResponse, include_in_schema=False)
def _root() -> str:
return _LANDING_HTML
_attach_supplementary_routes(app)
if __name__ == "__main__":
import uvicorn
port = int(os.environ.get("PORT", "7860"))
uvicorn.run(app, host="0.0.0.0", port=port)