prashasti commited on
Commit
423bddd
·
1 Parent(s): ad747a5
Files changed (4) hide show
  1. Dockerfile +7 -8
  2. requirements.txt +4 -4
  3. server/app.py +30 -1
  4. ui.py +0 -100
Dockerfile CHANGED
@@ -2,17 +2,16 @@ FROM python:3.12-slim
2
 
3
  WORKDIR /app
4
 
5
- # install uv (fast dependency manager)
6
- RUN pip install --no-cache-dir uv
 
7
 
8
- # copy everything
9
  COPY . .
10
 
11
- # install project from pyproject.toml
12
- RUN uv pip install --system -e ".[dev]"
 
13
 
14
- # expose API port (FastAPI default)
15
  EXPOSE 8000
16
 
17
- # run using your pyproject entrypoint
18
- CMD ["server"]
 
2
 
3
  WORKDIR /app
4
 
5
+ COPY requirements.txt .
6
+ RUN pip install --no-cache-dir -r requirements.txt
7
+
8
 
 
9
  COPY . .
10
 
11
+ ENV API_BASE_URL="https://router.huggingface.co/v1"
12
+ ENV MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"
13
+ ENV HF_TOKEN=""
14
 
 
15
  EXPOSE 8000
16
 
17
+ CMD ["python", "inference.py"]
 
requirements.txt CHANGED
@@ -1,6 +1,6 @@
1
- fastapi==0.110.0
2
- uvicorn==0.29.0
3
- pydantic==2.6.4
4
  openai>=1.0.0
 
5
  openenv-core>=0.2.0
6
- pyyaml>=6.0
 
1
+ fastapi>=0.110.0
2
+ uvicorn>=0.29.0
 
3
  openai>=1.0.0
4
+ python-dotenv>=1.0.0
5
  openenv-core>=0.2.0
6
+ pydantic>=2.0.0
server/app.py CHANGED
@@ -5,35 +5,46 @@ Exposes:
5
  POST /reset
6
  POST /step
7
  GET /state
 
8
  """
9
 
10
  from __future__ import annotations
11
  from typing import Dict, Any, Optional
12
 
13
  import os
 
14
  import uvicorn
15
  from fastapi import FastAPI, HTTPException
16
  from pydantic import BaseModel
17
 
18
- # Import your environments
 
 
19
  from tasks.task_simple import create_env as create_simple
20
  from tasks.task_multi_service import create_env as create_multi
21
  from tasks.task_critical import create_env as create_critical
22
 
 
 
23
 
24
  app = FastAPI(title="DebugOps AI Environment", version="1.0.0")
25
 
26
  # Global env instance
27
  _env = None
28
 
 
29
  class ResetRequest(BaseModel):
 
30
  task: str = "simple" # simple | multi_service | critical
31
 
32
 
33
  class StepRequest(BaseModel):
 
34
  action: str
35
 
 
36
  def create_env(task: str):
 
37
  if task == "simple":
38
  return create_simple()
39
  elif task == "multi_service":
@@ -45,13 +56,16 @@ def create_env(task: str):
45
 
46
 
47
  def get_env():
 
48
  global _env
49
  if _env is None:
50
  raise HTTPException(status_code=400, detail="Call /reset first")
51
  return _env
52
 
 
53
  @app.get("/")
54
  def root():
 
55
  return {
56
  "name": "DebugOps AI Environment",
57
  "description": "Production debugging RL environment (OpenEnv compatible)",
@@ -61,14 +75,17 @@ def root():
61
 
62
  @app.get("/health")
63
  def health():
 
64
  return {"status": "ok"}
65
 
66
 
67
  @app.post("/reset")
68
  def reset(request: Optional[ResetRequest] = None):
 
69
  global _env
70
  try:
71
  task = request.task if request else "simple"
 
72
 
73
  _env = create_env(task)
74
  obs = _env.reset()
@@ -79,15 +96,18 @@ def reset(request: Optional[ResetRequest] = None):
79
  }
80
 
81
  except Exception as e:
 
82
  raise HTTPException(status_code=500, detail=str(e))
83
 
84
 
85
  @app.post("/step")
86
  def step(request: StepRequest):
 
87
  env = get_env()
88
 
89
  try:
90
  obs, reward, done, info = env.step(request.action)
 
91
 
92
  return {
93
  "observation": obs,
@@ -97,19 +117,28 @@ def step(request: StepRequest):
97
  }
98
 
99
  except Exception as e:
 
100
  raise HTTPException(status_code=400, detail=str(e))
101
 
102
 
103
  @app.get("/state")
104
  def state():
 
105
  env = get_env()
106
  try:
107
  return env.state()
108
  except Exception as e:
 
109
  raise HTTPException(status_code=400, detail=str(e))
110
 
 
 
 
 
111
  def main():
 
112
  port = int(os.getenv("PORT", 7860))
 
113
  uvicorn.run(app, host="0.0.0.0", port=port)
114
 
115
 
 
5
  POST /reset
6
  POST /step
7
  GET /state
8
+ GET /health
9
  """
10
 
11
  from __future__ import annotations
12
  from typing import Dict, Any, Optional
13
 
14
  import os
15
+ import logging
16
  import uvicorn
17
  from fastapi import FastAPI, HTTPException
18
  from pydantic import BaseModel
19
 
20
+
21
+
22
+ # Import environments
23
  from tasks.task_simple import create_env as create_simple
24
  from tasks.task_multi_service import create_env as create_multi
25
  from tasks.task_critical import create_env as create_critical
26
 
27
+ # Configure logging
28
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
29
 
30
  app = FastAPI(title="DebugOps AI Environment", version="1.0.0")
31
 
32
  # Global env instance
33
  _env = None
34
 
35
+
36
  class ResetRequest(BaseModel):
37
+ """Request schema for resetting the environment."""
38
  task: str = "simple" # simple | multi_service | critical
39
 
40
 
41
  class StepRequest(BaseModel):
42
+ """Request schema for stepping through the environment."""
43
  action: str
44
 
45
+
46
  def create_env(task: str):
47
+ """Factory method to create environment based on task type."""
48
  if task == "simple":
49
  return create_simple()
50
  elif task == "multi_service":
 
56
 
57
 
58
  def get_env():
59
+ """Retrieve the current environment instance."""
60
  global _env
61
  if _env is None:
62
  raise HTTPException(status_code=400, detail="Call /reset first")
63
  return _env
64
 
65
+
66
  @app.get("/")
67
  def root():
68
+ """Root endpoint providing metadata and available endpoints."""
69
  return {
70
  "name": "DebugOps AI Environment",
71
  "description": "Production debugging RL environment (OpenEnv compatible)",
 
75
 
76
  @app.get("/health")
77
  def health():
78
+ """Health check endpoint."""
79
  return {"status": "ok"}
80
 
81
 
82
  @app.post("/reset")
83
  def reset(request: Optional[ResetRequest] = None):
84
+ """Reset the environment with a given task."""
85
  global _env
86
  try:
87
  task = request.task if request else "simple"
88
+ logging.info(f"Resetting environment with task: {task}")
89
 
90
  _env = create_env(task)
91
  obs = _env.reset()
 
96
  }
97
 
98
  except Exception as e:
99
+ logging.error(f"Error during reset: {e}")
100
  raise HTTPException(status_code=500, detail=str(e))
101
 
102
 
103
  @app.post("/step")
104
  def step(request: StepRequest):
105
+ """Perform a step in the environment with the given action."""
106
  env = get_env()
107
 
108
  try:
109
  obs, reward, done, info = env.step(request.action)
110
+ logging.info(f"Step taken: {request.action}, reward={reward}, done={done}")
111
 
112
  return {
113
  "observation": obs,
 
117
  }
118
 
119
  except Exception as e:
120
+ logging.error(f"Error during step: {e}")
121
  raise HTTPException(status_code=400, detail=str(e))
122
 
123
 
124
  @app.get("/state")
125
  def state():
126
+ """Retrieve the current environment state."""
127
  env = get_env()
128
  try:
129
  return env.state()
130
  except Exception as e:
131
+ logging.error(f"Error retrieving state: {e}")
132
  raise HTTPException(status_code=400, detail=str(e))
133
 
134
+
135
+
136
+
137
+
138
  def main():
139
+ """Entry point for running the FastAPI server."""
140
  port = int(os.getenv("PORT", 7860))
141
+ logging.info(f"Starting DebugOps server on port {port}")
142
  uvicorn.run(app, host="0.0.0.0", port=port)
143
 
144
 
ui.py DELETED
@@ -1,100 +0,0 @@
1
- import os
2
-
3
- import gradio as gr
4
- import requests
5
-
6
- BASE_URL = os.getenv("SPACE_URL", "http://localhost:8000")
7
-
8
- current_logs = []
9
- current_actions = []
10
-
11
-
12
- def reset_env(task):
13
- try:
14
- res = requests.post(f"{BASE_URL}/reset", json={"task": task})
15
- res.raise_for_status()
16
-
17
- data = res.json()
18
- obs = data["observation"]
19
-
20
- return (
21
- format_logs(obs.get("logs", [])),
22
- "Environment reset",
23
- "Running...",
24
- )
25
-
26
- except Exception as e:
27
- return ("Error occurred", str(e), "Failed", None)
28
-
29
-
30
- def step_env(action):
31
- try:
32
- res = requests.post(f"{BASE_URL}/step", json={"action": action})
33
- res.raise_for_status()
34
-
35
- data = res.json()
36
-
37
- obs = data["observation"]
38
- reward = data["reward"]
39
- done = data["done"]
40
-
41
- return (
42
- format_logs(obs.get("logs", [])),
43
- f"{action} → {reward}",
44
- "Done" if done else "Running",
45
- )
46
-
47
- except Exception as e:
48
- return ("Error occurred", str(e), "Failed", None)
49
-
50
-
51
- def format_logs(logs):
52
- return "\n".join([f"• {log}" for log in logs])
53
-
54
-
55
- def build_ui():
56
- with gr.Blocks() as demo:
57
- gr.Markdown("#DebugOps AI Environment")
58
- gr.Markdown("Interactive incident response simulator")
59
-
60
- task_dropdown = gr.Dropdown(
61
- ["simple", "multi_service", "critical"],
62
- label="Select Task",
63
- value="simple"
64
- )
65
-
66
- reset_btn = gr.Button("Reset Environment")
67
-
68
- logs_box = gr.Textbox(label="Logs", lines=10)
69
- actions_box = gr.Textbox(label="Actions Taken", lines=10)
70
- status_box = gr.Textbox(label="Status")
71
-
72
- with gr.Row():
73
- gr.Button("Restart API").click(
74
- lambda: step_env("restart_api"),
75
- outputs=[logs_box, actions_box, status_box]
76
- )
77
- gr.Button("Restart DB").click(
78
- lambda: step_env("restart_db"),
79
- outputs=[logs_box, actions_box, status_box]
80
- )
81
- gr.Button("Restart Cache").click(
82
- lambda: step_env("restart_cache"),
83
- outputs=[logs_box, actions_box, status_box]
84
- )
85
- gr.Button("Scale Up").click(
86
- lambda: step_env("scale_up"),
87
- outputs=[logs_box, actions_box, status_box]
88
- )
89
- gr.Button("No-op").click(
90
- lambda: step_env("noop"),
91
- outputs=[logs_box, actions_box, status_box]
92
- )
93
-
94
- reset_btn.click(
95
- reset_env,
96
- inputs=task_dropdown,
97
- outputs=[logs_box, actions_box, status_box]
98
- )
99
-
100
- return demo