prashasti commited on
Commit
c016180
·
1 Parent(s): 15c4c1b

Improvements

Browse files
inference.py CHANGED
@@ -40,6 +40,31 @@ if _OPENAI_AVAILABLE and API_KEY:
40
  _client = OpenAI(api_key=API_KEY, base_url=API_BASE_URL)
41
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  # Heuristic fallback agent (used when no LLM key or on API error)
44
  def _fallback_agent(state: Dict[str, Any], action_history: List[str]) -> str:
45
  """
@@ -106,8 +131,9 @@ def _call_llm(
106
 
107
  services_degraded = [s for s, h in state["services"].items() if h == "degraded"]
108
  metrics = state["metrics"]
 
109
 
110
- prompt = f"""You are an expert SRE triaging a production incident. Your goal is to resolve it in as few steps as possible.
111
 
112
  SYSTEM STATE (step {state['time_step']})
113
  Degraded services : {services_degraded if services_degraded else 'none'}
@@ -176,12 +202,28 @@ def run_episode(task_name: str = "simple") -> None:
176
 
177
  action_history: List[str] = []
178
  reward_history: List[float] = []
 
 
179
  episode_logs: List[Dict[str, Any]] = []
180
  done = False
181
  step = 0
182
 
183
  while not done and step < max_steps:
184
- action = _call_llm(state, action_history, reward_history)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
 
186
  try:
187
  next_state, reward, done, info = env.step(action)
@@ -192,11 +234,15 @@ def run_episode(task_name: str = "simple") -> None:
192
 
193
  action_history.append(action)
194
  reward_history.append(reward)
 
 
 
195
  episode_logs.append({"reward": reward, "info": info})
196
 
197
  print(
198
  f"[STEP] step={step} action={action} reward={round(reward, 3)} "
199
- f"done={str(done).lower()} error={error}",
 
200
  flush=True,
201
  )
202
 
 
40
  _client = OpenAI(api_key=API_KEY, base_url=API_BASE_URL)
41
 
42
 
43
+ def infer_root_cause(state: Dict[str, Any]) -> str:
44
+ logs = " ".join(state.get("logs", [])).lower()
45
+ metrics = state.get("metrics", {})
46
+
47
+ if "timeout" in logs or metrics.get("latency", 0) > 1000:
48
+ return "traffic_overload"
49
+
50
+ if "connection" in logs or "db" in logs:
51
+ return "database_issue"
52
+
53
+ if "cache" in logs:
54
+ return "cache_issue"
55
+
56
+ if metrics.get("cpu", 0) > 85:
57
+ return "resource_exhaustion"
58
+
59
+ return "unknown"
60
+
61
+ PLANS = {
62
+ "traffic_overload": ["scale_up", "restart_api"],
63
+ "database_issue": ["restart_db", "scale_up"],
64
+ "cache_issue": ["restart_cache", "scale_up"],
65
+ "resource_exhaustion": ["scale_up"],
66
+ }
67
+
68
  # Heuristic fallback agent (used when no LLM key or on API error)
69
  def _fallback_agent(state: Dict[str, Any], action_history: List[str]) -> str:
70
  """
 
131
 
132
  services_degraded = [s for s, h in state["services"].items() if h == "degraded"]
133
  metrics = state["metrics"]
134
+ root_cause = infer_root_cause(state)
135
 
136
+ prompt = f"""You are an expert SRE triaging a production incident. Your goal is to resolve it in as few steps as possible.ROOT CAUSE HYPOTHESIS: {root_cause}
137
 
138
  SYSTEM STATE (step {state['time_step']})
139
  Degraded services : {services_degraded if services_degraded else 'none'}
 
202
 
203
  action_history: List[str] = []
204
  reward_history: List[float] = []
205
+ bad_actions = set()
206
+ plan: List[str] = []
207
  episode_logs: List[Dict[str, Any]] = []
208
  done = False
209
  step = 0
210
 
211
  while not done and step < max_steps:
212
+ root_cause = infer_root_cause(state)
213
+
214
+ # generate plan if empty
215
+ if not plan:
216
+ plan = PLANS.get(root_cause, []).copy()
217
+
218
+ # choose from plan first
219
+ if plan:
220
+ action = plan.pop(0)
221
+ else:
222
+ action = _call_llm(state, action_history, reward_history)
223
+
224
+ # avoid bad actions
225
+ if action in bad_actions:
226
+ action = _fallback_agent(state, action_history)
227
 
228
  try:
229
  next_state, reward, done, info = env.step(action)
 
234
 
235
  action_history.append(action)
236
  reward_history.append(reward)
237
+
238
+ if reward < -5:
239
+ bad_actions.add(action)
240
  episode_logs.append({"reward": reward, "info": info})
241
 
242
  print(
243
  f"[STEP] step={step} action={action} reward={round(reward, 3)} "
244
+ f"done={str(done).lower()} error={error} "
245
+ f"root_cause={root_cause} plan_remaining={len(plan)}",
246
  flush=True,
247
  )
248
 
tasks/task_critical.py CHANGED
@@ -25,7 +25,7 @@ class CriticalEnv(DebugEnv):
25
 
26
  def reset(self) -> Dict[str, Any]:
27
  state = super().reset()
28
-
29
  self.state_data["root_cause"] = "memory_leak"
30
  self.state_data["fix_sequence"] = ["restart_api", "restart_db"]
31
 
@@ -64,15 +64,30 @@ class CriticalEnv(DebugEnv):
64
 
65
  def step(self, action: str) -> Tuple[Dict[str, Any], float, bool, Dict[str, Any]]:
66
  obs, reward, done, info = super().step(action)
 
 
 
 
67
 
68
  if info["latency"] > self.SLA_LATENCY_THRESHOLD:
69
  reward -= self.SLA_PENALTY
70
 
71
  if self.t > self.TIME_PRESSURE_START and not info["resolved"]:
72
  reward -= self.TIME_PRESSURE_PENALTY
 
 
 
 
 
73
 
74
  reward += random.uniform(-3, 3)
75
 
 
 
 
 
 
 
76
  return obs, reward, done, info
77
 
78
 
 
25
 
26
  def reset(self) -> Dict[str, Any]:
27
  state = super().reset()
28
+ self.last_action = None
29
  self.state_data["root_cause"] = "memory_leak"
30
  self.state_data["fix_sequence"] = ["restart_api", "restart_db"]
31
 
 
64
 
65
  def step(self, action: str) -> Tuple[Dict[str, Any], float, bool, Dict[str, Any]]:
66
  obs, reward, done, info = super().step(action)
67
+ if action == getattr(self, "last_action", None):
68
+ reward -= 5.0
69
+
70
+ self.last_action = action
71
 
72
  if info["latency"] > self.SLA_LATENCY_THRESHOLD:
73
  reward -= self.SLA_PENALTY
74
 
75
  if self.t > self.TIME_PRESSURE_START and not info["resolved"]:
76
  reward -= self.TIME_PRESSURE_PENALTY
77
+ if action == "scale_up":
78
+ reward -= 2.0 # cost penalty
79
+ if action == getattr(self, "last_action", None):
80
+ reward -= 5.0
81
+
82
 
83
  reward += random.uniform(-3, 3)
84
 
85
+ if info.get("resolved"):
86
+ info["explanation"] = "Incident resolved successfully"
87
+ elif reward > 0:
88
+ info["explanation"] = "Correct step towards resolution"
89
+ else:
90
+ info["explanation"] = "Ineffective or incorrect action"
91
  return obs, reward, done, info
92
 
93
 
tasks/task_multi_service.py CHANGED
@@ -12,6 +12,7 @@ class MultiServiceEnv(DebugEnv):
12
 
13
  def reset(self) -> Dict[str, Any]:
14
  state = super().reset()
 
15
  self.state_data["services"]["api"] = "degraded"
16
  self.state_data["services"]["db"] = "degraded"
17
  # Increase starting metric pressure
@@ -21,15 +22,28 @@ class MultiServiceEnv(DebugEnv):
21
  self.state_data["metrics"]["error_rate"] = min(
22
  self.state_data["metrics"]["error_rate"] * 1.2, 0.95
23
  )
 
 
 
24
  return self._obs()
25
 
26
  def step(self, action: str) -> Tuple[Dict[str, Any], float, bool, Dict[str, Any]]:
27
  obs, reward, done, info = super().step(action)
 
 
 
 
 
 
 
28
 
29
  # Additional latency penalty for multi-service SLA
30
  if info["latency"] > 300:
31
  reward -= 10.0
32
-
 
 
 
33
  return obs, reward, done, info
34
 
35
 
 
12
 
13
  def reset(self) -> Dict[str, Any]:
14
  state = super().reset()
15
+ self.last_action = None
16
  self.state_data["services"]["api"] = "degraded"
17
  self.state_data["services"]["db"] = "degraded"
18
  # Increase starting metric pressure
 
22
  self.state_data["metrics"]["error_rate"] = min(
23
  self.state_data["metrics"]["error_rate"] * 1.2, 0.95
24
  )
25
+ self.dependencies = {
26
+ "api": ["db"], # API depends on DB
27
+ }
28
  return self._obs()
29
 
30
  def step(self, action: str) -> Tuple[Dict[str, Any], float, bool, Dict[str, Any]]:
31
  obs, reward, done, info = super().step(action)
32
+ if action == getattr(self, "last_action", None):
33
+ reward -= 5.0
34
+
35
+ self.last_action = action
36
+ # Dependency impact
37
+ if self.state_data["services"]["db"] == "down":
38
+ self.state_data["services"]["api"] = "degraded"
39
 
40
  # Additional latency penalty for multi-service SLA
41
  if info["latency"] > 300:
42
  reward -= 10.0
43
+ if action == "scale_up":
44
+ reward -= 2.0 # cost penalty
45
+
46
+ info["explanation"] = f"Action {action} applied to fix issue"
47
  return obs, reward, done, info
48
 
49
 
tasks/task_simple.py CHANGED
@@ -1,6 +1,35 @@
1
- #Task: Simple: A single-service failure with a 2-step fix sequence.
2
- #Entry-level task - low penalty, generous step budget.
 
 
3
  from env.environment import DebugEnv
4
 
5
- def create_env() -> DebugEnv:
6
- return DebugEnv(max_steps=15)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ from typing import Dict, Any, Tuple
3
+ import random
4
+
5
  from env.environment import DebugEnv
6
 
7
+
8
+ class SimpleEnv(DebugEnv):
9
+
10
+ def reset(self) -> Dict[str, Any]:
11
+ state = super().reset()
12
+ self.last_action = None
13
+ # Add slight noise to logs
14
+ if random.random() < 0.2:
15
+ self.state_data["logs"].append("intermittent network glitch detected")
16
+
17
+ return self._obs()
18
+
19
+ def step(self, action: str) -> Tuple[Dict[str, Any], float, bool, Dict[str, Any]]:
20
+ obs, reward, done, info = super().step(action)
21
+ if action == getattr(self, "last_action", None):
22
+ reward -= 5.0
23
+
24
+ self.last_action = action
25
+
26
+ # Slight metric fluctuation
27
+ self.state_data["metrics"]["latency"] += random.randint(-20, 20)
28
+ self.state_data["metrics"]["cpu"] += random.randint(-3, 3)
29
+
30
+ info["explanation"] = f"Action {action} applied to fix issue"
31
+ return obs, reward, done, info
32
+
33
+
34
+ def create_env() -> SimpleEnv:
35
+ return SimpleEnv(max_steps=15)