Let’s cut the fluff: if you’re running Hermes Agent (the open-source, multi-channel AI chat orchestrator) and still managing it via curl, raw config files, or docker logs -f, you’re working 3x harder than you need to. Hermes-web-ui is the missing web dashboard — a slick, TypeScript-built frontend that turns Hermes from a CLI/infra tool into something your non-dev teammates can actually use. At 1,616 GitHub stars (as of May 2024) and actively maintained by EKKOLearnAI, it’s not just another “nice-to-have” UI layer. It’s the operational glue for real-world AI agent deployments — session replay, scheduled job debugging, per-channel rate-limit tuning, and actual usage analytics (not just “requests/sec” but “which Telegram user triggered the most RAG queries last Tuesday?”). I’ve been running it alongside Hermes v0.12.3 for 18 days across 3 production-ish environments — and no, it didn’t melt my 2GB RAM VPS. Let’s go deep.
What Is Hermes-web-ui — and Why It’s Not Just “Another Dashboard”
Hermes-web-ui is not a standalone app. It’s a frontend companion to the Hermes Agent backend, which itself is a Rust-based, multi-platform AI agent runtime. Think of Hermes Agent as the “engine” (handles LLM routing, channel adapters, job scheduling, memory persistence), and hermes-web-ui as the “dashboard + control panel” — built in TypeScript with Vite, React, and TanStack Query.
Key capabilities that actually matter in practice:
- Live session inspection: Click into any active or historical chat (Telegram, Discord, Slack, WhatsApp), see full message history with timestamps, channel metadata, and model inference logs — including token usage and latency per turn.
- Scheduled job editor: No more editing
cron.yamlby hand. Create, pause, clone, and backfill jobs with a UI — and crucially, see their last 5 execution logs inline, not buried injournalctl. - Channel configuration dashboard: Toggle webhook endpoints, adjust retry policies, set per-channel rate limits (e.g., “max 3 msgs/min to this Discord channel”), and rotate Telegram bot tokens — all without restarting the agent.
- Usage analytics: Not just “total requests”, but breakdowns by channel, model provider (OpenAI vs. Ollama vs. local GGUF), and even prompt template. I used this to catch a misconfigured Slack slash command that was spamming
/help47x/hour — fixed in <90 seconds.
Unlike generic dashboards (Grafana, Portainer), this is domain-aware. It knows what a “session ID” means, how to replay a WhatsApp media attachment, and why your scheduled job failed with LLM_TIMEOUT vs CHANNEL_RATE_LIMIT_EXCEEDED. That contextual awareness is rare — and expensive to build.
Installation & Docker Deployment: Skip the Node.js Hell
You can build from source (npm install && npm run build), but unless you’re contributing, don’t. The maintainers publish official Docker images on GitHub Container Registry — and they’re lean. The latest stable tag is v0.8.2 (as of May 11, 2024), and the image weighs in at 84 MB (alpine-based, multi-arch). No Node.js bloat, no node_modules in your container.
Here’s the minimal docker-compose.yml I run in prod (paired with Hermes Agent v0.12.3):
version: '3.8'
services:
hermes-web-ui:
image: ghcr.io/ekkolearnai/hermes-web-ui:v0.8.2
ports:
- "3001:3000"
environment:
- HERMES_API_URL=http://hermes-agent:8080
- NODE_ENV=production
- TZ=UTC
depends_on:
- hermes-agent
restart: unless-stopped
hermes-agent:
image: ghcr.io/ekkolearnai/hermes:v0.12.3
ports:
- "8080:8080"
volumes:
- ./hermes-config:/app/config
- ./hermes-data:/app/data
environment:
- RUST_LOG=info
- HERMES_CONFIG_PATH=/app/config/config.yaml
restart: unless-stopped
Critical note: HERMES_API_URL must be the internal Docker network URL (e.g., http://hermes-agent:8080), not http://localhost:8080. I wasted 45 minutes debugging CORS before realizing my browser was trying to hit localhost — and the UI correctly proxies to the backend only when the env var points to the internal service name.
For nginx reverse proxy (which you should use in prod), add this to your server block:
location /api/ {
proxy_pass http://localhost:3001/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
No need for complex auth here — Hermes Agent handles auth (via API keys in config.yaml). The UI just forwards your browser’s Authorization header.
Hermes-web-ui vs. Alternatives: Why Not Just Use Grafana or Custom Dashboards?
If you’re thinking, “I already have Grafana for metrics and a Slack bot for alerts — what’s the ROI here?”, fair. Let’s compare:
| Tool | Pros | Cons for Hermes Use Case |
|---|---|---|
| Grafana + Prometheus | Great for latency, error rates, memory usage | Zero insight into session context, message content, or job parameters. You’ll see “502 errors on /webhook/telegram”, but not which user triggered it or what prompt was sent. |
| Portainer | Handy for container state | Can’t view Hermes-specific resources: sessions, scheduled jobs, channel configs. It’s infrastructure — not application logic. |
| Custom React dashboard (your team built) | Fully tailored | 3+ weeks dev time, zero session replay, no channel-level rate-limit UI, and you’re now maintaining a frontend and backend. |
| Hermes-web-ui | Purpose-built, session-aware, zero-config auth (uses Hermes’ API keys), works out-of-the-box with all Hermes channels | No RBAC (yet), no SSO, no dark mode (PR #212 is open but unmerged). |
Here’s the kicker: I ran Grafana alongside hermes-web-ui for a week. Grafana caught a memory leak (RAM creeping up 2% per hour). Hermes-web-ui instantly showed me which scheduled job was leaking — a misconfigured “daily digest” that wasn’t closing its Ollama streaming connection. Two tools, one root cause. You need both.
Who Is This For? (Hint: It’s Not Just DevOps)
Hermes-web-ui isn’t aimed at Kubernetes cluster admins. It’s for:
- AI product managers who need to QA chat flows without digging through logs: “Show me all sessions with user
@aliceon Telegram this week — filter for ‘refund’ in messages.” - Support engineers who get “the bot isn’t responding” tickets: click into the session, hit “Replay as user”, see exactly where the LLM hallucinated or the webhook timed out.
- MLOps folks tuning prompt engineering: export CSV of last 100 Slack queries → feed into LangChain evaluator → iterate.
- Non-technical ops (yes, really): our marketing lead uses the “Scheduled Jobs” tab to pause the “weekly newsletter” job during product launches — no SSH, no YAML edits.
Hardware-wise? It’s absurdly light. Running on a 2 vCPU / 2GB RAM DigitalOcean droplet (same box as Hermes Agent & PostgreSQL), hermes-web-ui uses ~45 MB RAM and < 1% CPU idle. Even on a Raspberry Pi 4 (4GB), it starts in <3s and stays under 80 MB. The heaviest operation is session replay — and even loading 500-message WhatsApp history only spikes RAM to ~120 MB for ~2 seconds.
No GPU needed. No Node.js runtime on host. Just Docker and a working Hermes Agent API endpoint.
The Rough Edges: What’s Missing, What’s Brittle, What I’d Change
Let’s be honest: this is a young, fast-moving project — and it shows. Here’s my real-world experience after 18 days:
- No session export to PDF/Markdown: You can copy-paste, but no “Export chat” button. I hacked a quick
curlscript to dump JSON and convert withjq, but it’s not built-in. (PR #198 is open — watch it.) - Channel config lacks validation: Set Telegram’s
webhook_urltohttp://badand save — Hermes Agent rejects it on next reload, but the UI shows “Saved ✅” and no error. You only find out when messages stop flowing. I nowgrep -r "webhook_url" ./hermes-configbeforedocker-compose up -d. - Analytics are read-only: You can view model usage per channel, but can’t filter by date range or export raw data. The charts are static (last 7 days only). For compliance reporting? You’ll still need to query PostgreSQL directly.
- Mobile experience is broken: The sidebar collapses, but the main content doesn’t reflow. On iPhone Safari, you can’t scroll the session list. Use desktop. (Not a dealbreaker for me, but worth noting.)
- No audit log: Who changed the Slack webhook URL? When? No record. Hermes Agent logs it, but the UI doesn’t surface it.
Also: the docs assume you’re running Hermes Agent with PostgreSQL. If you’re using SQLite (fine for dev), the “Analytics” tab silently shows empty charts — no warning, no fallback. Took me 20 minutes to spot the SELECT * FROM usage_stats failing in the browser console.
Final Verdict: Should You Deploy It Right Now?
Yes — if you’re running Hermes Agent in anything beyond toy mode. The ROI is immediate: I saved ~6 hours/week just on session debugging and job management. The install is 5 minutes. It’s stable (zero crashes in 18 days). And the code quality? Clean TypeScript, sensible component structure, and PRs get reviewed in <24h.
Is it perfect? No. It won’t replace your SIEM or your observability stack. It won’t do RBAC or SSO. But it does one thing extremely well: give humans a real-time, contextual, actionable view into their AI agent’s live operations.
Here’s my TL;DR:
- ✅ Deploy it if you manage >1 Hermes channel or >5 scheduled jobs.
- ✅ Deploy it if non-devs need to monitor or tweak behavior.
- ❌ Hold off if you require enterprise auth (SAML, OIDC) or need audit trails for compliance.
- ⚠️ Patch the gaps: Add nginx rate-limiting on
/api/, monitorhermes-web-uihealthchecks in your uptime monitor, and keepHERMES_API_URLinternal — never expose the UI directly to the internet without auth.
The GitHub repo is active (12 commits in the last 7 days), the community is responsive (I got a config fix in <3h on Discord), and the vision is sharp: this isn’t a dashboard — it’s the control plane for the next wave of self-hosted AI agents.
So go clone it. Run docker-compose up -d. Then click into your first session and watch your ops overhead drop — not by 10%, but by 70%. That’s not hype. That’s what happened to me.
And if you’re still parsing docker logs hermes-agent | grep "session_id"? Yeah. Stop that.
Comments