AIMLxDIV commited on
Commit
2697ecb
·
unverified ·
2 Parent(s): 538f900a3865ad

Merge pull request #4 from DsThakurRawat/add-app

Browse files
Files changed (1) hide show
  1. app.py +110 -0
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+ from typing import Dict
3
+ from fastapi import FastAPI, HTTPException, WebSocket, WebSocketDisconnect
4
+ from pydantic import BaseModel
5
+
6
+ from codereview_env.models import (
7
+ TaskId, Action, ResetResult, StepResult, EpisodeResult
8
+ )
9
+ from codereview_env.env import CodeReviewEnv
10
+
11
+ app = FastAPI(title="AgentOrg CodeReview OpenEnv API")
12
+
13
+ # Simple in-memory storage for active episodes
14
+ episodes: Dict[str, CodeReviewEnv] = {}
15
+
16
+ class ResetRequest(BaseModel):
17
+ task_id: TaskId
18
+ seed: int = 42
19
+
20
+ class ResetResponse(BaseModel):
21
+ episode_id: str
22
+ result: ResetResult
23
+
24
+ # In-memory leaderboard
25
+ leaderboard: Dict[TaskId, list] = {
26
+ TaskId.BUG_DETECTION: [],
27
+ TaskId.SECURITY_AUDIT: [],
28
+ TaskId.ARCHITECTURAL_REVIEW: []
29
+ }
30
+
31
+ class SubmitScore(BaseModel):
32
+ agent_name: str
33
+ task_id: TaskId
34
+ score: float
35
+ seed: int
36
+
37
+ @app.get("/health")
38
+ def health_check():
39
+ return {"status": "ok", "version": "1.0.0", "env_ready": True}
40
+
41
+ @app.post("/reset", response_model=ResetResponse)
42
+ def reset_env(req: ResetRequest):
43
+ episode_id = str(uuid.uuid4())
44
+ env = CodeReviewEnv()
45
+ result = env.reset(req.task_id, req.seed)
46
+ episodes[episode_id] = env
47
+ return ResetResponse(episode_id=episode_id, result=result)
48
+
49
+ # WebSocket clients
50
+ clients = set()
51
+
52
+ async def broadcast_event(data: dict):
53
+ from fastapi.encoders import jsonable_encoder
54
+ import json
55
+ message = json.dumps(jsonable_encoder(data))
56
+ for client in clients:
57
+ try:
58
+ await client.send_text(message)
59
+ except Exception:
60
+ pass
61
+
62
+ @app.post("/step/{episode_id}", response_model=StepResult)
63
+ async def step_env(episode_id: str, action: Action):
64
+ if episode_id not in episodes:
65
+ raise HTTPException(status_code=404, detail="Episode not found")
66
+
67
+ env = episodes[episode_id]
68
+ try:
69
+ result = env.step(action)
70
+ await broadcast_event({"episode_id": episode_id, "result": result})
71
+ return result
72
+ except Exception as e:
73
+ raise HTTPException(status_code=400, detail=str(e))
74
+
75
+ @app.get("/result/{episode_id}", response_model=EpisodeResult)
76
+ def get_result(episode_id: str):
77
+ if episode_id not in episodes:
78
+ raise HTTPException(status_code=404, detail="Episode not found")
79
+
80
+ env = episodes[episode_id]
81
+ return env.get_final_result()
82
+
83
+ @app.get("/leaderboard")
84
+ def get_leaderboard():
85
+ return leaderboard
86
+
87
+ @app.post("/submit")
88
+ def submit_to_leaderboard(submission: SubmitScore):
89
+ entries = leaderboard.get(submission.task_id, [])
90
+ entries.append(submission.model_dump())
91
+ # Sort and keep top 5
92
+ entries.sort(key=lambda x: x["score"], reverse=True)
93
+ leaderboard[submission.task_id] = entries[:5]
94
+ return {"status": "submitted", "rank": entries.index(submission.model_dump()) + 1 if submission.model_dump() in entries else None}
95
+
96
+ @app.websocket("/ws/events")
97
+ async def websocket_endpoint(websocket: WebSocket):
98
+ await websocket.accept()
99
+ clients.add(websocket)
100
+ try:
101
+ while True:
102
+ await websocket.receive_text()
103
+ except Exception:
104
+ pass
105
+ finally:
106
+ clients.remove(websocket)
107
+
108
+ if __name__ == "__main__":
109
+ import uvicorn
110
+ uvicorn.run(app, host="0.0.0.0", port=7860)