Spaces:
Sleeping
Sleeping
| import os, subprocess, json | |
| from pathlib import Path | |
| from fastapi import FastAPI, BackgroundTasks, HTTPException | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from pydantic import BaseModel | |
| app = FastAPI(title="Hermes Serverless") | |
| SESSIONS_DIR = os.environ.get("SESSIONS_DIR", "/data/sessions") | |
| Path(SESSIONS_DIR).mkdir(parents=True, exist_ok=True) | |
| task_registry = {} | |
| class AgentTask(BaseModel): | |
| session_id: str | |
| task: str | |
| def execute_hermes(session_id: str, task: str): | |
| task_registry[session_id] = "running" | |
| workspace = Path(SESSIONS_DIR) / session_id | |
| workspace.mkdir(parents=True, exist_ok=True) | |
| log_path = workspace / "output.log" | |
| env = os.environ.copy() | |
| env.update({"HOME": "/root", "HERMES_HOME": "/root/.hermes"}) | |
| try: | |
| with open(log_path, "a") as f: | |
| p = subprocess.Popen(["hermes", "chat", "-q", task, "--resume", session_id, "--yolo"], cwd=str(workspace), stdout=f, stderr=subprocess.STDOUT, env=env, text=True) | |
| rc = p.wait(timeout=1800) | |
| task_registry[session_id] = "completed" if rc == 0 else f"failed:{rc}" | |
| except Exception as e: | |
| task_registry[session_id] = f"error:{str(e)}" | |
| async def run(payload: AgentTask, bg: BackgroundTasks): | |
| if not payload.session_id or not payload.task: | |
| raise HTTPException(400, "Missing session_id or task") | |
| bg.add_task(execute_hermes, payload.session_id, payload.task) | |
| return {"status": "queued", "session_id": payload.session_id} | |
| def status(session_id: str): | |
| st = task_registry.get(session_id, "unknown") | |
| log = Path(SESSIONS_DIR) / session_id / "output.log" | |
| logs = log.read_text()[-2000:] if log.exists() else "" | |
| return {"session_id": session_id, "status": st, "logs": logs} | |
| def file(session_id: str, filename: str): | |
| if "/" in filename or ".." in filename: | |
| raise HTTPException(400, "Invalid filename") | |
| path = Path(SESSIONS_DIR) / session_id / filename | |
| if not path.exists(): | |
| raise HTTPException(404, "File not found") | |
| return FileResponse(str(path)) | |
| def health(): | |
| return {"status": "ok", "engine": "hermes-serverless"} | |
| def root(): | |
| return {"message": "Hermes Serverless API", "docs": "/docs"} |