Mayank2027 commited on
Commit
dc55f3b
·
verified ·
1 Parent(s): 155186b

Update backend/main.py

Browse files
Files changed (1) hide show
  1. backend/main.py +64 -25
backend/main.py CHANGED
@@ -33,7 +33,7 @@ async def startup_index():
33
 
34
  @asynccontextmanager
35
  async def lifespan(app: FastAPI):
36
- await refresh_model_cache() # fetch all models on startup
37
  await startup_index()
38
  yield
39
 
@@ -44,7 +44,7 @@ agents = {}
44
  STATIC_DIR = "static"
45
 
46
  class ChatRequest(BaseModel):
47
- model: str = "groq-llama-3.1-8b-instant"
48
  messages: List[Dict[str, str]]
49
  context_files: Optional[List[str]] = None
50
  project_path: str = "/app/sandbox"
@@ -75,7 +75,11 @@ class ReviewRequest(BaseModel):
75
  pr_diff: str
76
  project_path: str
77
 
78
- # ---------- API ----------
 
 
 
 
79
  @app.get("/api/models")
80
  async def get_models():
81
  return get_available_models_sync()
@@ -113,17 +117,26 @@ async def chat(req: ChatRequest):
113
  yield "data: [DONE]\n\n"
114
  return StreamingResponse(event_stream(), media_type="text/event-stream")
115
 
 
116
  @app.post("/api/agent/run")
117
  async def run_agent(req: AgentTaskRequest, background_tasks: BackgroundTasks):
118
- agent = CodingAgent(project_path=req.project_path, model=req.model)
119
- task_id = str(uuid.uuid4())
120
- agents[task_id] = agent
121
- if req.background:
122
- background_tasks.add_task(agent.run_task, req.prompt)
123
- return {"task_id": task_id, "status": "started"}
124
- else:
125
- result = await agent.run_task(req.prompt)
126
- return {"task_id": task_id, "status": agent.status, "logs": agent.logs, "pending_changes": result["pending_changes"]}
 
 
 
 
 
 
 
 
127
 
128
  @app.post("/api/agent/approve/{task_id}")
129
  async def approve_agent_changes(task_id: str):
@@ -132,20 +145,28 @@ async def approve_agent_changes(task_id: str):
132
  raise HTTPException(404, "Agent not found")
133
  if agent.status != "awaiting_approval":
134
  raise HTTPException(400, "Agent not awaiting approval")
135
- await agent.approve_and_apply()
136
- return {"status": agent.status, "logs": agent.logs}
 
 
 
137
 
138
  @app.get("/api/agent/task/{task_id}")
139
  async def get_agent_status(task_id: str):
140
  agent = agents.get(task_id)
141
  if not agent:
142
  raise HTTPException(404, "Task not found")
143
- return {"status": agent.status, "logs": agent.logs, "pending_changes": agent.pending_changes}
 
 
 
 
144
 
145
  @app.get("/api/agent/tasks")
146
  async def list_agent_tasks():
147
  return {"tasks": list(agents.keys())}
148
 
 
149
  @app.post("/api/autocomplete")
150
  async def autocomplete(req: AutocompleteRequest):
151
  suggestions = await generate_autocomplete(req)
@@ -164,8 +185,10 @@ async def search_codebase(query: str, project_path: str = "/app/sandbox", top_k:
164
  if project_path not in indexers:
165
  CBI = get_codebase_index()
166
  idx = CBI(project_path)
167
- try: idx.build_index()
168
- except Exception as e: raise HTTPException(503, f"Indexing failed: {str(e)}")
 
 
169
  indexers[project_path] = idx
170
  idx = indexers[project_path]
171
  results = idx.search(query, top_k)
@@ -214,9 +237,15 @@ async def terminal_ws(websocket: WebSocket):
214
  cmd = await websocket.receive_text()
215
  if cmd.startswith("exec:"):
216
  command = cmd[5:]
217
- proc = await asyncio.create_subprocess_shell(command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, cwd="/app/sandbox")
 
 
 
 
 
218
  stdout, stderr = await proc.communicate()
219
- await websocket.send_text(stdout.decode() + stderr.decode())
 
220
  elif cmd == "ctrl-c" and proc:
221
  proc.terminate()
222
  except WebSocketDisconnect:
@@ -227,10 +256,16 @@ async def list_files(project_path: str = "/app/sandbox"):
227
  def build_tree(path):
228
  tree = []
229
  for item in sorted(os.listdir(path)):
230
- if item.startswith('.') or item == '__pycache__': continue
 
231
  full = os.path.join(path, item)
232
- node = {"name": item, "path": full.replace(project_path, "").lstrip("/"), "type": "folder" if os.path.isdir(full) else "file"}
233
- if os.path.isdir(full): node["children"] = build_tree(full)
 
 
 
 
 
234
  tree.append(node)
235
  return tree
236
  try:
@@ -253,13 +288,17 @@ async def upload_file(file: UploadFile, project_path: str = "/app/sandbox"):
253
  dest.write_bytes(content)
254
  return {"filename": file.filename, "size": len(content)}
255
 
 
256
  @app.get("/{full_path:path}")
257
  async def serve_frontend(full_path: str):
258
- if full_path.startswith("api"): raise HTTPException(404)
 
259
  file_path = os.path.join(STATIC_DIR, full_path)
260
- if os.path.isfile(file_path): return FileResponse(file_path)
 
261
  index_path = os.path.join(STATIC_DIR, "index.html")
262
- if os.path.isfile(index_path): return FileResponse(index_path)
 
263
  raise HTTPException(404, detail="Not found")
264
 
265
  if __name__ == "__main__":
 
33
 
34
  @asynccontextmanager
35
  async def lifespan(app: FastAPI):
36
+ await refresh_model_cache()
37
  await startup_index()
38
  yield
39
 
 
44
  STATIC_DIR = "static"
45
 
46
  class ChatRequest(BaseModel):
47
+ model: str = "groq-llama-3.3-70b-versatile"
48
  messages: List[Dict[str, str]]
49
  context_files: Optional[List[str]] = None
50
  project_path: str = "/app/sandbox"
 
75
  pr_diff: str
76
  project_path: str
77
 
78
+ class ApplyRequest(BaseModel):
79
+ task_id: str
80
+ approved_indices: List[int]
81
+
82
+ # ---------- API Routes ----------
83
  @app.get("/api/models")
84
  async def get_models():
85
  return get_available_models_sync()
 
117
  yield "data: [DONE]\n\n"
118
  return StreamingResponse(event_stream(), media_type="text/event-stream")
119
 
120
+ # ---------- Agent endpoints with error handling ----------
121
  @app.post("/api/agent/run")
122
  async def run_agent(req: AgentTaskRequest, background_tasks: BackgroundTasks):
123
+ try:
124
+ agent = CodingAgent(project_path=req.project_path, model=req.model)
125
+ task_id = str(uuid.uuid4())
126
+ agents[task_id] = agent
127
+ if req.background:
128
+ background_tasks.add_task(agent.run_task, req.prompt)
129
+ return {"task_id": task_id, "status": "started"}
130
+ else:
131
+ result = await agent.run_task(req.prompt)
132
+ return {
133
+ "task_id": task_id,
134
+ "status": agent.status,
135
+ "logs": agent.logs,
136
+ "pending_changes": result["pending_changes"]
137
+ }
138
+ except Exception as e:
139
+ raise HTTPException(status_code=500, detail=str(e))
140
 
141
  @app.post("/api/agent/approve/{task_id}")
142
  async def approve_agent_changes(task_id: str):
 
145
  raise HTTPException(404, "Agent not found")
146
  if agent.status != "awaiting_approval":
147
  raise HTTPException(400, "Agent not awaiting approval")
148
+ try:
149
+ await agent.approve_and_apply()
150
+ return {"status": agent.status, "logs": agent.logs}
151
+ except Exception as e:
152
+ raise HTTPException(500, detail=str(e))
153
 
154
  @app.get("/api/agent/task/{task_id}")
155
  async def get_agent_status(task_id: str):
156
  agent = agents.get(task_id)
157
  if not agent:
158
  raise HTTPException(404, "Task not found")
159
+ return {
160
+ "status": agent.status,
161
+ "logs": agent.logs,
162
+ "pending_changes": agent.pending_changes
163
+ }
164
 
165
  @app.get("/api/agent/tasks")
166
  async def list_agent_tasks():
167
  return {"tasks": list(agents.keys())}
168
 
169
+ # ---------- Other endpoints ----------
170
  @app.post("/api/autocomplete")
171
  async def autocomplete(req: AutocompleteRequest):
172
  suggestions = await generate_autocomplete(req)
 
185
  if project_path not in indexers:
186
  CBI = get_codebase_index()
187
  idx = CBI(project_path)
188
+ try:
189
+ idx.build_index()
190
+ except Exception as e:
191
+ raise HTTPException(503, f"Indexing failed: {str(e)}")
192
  indexers[project_path] = idx
193
  idx = indexers[project_path]
194
  results = idx.search(query, top_k)
 
237
  cmd = await websocket.receive_text()
238
  if cmd.startswith("exec:"):
239
  command = cmd[5:]
240
+ proc = await asyncio.create_subprocess_shell(
241
+ command,
242
+ stdout=asyncio.subprocess.PIPE,
243
+ stderr=asyncio.subprocess.PIPE,
244
+ cwd="/app/sandbox"
245
+ )
246
  stdout, stderr = await proc.communicate()
247
+ output = stdout.decode() + stderr.decode()
248
+ await websocket.send_text(output)
249
  elif cmd == "ctrl-c" and proc:
250
  proc.terminate()
251
  except WebSocketDisconnect:
 
256
  def build_tree(path):
257
  tree = []
258
  for item in sorted(os.listdir(path)):
259
+ if item.startswith('.') or item == '__pycache__':
260
+ continue
261
  full = os.path.join(path, item)
262
+ node = {
263
+ "name": item,
264
+ "path": full.replace(project_path, "").lstrip("/"),
265
+ "type": "folder" if os.path.isdir(full) else "file"
266
+ }
267
+ if os.path.isdir(full):
268
+ node["children"] = build_tree(full)
269
  tree.append(node)
270
  return tree
271
  try:
 
288
  dest.write_bytes(content)
289
  return {"filename": file.filename, "size": len(content)}
290
 
291
+ # ---------- Serve frontend ----------
292
  @app.get("/{full_path:path}")
293
  async def serve_frontend(full_path: str):
294
+ if full_path.startswith("api"):
295
+ raise HTTPException(404)
296
  file_path = os.path.join(STATIC_DIR, full_path)
297
+ if os.path.isfile(file_path):
298
+ return FileResponse(file_path)
299
  index_path = os.path.join(STATIC_DIR, "index.html")
300
+ if os.path.isfile(index_path):
301
+ return FileResponse(index_path)
302
  raise HTTPException(404, detail="Not found")
303
 
304
  if __name__ == "__main__":