File size: 5,297 Bytes
7bff66e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | """
server/app.py — Step 4: Create Server
FastAPI application for the Cross-Session Continuity environment.
Uses openenv.core's create_app() factory, which wires up:
POST /reset — start a new episode
POST /step — execute an action
GET /state — current episode state
GET /health — health check
WS /ws — WebSocket session (stateful)
GET /docs — Swagger UI
Run with:
uvicorn server.app:app --host 0.0.0.0 --port 7860
"""
import sys
import os
_HERE = os.path.dirname(os.path.abspath(__file__))
_ROOT = os.path.dirname(_HERE)
if _ROOT not in sys.path:
sys.path.insert(0, _ROOT)
try:
from openenv.core.env_server.http_server import create_app
except Exception as e:
raise ImportError(
"openenv-core is required. Install with: pip install openenv-core"
) from e
try:
from models import ContinuityAction, ContinuityObservation
from server.env import CrossSessionContinuityEnv
except ImportError:
from models import ContinuityAction, ContinuityObservation # type: ignore
from server.env import CrossSessionContinuityEnv # type: ignore
from fastapi.responses import HTMLResponse
app = create_app(
CrossSessionContinuityEnv,
ContinuityAction,
ContinuityObservation,
env_name="cross-session-continuity-env",
max_concurrent_envs=1,
)
_LANDING_HTML = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Cross-Session Continuity Env</title>
<style>
body { font-family: system-ui, sans-serif; background: #0f1117; color: #e0e0e0;
display: flex; justify-content: center; padding: 60px 20px; margin: 0; }
.card { max-width: 720px; width: 100%; }
h1 { font-size: 2rem; margin-bottom: 4px; color: #fff; }
.badge { display:inline-block; background:#238636; color:#fff; border-radius:12px;
padding:2px 10px; font-size:0.8rem; margin-bottom:24px; }
p { color: #aaa; line-height: 1.6; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin: 28px 0; }
.endpoint { background: #1c1f26; border: 1px solid #30363d; border-radius: 8px;
padding: 14px 18px; }
.endpoint code { color: #58a6ff; font-size: 0.9rem; }
.endpoint small { color: #666; display:block; margin-top:4px; }
a { color: #58a6ff; text-decoration: none; }
a:hover { text-decoration: underline; }
pre { background:#161b22; padding:14px; border-radius:8px;
font-size:0.82rem; overflow:auto; color:#e0e0e0; }
.footer { margin-top: 32px; font-size: 0.8rem; color: #555;
border-top: 1px solid #21262d; padding-top: 16px; }
</style>
</head>
<body>
<div class="card">
<h1>🧠 Cross-Session Continuity Env</h1>
<span class="badge">• Running</span>
<p>An <a href="https://github.com/meta-pytorch/OpenEnv" target="_blank">OpenEnv</a>-compliant
RL environment where an LLM agent must complete a coding task across two sessions
with <strong>zero shared memory</strong>. Session 1 writes a structured handoff note;
Session 2 starts cold with only that note.</p>
<div class="grid">
<div class="endpoint"><code>GET /health</code><small>Server health check</small></div>
<div class="endpoint"><code>GET /docs</code><small>Interactive API (Swagger)</small></div>
<div class="endpoint"><code>POST /reset</code><small>Start a new episode</small></div>
<div class="endpoint"><code>POST /step</code><small>Execute an action</small></div>
<div class="endpoint"><code>WS /ws</code><small>WebSocket (stateful session)</small></div>
<div class="endpoint"><code>GET /state</code><small>Current episode state</small></div>
</div>
<p><strong>Quick start:</strong></p>
<pre>pip install openenv-core
from client import ContinuityEnvClient, ContinuityAction
with ContinuityEnvClient(
base_url="https://aswini-kumar-cross-session-continuity-env.hf.space"
) as env:
obs = env.reset(difficulty="easy", seed=42)
result = env.step(ContinuityAction(tool="run_tests"))
print(result.observation.output)</pre>
<p><strong>Tools:</strong>
<code>read_file</code>
<code>write_file</code>
<code>run_tests</code>
<code>write_handoff</code>
<code>parse_handoff</code>
<code>submit</code>
</p>
<div class="footer">
<a href="/docs">API Docs</a> |
<a href="/health">Health</a> |
<a href="https://github.com/CelestialWorthyOfHeavenAndEarth/cross-session-continuity-env" target="_blank">GitHub</a> |
<a href="https://huggingface.co/spaces/Aswini-Kumar/cross-session-continuity-env" target="_blank">HF Space</a>
</div>
</div>
</body>
</html>"""
@app.get("/", response_class=HTMLResponse, include_in_schema=False)
@app.get("/web", response_class=HTMLResponse, include_in_schema=False)
async def landing():
"""Human-readable landing page."""
return HTMLResponse(content=_LANDING_HTML)
def main(host: str = "0.0.0.0", port: int = 7860):
import uvicorn
uvicorn.run(app, host=host, port=port)
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--host", default="0.0.0.0")
parser.add_argument("--port", type=int, default=7860)
args = parser.parse_args()
main(host=args.host, port=args.port)
|