Spaces:
Sleeping
Sleeping
| import asyncio | |
| import json | |
| import os | |
| import textwrap | |
| from typing import List, Optional | |
| import requests | |
| from openai import OpenAI | |
| HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("API_KEY", "dummy") | |
| API_BASE_URL = os.getenv("API_BASE_URL", "https://router.huggingface.co/v1") | |
| MODEL_NAME = os.getenv("MODEL_NAME", "Qwen/Qwen2.5-72B-Instruct") | |
| ENV_BASE_URL = os.getenv("ENV_BASE_URL", "http://localhost:8000") | |
| BENCHMARK = "crisis_room" | |
| SUCCESS_SCORE_THRESHOLD = 0.3 | |
| SYSTEM_PROMPT = textwrap.dedent(""" | |
| You are an AI Site Reliability Engineer responding to a live production incident. | |
| You will receive alerts, service statuses, and log outputs. | |
| Your job is to investigate, identify the root cause, fix it, and notify the team. | |
| Available actions: | |
| - check_logs: Read logs for a specific service. target = service name. | |
| - run_diagnostic: Run a diagnostic check. target = diagnostic name (e.g. memory, cpu, db_connections, dns_check, data_integrity, ssl_check). | |
| - restart_service: Restart a specific service. Only do this after you understand the cause. | |
| - rollback_deployment: Roll back a service to previous version. target = service name. | |
| - scale_up: Add more instances. target = service name. | |
| - notify_team: Send a message to the team. target = your message. | |
| - escalate: Escalate to on-call lead. target = reason. | |
| - mark_resolved: Close the incident. target = root cause description. | |
| Respond with ONLY a JSON object like: | |
| {"action_type": "check_logs", "target": "payment-service"} | |
| No explanation. No preamble. Valid JSON only. | |
| Think step by step: investigate first, then fix, then notify. | |
| """).strip() | |
| TASKS = [ | |
| {"name": "easy-incident", "difficulty": "easy"}, | |
| {"name": "medium-incident", "difficulty": "medium"}, | |
| {"name": "hard-incident", "difficulty": "hard"}, | |
| ] | |
| def env_reset(difficulty: str): | |
| r = requests.post( | |
| f"{ENV_BASE_URL}/reset", | |
| json={"difficulty": difficulty}, | |
| headers={"Content-Type": "application/json"}, | |
| timeout=30, | |
| ) | |
| r.raise_for_status() | |
| return r.json() | |
| def env_step(action_type: str, target: str): | |
| r = requests.post( | |
| f"{ENV_BASE_URL}/step", | |
| json={"action": {"action_type": action_type, "target": target}}, | |
| timeout=30, | |
| ) | |
| r.raise_for_status() | |
| return r.json() | |
| def get_action(client: OpenAI, obs: dict, history: List[str]) -> dict: | |
| alerts = obs.get("active_alerts", []) | |
| status = obs.get("service_status", {}) | |
| log_out = obs.get("log_output", "") | |
| message = obs.get("message", "") | |
| history_block = "\n".join(history[-6:]) if history else "None" | |
| user_prompt = textwrap.dedent(f""" | |
| INCIDENT MESSAGE: {message} | |
| ACTIVE ALERTS: | |
| {chr(10).join(alerts)} | |
| SERVICE STATUS: | |
| {json.dumps(status, indent=2)} | |
| LAST LOG/DIAGNOSTIC OUTPUT: | |
| {log_out or "None yet"} | |
| PREVIOUS ACTIONS: | |
| {history_block} | |
| What is your next action? Respond with JSON only. | |
| """).strip() | |
| try: | |
| completion = client.chat.completions.create( | |
| model=MODEL_NAME, | |
| messages=[ | |
| {"role": "system", "content": SYSTEM_PROMPT}, | |
| {"role": "user", "content": user_prompt}, | |
| ], | |
| temperature=0.3, | |
| max_tokens=100, | |
| ) | |
| text = (completion.choices[0].message.content or "").strip() | |
| if text.startswith("```"): | |
| text = text.split("```")[1] | |
| if text.startswith("json"): | |
| text = text[4:] | |
| return json.loads(text.strip()) | |
| except Exception as exc: | |
| print(f"[DEBUG] Model error: {exc}", flush=True) | |
| return {"action_type": "check_logs", "target": ""} | |
| def log_start(task, env, model): | |
| print(f"[START] task={task} env={env} model={model}", flush=True) | |
| def log_step(step, action, reward, done, error): | |
| err = error if error else "null" | |
| print(f"[STEP] step={step} action={action[:100]} reward={reward:.2f} done={str(done).lower()} error={err}", flush=True) | |
| def log_end(success, steps, score, rewards): | |
| r = ",".join(f"{x:.2f}" for x in rewards) | |
| print(f"[END] success={str(success).lower()} steps={steps} score={score:.3f} rewards={r}", flush=True) | |
| async def run_episode(client: OpenAI, task: dict) -> float: | |
| difficulty = task["difficulty"] | |
| task_name = task["name"] | |
| max_steps = {"easy": 8, "medium": 10, "hard": 12}[difficulty] | |
| history: List[str] = [] | |
| rewards: List[float] = [] | |
| steps_taken = 0 | |
| score = 0.0 | |
| success = False | |
| log_start(task=task_name, env=BENCHMARK, model=MODEL_NAME) | |
| try: | |
| result = env_reset(difficulty) | |
| obs = result["observation"] | |
| done = result.get("done", False) | |
| for step in range(1, max_steps + 1): | |
| if done: | |
| break | |
| action_dict = get_action(client, obs, history) | |
| action_type = action_dict.get("action_type", "check_logs") | |
| target = action_dict.get("target", "") | |
| try: | |
| result = env_step(action_type, target) | |
| obs = result["observation"] | |
| reward = float(result.get("reward", 0.0)) | |
| done = result.get("done", False) | |
| error = None | |
| except Exception as e: | |
| reward = 0.0 | |
| done = True | |
| error = str(e) | |
| rewards.append(reward) | |
| steps_taken = step | |
| log_step(step=step, action=f"{action_type}:{target}", reward=reward, done=done, error=error) | |
| history.append(f"Step {step}: {action_type}({target}) -> reward {reward:+.2f}") | |
| if done: | |
| break | |
| score = max(rewards) if rewards else 0.0 | |
| score = min(max(score, 0.0), 1.0) | |
| success = score >= SUCCESS_SCORE_THRESHOLD | |
| finally: | |
| log_end(success=success, steps=steps_taken, score=score, rewards=rewards) | |
| return score | |
| async def main() -> None: | |
| client = OpenAI(base_url=API_BASE_URL, api_key=HF_TOKEN) | |
| all_scores = [] | |
| for task in TASKS: | |
| score = await run_episode(client, task) | |
| all_scores.append(score) | |
| print(f"\n=== FINAL RESULTS ===", flush=True) | |
| for task, score in zip(TASKS, all_scores): | |
| print(f"{task['name']}: {score:.3f}", flush=True) | |
| print(f"Average: {sum(all_scores)/len(all_scores):.3f}", flush=True) | |
| if __name__ == "__main__": | |
| asyncio.run(main()) |