from typing import Optional
from fastapi import FastAPI, HTTPException, Body
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from environment.env import CodeSentinelEnv
from environment.models import (
Action, TaskId, StepResponse, ResetResponse,
EnvironmentState, ValidateResponse, Observation
)
app = FastAPI(
title = "CodeSentinel OpenEnv",
description = "AI environment for automated code review agents",
version = "1.0.0",
)
env = CodeSentinelEnv()
class ResetRequest(BaseModel):
task_id: TaskId = TaskId.bug_detection
seed: int = 42
@app.get("/", response_class=HTMLResponse, include_in_schema=False)
def root():
return """
CodeSentinel — AI Code Review Environment
🛡️ CodeSentinel
A real-world OpenEnv environment where AI agents learn to review code like a senior engineer.
Tasks
| Task | Difficulty | Max Steps |
| bug_detection | Easy | 20 |
| security_audit | Medium | 30 |
| architecture_review | Hard | 50 |
API
- GET /validate — Health check
- GET /docs — Swagger UI
- POST /reset — Start episode
- POST /step — Submit action
- GET /state — Inspect state
"""
@app.get("/validate", response_model=ValidateResponse)
def validate():
return ValidateResponse(
valid = True,
version = "1.0.0",
tasks = ["bug_detection", "security_audit", "architecture_review"],
message = "CodeSentinel is healthy and ready.",
)
@app.post("/reset", response_model=Observation)
def reset(req: Optional[ResetRequest] = Body(None)):
if req is None:
req = ResetRequest()
try:
resp = env.reset(task_id=req.task_id, seed=req.seed)
return resp.observation
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/step", response_model=StepResponse)
def step(action: Action):
try:
return env.step(action)
except RuntimeError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
import traceback
traceback.print_exc()
raise HTTPException(status_code=500, detail=str(e))
@app.get("/state", response_model=EnvironmentState)
def state():
try:
return env.state()
except RuntimeError as e:
raise HTTPException(status_code=400, detail=str(e))
def main():
import uvicorn
uvicorn.run("server.app:app", host="0.0.0.0", port=7860)
if __name__ == "__main__":
main()