File size: 10,097 Bytes
922c4d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
---
title: IncidentOps SRE Environment
emoji: 🚨
colorFrom: red
colorTo: gray
sdk: docker
app_port: 8000
---

# IncidentOps β€” AI Incident Response Training Environment

[![OpenEnv](https://img.shields.io/badge/OpenEnv-compatible-blue)](https://github.com/meta-pytorch/OpenEnv)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Team: CodeBlockers](https://img.shields.io/badge/Team-CodeBlockers-purple)](https://huggingface.co/chandan123467896uyjh)

**IncidentOps** is a production-grade OpenEnv environment that trains AI agents to respond to real-world production incidents, just like an on-call Site Reliability Engineer (SRE).

The agent interacts with a simulated microservice infrastructure through a realistic text-based terminal, executing commands to triage alerts, investigate logs and metrics, identify root causes, and apply remediations.

> **Why this matters**: Incident response is one of the highest-stakes, time-sensitive tasks in software engineering. Training AI agents to perform it well has immediate real-world value for DevOps/SRE teams.

---

## Environment Description

The agent acts as an on-call SRE engineer who receives a pager alert. They must:

1. **Triage** β€” Check active alerts and system-wide dashboard to understand impact
2. **Investigate** β€” Dig into logs, metrics, distributed traces, and diagnostics
3. **Identify Root Cause** β€” Determine which service failed and why
4. **Remediate** β€” Apply the correct fix (restart, rollback, failover, config change)
5. **Resolve** β€” Confirm recovery and close the incident

The environment simulates realistic microservice architectures with:
- Service dependency graphs (5–8 services per scenario)
- Timestamped log streams showing the failure progression
- Performance metrics (CPU, memory, latency percentiles, error rates)
- Distributed request traces across the service mesh
- Multiple alerts with varying severity β€” including red-herring alerts

---

## Action Space

The agent issues text commands through a terminal-style interface:

| Command | Description | Example |
|---------|-------------|---------|
| `help` | List all available commands | `help` |
| `status` | System-wide service dashboard | `status` |
| `alerts` | Active alerts with severity and details | `alerts` |
| `logs <service>` | Recent log entries for a service | `logs api-gateway` |
| `metrics <service>` | CPU / memory / latency / error-rate | `metrics database-primary` |
| `trace <request_id>` | Follow a request across services | `trace req-48219` |
| `diagnose <service>` | Deep diagnostic with recommendations | `diagnose payment-processor` |
| `restart <service>` | Restart a service | `restart payment-processor` |
| `scale <service> <n>` | Scale replica count | `scale read-service 6` |
| `rollback <service>` | Roll back last deployment | `rollback api-gateway` |
| `failover <service>` | Promote standby to primary | `failover database-primary` |
| `config <service> <key> <val>` | Update live configuration | `config api-gateway pool_size 100` |
| `notify <channel> <msg>` | Post status update to team | `notify oncall investigating` |
| `resolve` | Declare the incident resolved (ends episode) | `resolve` |

### Action Model

```python
class IncidentAction(Action):
    command: str    # Full command string including arguments
```

---

## Observation Space

After each action, the environment returns:

```python
class IncidentObservation(Observation):
    output: str              # Terminal-style output from the command
    timestamp: str           # Current simulation time (ISO-8601)
    alert_count: int         # Number of active alerts remaining
    severity: str            # Incident severity: "critical" | "high" | "medium" | "low" | "none"
    affected_services: list  # Services currently degraded or down
    done: bool               # True when episode has ended
    reward: float            # Score in open interval (0.01, 0.99)
    metadata: dict           # task_name, episode_id, step, final_score
```

---

## Tasks

Three tasks of increasing difficulty. Select at reset time via `task_name` parameter.

### Task 1: `service-restart` β€” OOM Service Crash (Easy)

**Scenario**: A `payment-processor` microservice has been OOM-killed (Out of Memory). It has entered CrashLoopBackOff. Three alerts are firing including a `critical` alert.

**Objective**: Identify the crashing service and restart it.

**Expected episode length**: 3–6 steps

**Grading**:
- Checked alerts: +5%
- Checked payment-processor logs/metrics: +12%
- Found root cause (payment-processor): +30%
- Applied correct fix (restart payment-processor): +30%
- Sent a status notification: +5%
- Efficiency bonus (≀ 4 steps): +5%

**Baseline score**: ~0.65

---

### Task 2: `config-drift` β€” Connection Pool Exhaustion (Medium)

**Scenario**: A recent deployment to `api-gateway` (v3.1.5) introduced a config regression β€” the connection pool size was set to 5 (was 100). This causes connection pool exhaustion, cascading timeouts across 3 downstream services, and a `critical` + `high` alert combo.

**Objective**: Identify the config regression and fix it (rollback or `config api-gateway pool_size 100`).

**Expected episode length**: 6–12 steps

**Grading**:
- Investigated 2+ services: +10%
- Diagnosed api-gateway: +30%
- Applied correct fix (rollback or config): +30%
- Sent notification: +5%
- Efficiency bonus: +5%

**Baseline score**: ~0.58

---

### Task 3: `cascading-failure` β€” Disk I/O β†’ Cache Stampede β†’ API Overload (Hard)

**Scenario**: A complex multi-service cascading failure:
- `database-primary` disk I/O saturated (iowait 82%)
- Replication lag builds to 182 seconds
- `cache-layer` gets a stampede (cache hit rate drops from 94% to 16%, CPU hits 99.8%)
- `api-gateway` becomes overloaded (72% error rate)
- Two **red-herring** alerts are included (notification-service delay, inventory maintenance window)

**Objective**: Full incident lifecycle β€” identify disk I/O root cause, execute `failover database-primary` then `restart cache-layer`, verify recovery.

**Expected episode length**: 10–20 steps

**Grading**:
- Explored full causal chain (DB β†’ cache β†’ API): +30%
- Identified database-primary as root cause: +25%
- DB failover: +18%
- Cache restart: +12%
- Both steps executed: +30% total (instead of +18+12)
- Notification: +5%
- Efficiency + avoided red herrings: up to +10%

**Baseline score**: ~0.48

---

## Reward Function

Rewards are **dense** β€” they provide signal on every step, not just at episode end.

| Phase | Range | Signal |
|-------|-------|--------|
| Investigation steps | 0.01–0.05 incremental | +0.05 for root-cause service, +0.03 for affected, +0.01 for healthy |
| Root cause identification | 0.05–0.30 | Based on depth of investigation |
| Correct remediation | 0.30 | On correct fix applied to correct service |
| Wrong remediation | βˆ’0.05 | Restarting healthy services penalised |
| Communication | 0.05 | At least one `notify` issued |
| Efficiency | 0.00–0.10 | Inverse of excess steps taken |

All rewards are clamped to the **open interval (0.01, 0.99)** to satisfy the OpenEnv validator.

---

## Setup & Usage

### Prerequisites

- Python 3.10+
- `pip install openenv-core`

### Local Development (without Docker)

```bash
# Install
pip install -e ".[dev]"

# Run the server locally
uvicorn server.app:app --host 0.0.0.0 --port 8000 --reload

# In a separate terminal β€” connect and interact
python - <<'EOF'
from incident_ops_env import IncidentAction, IncidentOpsEnv

with IncidentOpsEnv(base_url="http://localhost:8000").sync() as env:
    result = env.reset(task_name="service-restart")
    print(result.observation.output)

    for cmd in ["alerts", "logs payment-processor", "restart payment-processor", "resolve"]:
        result = env.step(IncidentAction(command=cmd))
        print(result.observation.output)
        if result.observation.done:
            print(f"\nFinal score: {result.reward:.3f}")
            break
EOF
```

### Docker

```bash
# Build
docker build -f server/Dockerfile -t incident-ops-env:latest .

# Run
docker run -p 8000:8000 incident-ops-env:latest

# Validate
openenv validate
```

### Running the Baseline Inference Script

```bash
export HF_TOKEN="your-token"
export API_BASE_URL="https://router.huggingface.co/v1"
export MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"
export INCIDENT_BASE_URL="http://localhost:8000"

python inference.py
```

### Running Tests

```bash
pip install ".[dev]"
pytest tests/test_env.py -v
```

---

## Baseline Scores

Scores achieved by `Qwen/Qwen2.5-72B-Instruct` via HuggingFace Inference:

| Task | Difficulty | Baseline Score |
|------|-----------|---------------|
| `service-restart` | Easy | ~0.65 |
| `config-drift` | Medium | ~0.58 |
| `cascading-failure` | Hard | ~0.48 |

A perfect agent would score ~0.95 on all tasks. These baseline scores leave significant headroom for RL training to improve agent performance.

---

## Project Structure

```
.
β”œβ”€β”€ openenv.yaml          # OpenEnv manifest
β”œβ”€β”€ pyproject.toml        # Package and dependency configuration
β”œβ”€β”€ README.md             # This file
β”œβ”€β”€ inference.py          # Baseline inference script
β”œβ”€β”€ __init__.py           # Package exports
β”œβ”€β”€ models.py             # Pydantic Action/Observation models
β”œβ”€β”€ client.py             # EnvClient subclass
β”œβ”€β”€ tests/
β”‚   └── test_env.py       # Unit tests
└── server/
    β”œβ”€β”€ __init__.py
    β”œβ”€β”€ app.py             # FastAPI application
    β”œβ”€β”€ Dockerfile         # Container image
    β”œβ”€β”€ environment.py     # Core IncidentOpsEnvironment class
    β”œβ”€β”€ scenarios.py       # Three incident scenario definitions
    β”œβ”€β”€ graders.py         # Task-specific scoring functions
    └── simulation.py      # System simulation engine
```

---

## HuggingFace Space

**URL**: https://chandan123467896uyjh.hf.space

**Team**: CodeBlockers

---

## License 

MIT License. See [LICENSE](LICENSE) file.