"""Thin operator web console for the API server. This keeps the UI intentionally small: an aiohttp-mounted cockpit that surfaces Hermes health, browser runtime state, and ecosystem discovery without introducing a second heavyweight frontend architecture. """ from __future__ import annotations import json from html import escape from typing import Any, Dict from aiohttp import web from tools.browser_tool import browser_runtime_heal, browser_runtime_status _DISCOVERY_FRONTENDS = [ "Open WebUI", "LobeChat", "LibreChat", "AnythingLLM", "NextChat", "ChatBox", ] def _adapter(request: web.Request): return request.app["api_server_adapter"] def _auth_or_none(request: web.Request): adapter = _adapter(request) return adapter._check_auth(request) def _render_console_html(adapter) -> str: health = { "platform": "api_server", "host": adapter._host, "port": adapter._port, "model": adapter._model_name, "auth_required": bool(adapter._api_key), } health_json = escape(json.dumps(health, indent=2, ensure_ascii=False)) return f''' Hermes Web Console

Hermes Web Console operator cockpit

Thin web UI over the existing API server, browser runtime, and streaming endpoints.

Gateway Health

{health_json}

Browser Cockpit

Loading...

Ecosystem Discovery

Loading...
''' async def handle_web_console_index(request: web.Request) -> web.Response: return web.Response(text=_render_console_html(_adapter(request)), content_type="text/html") async def handle_gui_health(request: web.Request) -> web.Response: adapter = _adapter(request) return web.json_response({ "status": "ok", "platform": "api_server", "host": adapter._host, "port": adapter._port, "model": adapter._model_name, "auth_required": bool(adapter._api_key), }) async def handle_browser_status(request: web.Request) -> web.Response: auth_err = _auth_or_none(request) if auth_err is not None: return auth_err return web.json_response(browser_runtime_status()) async def handle_browser_heal(request: web.Request) -> web.Response: auth_err = _auth_or_none(request) if auth_err is not None: return auth_err return web.json_response(browser_runtime_heal()) async def handle_discovery(request: web.Request) -> web.Response: adapter = _adapter(request) return web.json_response({ "frontends": _DISCOVERY_FRONTENDS, "operator_cockpit": { "root": "/", "health": "/api/gui/health", "browser_status": "/api/gui/browser/status", "browser_heal": "/api/gui/browser/heal", }, "openai_compatible": { "models": "/v1/models", "chat_completions": "/v1/chat/completions", "responses": "/v1/responses", "runs": "/v1/runs", "run_events": "/v1/runs/{run_id}/events", "model_name": adapter._model_name, }, }) def maybe_register_web_console(app: web.Application) -> None: app.router.add_get("/", handle_web_console_index) app.router.add_get("/api/gui/health", handle_gui_health) app.router.add_get("/api/gui/browser/status", handle_browser_status) app.router.add_post("/api/gui/browser/heal", handle_browser_heal) app.router.add_get("/api/gui/discovery", handle_discovery)