Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 59s
Cherry-pick the Hermes Web Console from gary-the-ai/hermes-web-console-gui. React + TypeScript frontend with Vite, Python aiohttp backend API. Components: - web_console/ — React frontend (chat, sessions, memory, settings, skills, gateway config, cron, workspace, tools, browser, insights pages) - gateway/web_console/ — Python backend API (23 endpoints, SSE event bus, 11 service modules) - gateway/platforms/api_server_ui.py — embedded browser UI for API server - gateway/platforms/api_server.py — route registration refactored into _register_routes(), web console mounted via maybe_register_web_console() - run-gui.sh / setup-gui.sh — one-command launch and setup scripts - tests/gateway/test_api_server_gui_mount.py — 4 integration tests (passing) - tests/web_console/ — 13 backend test files (51 passing) - docs/plans/ — implementation plan, API schema, frontend architecture Fix: added missing ModelContextError class and CRON_MIN_CONTEXT_TOKENS to cron/scheduler.py (pre-existing import bug). Closes #325
47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
"""Metrics API routes for the Hermes Web Console backend."""
|
|
|
|
import logging
|
|
import psutil
|
|
import time
|
|
from aiohttp import web
|
|
|
|
logger = logging.getLogger("metrics_api")
|
|
|
|
async def handle_get_metrics_global(request: web.Request) -> web.Response:
|
|
try:
|
|
from hermes_state import SessionDB
|
|
from agent.insights import InsightsEngine
|
|
from tools.process_registry import process_registry
|
|
|
|
cron_jobs_count = 0
|
|
try:
|
|
from cron.scheduler import scheduler
|
|
cron_jobs_count = len(scheduler.get_jobs()) if hasattr(scheduler, "get_jobs") else 0
|
|
except Exception:
|
|
pass
|
|
|
|
db = SessionDB()
|
|
engine = InsightsEngine(db)
|
|
|
|
# Fetch current day usage as a representative metric snippet
|
|
report = engine.generate(days=1)
|
|
db.close()
|
|
|
|
metrics = {
|
|
"token_usage_today": report.get("total_tokens", 0),
|
|
"cost_today": report.get("estimated_cost_usd", 0.0),
|
|
"active_processes": len([s for s in process_registry.list_sessions() if s.get("status") == "running"]),
|
|
"cron_jobs": cron_jobs_count,
|
|
"cpu_percent": psutil.cpu_percent(interval=None),
|
|
"memory_percent": psutil.virtual_memory().percent,
|
|
"uptime_seconds": time.time() - psutil.boot_time(),
|
|
}
|
|
|
|
return web.json_response({"ok": True, "metrics": metrics})
|
|
except Exception as e:
|
|
logger.error(f"Failed to fetch global metrics: {e}")
|
|
return web.json_response({"ok": False, "error": str(e)}, status=500)
|
|
|
|
def register_metrics_api_routes(app: web.Application) -> None:
|
|
app.router.add_get("/api/gui/metrics/global", handle_get_metrics_global)
|