Spaces:
Sleeping
Sleeping
| """ | |
| LogSentinel v2 FastAPI application — canonical definition. | |
| Both server.py (root) and server/__init__.py import from here. | |
| """ | |
| import sys | |
| import os | |
| # Ensure parent directory (repo root) is on sys.path for module imports | |
| _repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| if _repo_root not in sys.path: | |
| sys.path.insert(0, _repo_root) | |
| from typing import Any, Dict | |
| from fastapi import Body, FastAPI | |
| from environment import LogSentinelEnv | |
| from tasks import TASKS | |
| app = FastAPI( | |
| title="LogSentinel v2 — Multi-Agent SOC War-Room", | |
| description="OpenEnv-compliant multi-agent SOC environment for RLVR training.", | |
| version="2.0.0", | |
| ) | |
| env = LogSentinelEnv() | |
| async def root() -> Dict[str, Any]: | |
| """Root endpoint — environment info.""" | |
| return { | |
| "name": "LogSentinel", | |
| "version": "2.0.0", | |
| "description": ( | |
| "Adaptive Multi-Agent SOC War-Room environment for training AI agents " | |
| "on real-world incident response with verifiable rewards." | |
| ), | |
| "endpoints": { | |
| "POST /reset": "Reset environment, returns initial observation", | |
| "POST /step": "Execute action, returns {observation, reward, done, info}", | |
| "GET /state": "Current environment state with reward breakdown", | |
| "GET /health": "Health check", | |
| "GET /tasks": "List available tasks", | |
| }, | |
| "status": "healthy", | |
| } | |
| async def reset(request: Dict[str, Any] = Body(default={})) -> Dict[str, Any]: | |
| """Reset the environment and return initial observation.""" | |
| task_name = request.get("task_name") | |
| agent_role = request.get("agent_role") | |
| seed = request.get("seed") | |
| return env.reset(task_name=task_name, agent_role=agent_role, seed=seed) | |
| async def step(request: Dict[str, Any] = Body(...)) -> Dict[str, Any]: | |
| """Take a step with the given action.""" | |
| action_data = request.get("action", {}) | |
| return env.step(action_data) | |
| async def get_state() -> Dict[str, Any]: | |
| """Return current environment state.""" | |
| return env.state | |
| async def health() -> Dict[str, str]: | |
| """Health check endpoint.""" | |
| return {"status": "healthy"} | |
| async def list_tasks() -> Dict[str, Any]: | |
| """List available tasks.""" | |
| return { | |
| "tasks": [ | |
| { | |
| "name": t.name, | |
| "description": t.description, | |
| "difficulty": t.difficulty, | |
| "max_steps": t.max_steps, | |
| "num_logs": t.num_logs, | |
| "multi_agent": t.multi_agent, | |
| } | |
| for t in TASKS.values() | |
| ] | |
| } | |
| def main() -> None: | |
| """Entry point for [project.scripts] server command.""" | |
| import uvicorn | |
| uvicorn.run(app, host="0.0.0.0", port=7860) | |
| if __name__ == "__main__": | |
| main() | |