jeevan2717's picture
Initial deployment — Incident Post-Mortem Writer OpenEnv
6f89aae
Raw
History Blame Contribute Delete
5.36 kB
"""
Typed HTTP Client for the Incident Post-Mortem Writer OpenEnv environment.
Follows the OpenEnv HTTPEnvClient pattern with typed _step_payload and _parse_result.
"""
from __future__ import annotations
from typing import Any, Dict, Optional
import requests
class PostMortemEnv:
"""
Typed HTTP client for the Incident Post-Mortem Writer OpenEnv environment.
Follows the OpenEnv HTTPEnvClient pattern.
Usage (sync):
with PostMortemEnv(base_url="http://localhost:7860") as env:
result = env.reset(difficulty="easy")
obs = result["observation"]
result = env.step({"action_type": "QUERY_LOGS",
"query_service": "payments",
"query_from": "03:38", "query_to": "03:45"})
result = env.submit()
Usage (WebSocket — persistent session):
import websockets, asyncio, json
async with websockets.connect("ws://localhost:7860/ws") as ws:
await ws.send(json.dumps({"command": "reset", "difficulty": "easy"}))
result = json.loads(await ws.recv())
"""
def __init__(self, base_url: str = "http://localhost:7860", timeout: int = 30):
self.base_url = base_url.rstrip("/")
self.timeout = timeout
self._session = requests.Session()
# ------------------------------------------------------------------
# OpenEnv core API — matches HTTPEnvClient interface
# ------------------------------------------------------------------
def _step_payload(self, action: Dict[str, Any]) -> Dict[str, Any]:
"""Convert typed action dict to JSON payload for HTTP POST /step."""
return action
def _parse_result(self, payload: Dict[str, Any]) -> Dict[str, Any]:
"""Parse HTTP JSON response into validated result dict with observation, reward, done, info."""
return {
"observation": payload.get("observation", {}),
"reward": float(payload.get("reward", {}).get("total", 0.0) if isinstance(payload.get("reward"), dict) else payload.get("reward") or 0.0),
"done": bool(payload.get("done", False)),
"info": payload.get("info", {}),
}
def _parse_state(self, payload: Dict[str, Any]) -> Dict[str, Any]:
"""Parse HTTP JSON response from GET /state."""
return payload
def reset(self, difficulty: str = "easy") -> Dict[str, Any]:
"""Reset environment. Returns StepResult with observation, reward, done, info."""
resp = self._session.post(
f"{self.base_url}/reset",
json={"difficulty": difficulty},
timeout=self.timeout,
)
resp.raise_for_status()
return self._parse_result(resp.json())
def step(self, action: Dict[str, Any]) -> Dict[str, Any]:
"""Execute one action. Returns StepResult with observation, reward, done, info."""
resp = self._session.post(
f"{self.base_url}/step",
json=self._step_payload(action),
timeout=self.timeout,
)
resp.raise_for_status()
return self._parse_result(resp.json())
def state(self) -> Dict[str, Any]:
"""Get current episode state."""
resp = self._session.get(f"{self.base_url}/state", timeout=self.timeout)
resp.raise_for_status()
return self._parse_state(resp.json())
def health(self) -> bool:
"""Returns True if server is healthy."""
try:
resp = self._session.get(f"{self.base_url}/health", timeout=5)
return resp.status_code == 200
except Exception:
return False
def tasks(self) -> Dict[str, Any]:
"""List all available tasks."""
resp = self._session.get(f"{self.base_url}/tasks", timeout=self.timeout)
resp.raise_for_status()
return resp.json()
# ------------------------------------------------------------------
# Typed convenience helpers
# ------------------------------------------------------------------
def query_logs(self, service: str, from_time: str, to_time: str) -> Dict[str, Any]:
return self.step({"action_type": "QUERY_LOGS",
"query_service": service,
"query_from": from_time,
"query_to": to_time})
def write_section(self, section_name: str, content: str) -> Dict[str, Any]:
return self.step({"action_type": "WRITE_SECTION",
"section_name": section_name,
"section_content": content})
def assign_action_item(self, description: str, owner: str, due_date: str) -> Dict[str, Any]:
return self.step({"action_type": "ASSIGN_ACTION_ITEM",
"action_item_description": description,
"action_item_owner": owner,
"action_item_due_date": due_date})
def submit(self) -> Dict[str, Any]:
return self.step({"action_type": "SUBMIT"})
# ------------------------------------------------------------------
# Context manager
# ------------------------------------------------------------------
def __enter__(self):
return self
def __exit__(self, *_):
self.close()
def close(self):
self._session.close()