hermes-hudui-consciousness-monitor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHermes HUD Web UI Skill
Hermes HUD Web UI Skill
Overview
概述
Hermes HUD Web UI is a browser-based consciousness monitor for Hermes, the AI agent with persistent memory. It provides 18 tabs covering executive dashboard, identity, memory, skills, sessions, health diagnostics, costs, model analytics, gateway control, plugin management, and live chat. The UI updates in real-time via WebSocket and reads from the same data directory as the Hermes agent.
~/.hermes/Key Features:
- Real-time monitoring of agent memory, sessions, and health
- Cost and token analytics per model
- Gateway managed-tool visibility (web search, image generation, TTS, browser automation)
- Hermes Replay: export shareable, redacted session artifacts
- 5 themes, keyboard shortcuts, command palette
- Bilingual: English and Chinese
- Companion to the TUI version; both can run simultaneously
Hermes HUD Web UI是一款基于浏览器的意识监控工具,用于监控具备持久化记忆的AI Agent——Hermes。它提供18个标签页,涵盖执行仪表板、身份信息、内存、技能、会话、健康诊断、成本、模型分析、网关控制、插件管理及实时聊天。UI通过WebSocket实现实时更新,并读取与Hermes Agent相同的数据目录。
~/.hermes/核心特性:
- 实时监控Agent内存、会话及健康状态
- 按模型统计成本与Token分析
- 网关管理工具可见性(网页搜索、图像生成、TTS、浏览器自动化)
- Hermes Replay:导出可分享的脱敏会话 artifacts
- 5种主题、键盘快捷键、命令面板
- 双语支持:英文和中文
- 与TUI版本兼容;两者可同时运行
Installation
安装
Requirements
要求
- Python 3.11+
- Node.js 18+
- A running Hermes agent with data in
~/.hermes/
- Python 3.11+
- Node.js 18+
- 运行中的Hermes Agent,且数据存储在目录中
~/.hermes/
Quick Start
快速开始
bash
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
./install.sh
hermes-huduiThe installer creates a Python virtual environment, installs dependencies, and builds the frontend. Open http://localhost:3001 after launch.
bash
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
./install.sh
hermes-hudui安装程序会创建Python虚拟环境、安装依赖并构建前端。启动后打开 http://localhost:3001。
Manual Installation
手动安装
bash
undefinedbash
undefinedClone repository
Clone repository
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
Create virtual environment
Create virtual environment
python3.11 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
python3.11 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
Install Python dependencies
Install Python dependencies
pip install -e .
pip install -e .
Install Node dependencies and build frontend
Install Node dependencies and build frontend
cd frontend
npm install
npm run build
cd ..
cd frontend
npm install
npm run build
cd ..
Launch
Launch
hermes-hudui
undefinedhermes-hudui
undefinedFuture Runs
后续运行
bash
cd hermes-hudui
source venv/bin/activate && hermes-huduibash
cd hermes-hudui
source venv/bin/activate && hermes-huduiOptional TUI Integration
可选TUI集成
If you also want the TUI version available:
bash
undefined如果同时需要TUI版本:
bash
undefinedIn zsh (quotes required)
In zsh (quotes required)
pip install 'hermes-hudui[tui]'
pip install 'hermes-hudui[tui]'
In bash/fish (quotes optional but safe)
In bash/fish (quotes optional but safe)
pip install 'hermes-hudui[tui]'
undefinedpip install 'hermes-hudui[tui]'
undefinedConfiguration
配置
Environment Variables
环境变量
bash
undefinedbash
undefinedCustom port (default: 3001)
Custom port (default: 3001)
export HERMES_HUD_PORT=8080
export HERMES_HUD_PORT=8080
Custom Hermes data directory (default: ~/.hermes/)
Custom Hermes data directory (default: ~/.hermes/)
export HERMES_DATA_DIR=/path/to/custom/hermes/data
export HERMES_DATA_DIR=/path/to/custom/hermes/data
WebSocket host (default: localhost)
WebSocket host (default: localhost)
export HERMES_WS_HOST=0.0.0.0
undefinedexport HERMES_WS_HOST=0.0.0.0
undefinedData Directory Structure
数据目录结构
Hermes HUD reads from :
~/.hermes/~/.hermes/
├── identity.json # Agent identity and configuration
├── memory/ # Persistent memory store
├── sessions/ # Session logs and history
├── skills/ # Installed skills
├── cron/ # Scheduled jobs
├── projects/ # Project tracking
├── health/ # Health metrics
└── costs/ # Usage and cost trackingHermes HUD读取目录中的数据:
~/.hermes/~/.hermes/
├── identity.json # Agent identity and configuration
├── memory/ # Persistent memory store
├── sessions/ # Session logs and history
├── skills/ # Installed skills
├── cron/ # Scheduled jobs
├── projects/ # Project tracking
├── health/ # Health metrics
└── costs/ # Usage and cost trackingReplay Export Directory
重放导出目录
Exported replay artifacts are written to:
~/.hermes-hud/replays/
├── session_abc123/
│ ├── replay.redacted.json
│ ├── replay.md
│ ├── replay.html
│ ├── share-card.png
│ └── fork.json导出的重放artifacts会写入以下目录:
~/.hermes-hud/replays/
├── session_abc123/
│ ├── replay.redacted.json
│ ├── replay.md
│ ├── replay.html
│ ├── share-card.png
│ └── fork.jsonKey Commands
关键命令
CLI
CLI
bash
undefinedbash
undefinedStart the web UI
Start the web UI
hermes-hudui
hermes-hudui
Start on custom port
Start on custom port
HERMES_HUD_PORT=8080 hermes-hudui
HERMES_HUD_PORT=8080 hermes-hudui
Point to custom Hermes data directory
Point to custom Hermes data directory
HERMES_DATA_DIR=/custom/path hermes-hudui
undefinedHERMES_DATA_DIR=/custom/path hermes-hudui
undefinedKeyboard Shortcuts (In Browser)
浏览器快捷键
| Key | Action |
|---|---|
| Switch between tabs 1-10 |
| Open theme picker |
| Open command palette |
| 按键 | 操作 |
|---|---|
| 在第1-10个标签页间切换 |
| 打开主题选择器 |
| 打开命令面板 |
Themes
主题
Five built-in themes (toggle with ):
t- Neural Awakening (cyan) — default
- Hermes Teal (official Nous palette)
- Blade Runner (amber)
- fsociety (green)
- Anime (purple)
Optional CRT scanlines available in theme settings.
内置5种主题(按键切换):
t- Neural Awakening(青色)——默认主题
- Hermes Teal(官方Nous配色)
- Blade Runner(琥珀色)
- fsociety(绿色)
- Anime(紫色)
主题设置中可选择是否启用CRT扫描线效果。
Language Toggle
语言切换
Click the language icon in the top-right header to switch between English and Chinese. Persists to localStorage. When Chinese is selected, chat responses from your agent also come back in Chinese.
点击右上角头部的语言图标可在英文和中文间切换,设置会保存到localStorage。选择中文后,Agent的聊天回复也会以中文返回。
Core Functionality
核心功能
Accessing the Dashboard
访问仪表板
After starting , navigate to http://localhost:3001 in your browser. The executive dashboard loads first, showing:
hermes-hudui- Agent health status
- Spend pulse (recent costs)
- Top model by usage
- Provider/gateway risk
- Highest-cost session
- Action items
启动后,在浏览器中访问http://localhost:3001。首先加载的是执行仪表板,显示:
hermes-hudui- Agent健康状态
- 支出动态(近期成本)
- 使用量最高的模型
- 提供商/网关风险
- 成本最高的会话
- 待办事项
Real-Time Updates
实时更新
The UI uses WebSocket for live updates. Health reacts to filesystem changes in and WebSocket messages. Expensive refresh paths (e.g., full memory scans) are throttled.
~/.hermes/UI通过WebSocket实现实时更新。健康状态会响应目录中的文件系统变化及WebSocket消息。资源消耗较高的刷新路径(如完整内存扫描)会被限流。
~/.hermes/Gateway Managed Tools
网关管理工具
The Gateway tab shows routing for:
- Web search
- Image generation
- Text-to-speech
- Browser automation
Each tool displays one of three states:
- Gateway: routed through Nous Tool Gateway
- Direct Key: using your own API key
- Unavailable: not configured
网关标签页显示以下工具的路由情况:
- 网页搜索
- 图像生成
- 文本转语音(TTS)
- 浏览器自动化
每个工具会显示三种状态之一:
- Gateway:通过Nous Tool Gateway路由
- Direct Key:使用您自己的API密钥
- Unavailable:未配置
Plugin Hub
插件中心
The Plugins tab shows:
- Installed dashboard and agent plugins
- Extension entry points
- Runtime status
- Required auth commands
- Enable/disable/update actions (two-click safety)
插件标签页显示:
- 已安装的仪表板和Agent插件
- 扩展入口点
- 运行时状态
- 所需的认证命令
- 启用/禁用/更新操作(双击确认安全机制)
Hermes Replay
Hermes Replay
Purpose: Turn agent runs into redacted, shareable proof artifacts.
Workflow:
- Open the Replay tab
- Select a Hermes session from the list
- Inspect the normalized timeline
- Review the run receipt
- Export artifacts (local files, no upload by default)
Export Formats:
- Redacted JSON ()
replay.redacted.json - GitHub-ready Markdown ()
replay.md - Standalone HTML ()
replay.html - PNG share card 1200×630 ()
share-card.png - Fork-safe metadata ()
fork.json
Safe Share Mode (default):
- Redacts raw tool arguments
- Strips terminal output
- Removes assistant reasoning
- Masks tokens, emails, local paths
- Includes local hashes and Ed25519 signatures for integrity
Example redacted payload:
assets/example-replay.redacted.json用途: 将Agent运行记录转换为脱敏的、可分享的证明artifacts。
流程:
- 打开Replay标签页
- 从列表中选择一个Hermes会话
- 查看标准化时间线
- 审核运行记录
- 导出artifacts(默认保存到本地文件,不上传)
导出格式:
- 脱敏JSON()
replay.redacted.json - 适用于GitHub的Markdown()
replay.md - 独立HTML()
replay.html - PNG分享卡片(1200×630,)
share-card.png - 可用于复刻的元数据()
fork.json
安全分享模式(默认):
- 脱敏原始工具参数
- 移除终端输出
- 删除助手推理过程
- 掩码Token、邮箱、本地路径
- 包含本地哈希和Ed25519签名以保证完整性
示例脱敏载荷:
assets/example-replay.redacted.jsonCode Examples
代码示例
Python: Extending the Backend
Python:扩展后端
Add a custom WebSocket event handler:
python
undefined添加自定义WebSocket事件处理器:
python
undefinedserver/handlers/custom_handler.py
server/handlers/custom_handler.py
from server.websocket import send_message
async def handle_custom_event(websocket, data):
"""
Custom event handler for new dashboard features.
"""
event_type = data.get("type")
if event_type == "request_custom_metric":
metric_data = compute_custom_metric()
await send_message(websocket, {
"type": "custom_metric",
"payload": metric_data
})def compute_custom_metric():
# Read from ~/.hermes/ or compute live data
return {
"metric_name": "agent_velocity",
"value": 42,
"timestamp": "2026-05-16T18:00:00Z"
}
Register the handler in `server/websocket.py`:
```python
from server.handlers.custom_handler import handle_custom_event
async def handle_message(websocket, message):
data = json.loads(message)
if data["type"] == "request_custom_metric":
await handle_custom_event(websocket, data)
# ... existing handlersfrom server.websocket import send_message
async def handle_custom_event(websocket, data):
"""
Custom event handler for new dashboard features.
"""
event_type = data.get("type")
if event_type == "request_custom_metric":
metric_data = compute_custom_metric()
await send_message(websocket, {
"type": "custom_metric",
"payload": metric_data
})def compute_custom_metric():
# Read from ~/.hermes/ or compute live data
return {
"metric_name": "agent_velocity",
"value": 42,
"timestamp": "2026-05-16T18:00:00Z"
}
在`server/websocket.py`中注册处理器:
```python
from server.handlers.custom_handler import handle_custom_event
async def handle_message(websocket, message):
data = json.loads(message)
if data["type"] == "request_custom_metric":
await handle_custom_event(websocket, data)
# ... existing handlersPython: Reading Hermes Data
Python:读取Hermes数据
Access agent identity and memory:
python
import json
from pathlib import Path
def load_hermes_identity():
"""Load agent identity from ~/.hermes/identity.json"""
hermes_dir = Path.home() / ".hermes"
identity_path = hermes_dir / "identity.json"
if identity_path.exists():
with open(identity_path, "r") as f:
return json.load(f)
return None
def get_recent_sessions(limit=10):
"""Get most recent session logs"""
sessions_dir = Path.home() / ".hermes" / "sessions"
if not sessions_dir.exists():
return []
session_files = sorted(
sessions_dir.glob("*.json"),
key=lambda p: p.stat().st_mtime,
reverse=True
)
sessions = []
for session_file in session_files[:limit]:
with open(session_file, "r") as f:
sessions.append(json.load(f))
return sessions访问Agent身份信息和内存:
python
import json
from pathlib import Path
def load_hermes_identity():
"""Load agent identity from ~/.hermes/identity.json"""
hermes_dir = Path.home() / ".hermes"
identity_path = hermes_dir / "identity.json"
if identity_path.exists():
with open(identity_path, "r") as f:
return json.load(f)
return None
def get_recent_sessions(limit=10):
"""Get most recent session logs"""
sessions_dir = Path.home() / ".hermes" / "sessions"
if not sessions_dir.exists():
return []
session_files = sorted(
sessions_dir.glob("*.json"),
key=lambda p: p.stat().st_mtime,
reverse=True
)
sessions = []
for session_file in session_files[:limit]:
with open(session_file, "r") as f:
sessions.append(json.load(f))
return sessionsJavaScript: Custom Dashboard Widget
JavaScript:自定义仪表板组件
Add a new chart to the frontend:
javascript
// frontend/src/components/CustomMetricWidget.jsx
import React, { useEffect, useState } from 'react';
import { useWebSocket } from '../hooks/useWebSocket';
export function CustomMetricWidget() {
const [metricData, setMetricData] = useState(null);
const { sendMessage, onMessage } = useWebSocket();
useEffect(() => {
// Request custom metric from backend
sendMessage({ type: 'request_custom_metric' });
// Listen for response
const unsubscribe = onMessage((data) => {
if (data.type === 'custom_metric') {
setMetricData(data.payload);
}
});
return unsubscribe;
}, []);
if (!metricData) return <div>Loading...</div>;
return (
<div className="metric-widget">
<h3>{metricData.metric_name}</h3>
<div className="metric-value">{metricData.value}</div>
<div className="metric-timestamp">{metricData.timestamp}</div>
</div>
);
}向前端添加新图表:
javascript
// frontend/src/components/CustomMetricWidget.jsx
import React, { useEffect, useState } from 'react';
import { useWebSocket } from '../hooks/useWebSocket';
export function CustomMetricWidget() {
const [metricData, setMetricData] = useState(null);
const { sendMessage, onMessage } = useWebSocket();
useEffect(() => {
// Request custom metric from backend
sendMessage({ type: 'request_custom_metric' });
// Listen for response
const unsubscribe = onMessage((data) => {
if (data.type === 'custom_metric') {
setMetricData(data.payload);
}
});
return unsubscribe;
}, []);
if (!metricData) return <div>Loading...</div>;
return (
<div className="metric-widget">
<h3>{metricData.metric_name}</h3>
<div className="metric-value">{metricData.value}</div>
<div className="metric-timestamp">{metricData.timestamp}</div>
</div>
);
}Python: Replay Export Customization
Python:自定义重放导出器
Create a custom replay exporter:
python
undefined创建自定义重放导出器:
python
undefinedserver/replay/custom_exporter.py
server/replay/custom_exporter.py
import json
from pathlib import Path
from datetime import datetime
class CustomReplayExporter:
def init(self, session_id, replay_data):
self.session_id = session_id
self.replay_data = replay_data
self.output_dir = Path.home() / ".hermes-hud" / "replays" / session_id
self.output_dir.mkdir(parents=True, exist_ok=True)
def export_json(self):
"""Export custom JSON format"""
output_path = self.output_dir / "custom-export.json"
custom_format = {
"version": "1.0",
"session_id": self.session_id,
"exported_at": datetime.utcnow().isoformat(),
"timeline": self.replay_data.get("timeline", []),
"metadata": self.replay_data.get("metadata", {})
}
with open(output_path, "w") as f:
json.dump(custom_format, f, indent=2)
return output_path
def export_csv(self):
"""Export timeline as CSV"""
import csv
output_path = self.output_dir / "timeline.csv"
timeline = self.replay_data.get("timeline", [])
if not timeline:
return None
with open(output_path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=timeline[0].keys())
writer.writeheader()
writer.writerows(timeline)
return output_pathundefinedimport json
from pathlib import Path
from datetime import datetime
class CustomReplayExporter:
def init(self, session_id, replay_data):
self.session_id = session_id
self.replay_data = replay_data
self.output_dir = Path.home() / ".hermes-hud" / "replays" / session_id
self.output_dir.mkdir(parents=True, exist_ok=True)
def export_json(self):
"""Export custom JSON format"""
output_path = self.output_dir / "custom-export.json"
custom_format = {
"version": "1.0",
"session_id": self.session_id,
"exported_at": datetime.utcnow().isoformat(),
"timeline": self.replay_data.get("timeline", []),
"metadata": self.replay_data.get("metadata", {})
}
with open(output_path, "w") as f:
json.dump(custom_format, f, indent=2)
return output_path
def export_csv(self):
"""Export timeline as CSV"""
import csv
output_path = self.output_dir / "timeline.csv"
timeline = self.replay_data.get("timeline", [])
if not timeline:
return None
with open(output_path, "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=timeline[0].keys())
writer.writeheader()
writer.writerows(timeline)
return output_pathundefinedCommon Patterns
常见模式
Monitoring Agent Health
监控Agent健康状态
python
from pathlib import Path
import json
def check_agent_health():
"""Check Hermes agent health status"""
health_file = Path.home() / ".hermes" / "health" / "status.json"
if not health_file.exists():
return {"status": "unknown", "message": "Health file not found"}
with open(health_file, "r") as f:
health_data = json.load(f)
return {
"status": health_data.get("status"),
"last_check": health_data.get("timestamp"),
"issues": health_data.get("issues", [])
}python
from pathlib import Path
import json
def check_agent_health():
"""Check Hermes agent health status"""
health_file = Path.home() / ".hermes" / "health" / "status.json"
if not health_file.exists():
return {"status": "unknown", "message": "Health file not found"}
with open(health_file, "r") as f:
health_data = json.load(f)
return {
"status": health_data.get("status"),
"last_check": health_data.get("timestamp"),
"issues": health_data.get("issues", [])
}Accessing Cost Analytics
访问成本分析数据
python
def get_cost_summary(model_name=None):
"""Get cost analytics, optionally filtered by model"""
costs_dir = Path.home() / ".hermes" / "costs"
if not costs_dir.exists():
return {"total": 0, "by_model": {}}
total_cost = 0
by_model = {}
for cost_file in costs_dir.glob("*.json"):
with open(cost_file, "r") as f:
data = json.load(f)
model = data.get("model")
cost = data.get("cost", 0)
if model_name and model != model_name:
continue
total_cost += cost
by_model[model] = by_model.get(model, 0) + cost
return {
"total": total_cost,
"by_model": by_model
}python
def get_cost_summary(model_name=None):
"""Get cost analytics, optionally filtered by model"""
costs_dir = Path.home() / ".hermes" / "costs"
if not costs_dir.exists():
return {"total": 0, "by_model": {}}
total_cost = 0
by_model = {}
for cost_file in costs_dir.glob("*.json"):
with open(cost_file, "r") as f:
data = json.load(f)
model = data.get("model")
cost = data.get("cost", 0)
if model_name and model != model_name:
continue
total_cost += cost
by_model[model] = by_model.get(model, 0) + cost
return {
"total": total_cost,
"by_model": by_model
}WebSocket Real-Time Updates
WebSocket实时更新
javascript
// frontend/src/hooks/useAgentHealth.js
import { useEffect, useState } from 'react';
import { useWebSocket } from './useWebSocket';
export function useAgentHealth() {
const [health, setHealth] = useState(null);
const { sendMessage, onMessage } = useWebSocket();
useEffect(() => {
// Request initial health status
sendMessage({ type: 'request_health' });
// Subscribe to health updates
const unsubscribe = onMessage((data) => {
if (data.type === 'health_update') {
setHealth(data.payload);
}
});
// Refresh every 30 seconds
const interval = setInterval(() => {
sendMessage({ type: 'request_health' });
}, 30000);
return () => {
unsubscribe();
clearInterval(interval);
};
}, []);
return health;
}javascript
// frontend/src/hooks/useAgentHealth.js
import { useEffect, useState } from 'react';
import { useWebSocket } from './useWebSocket';
export function useAgentHealth() {
const [health, setHealth] = useState(null);
const { sendMessage, onMessage } = useWebSocket();
useEffect(() => {
// Request initial health status
sendMessage({ type: 'request_health' });
// Subscribe to health updates
const unsubscribe = onMessage((data) => {
if (data.type === 'health_update') {
setHealth(data.payload);
}
});
// Refresh every 30 seconds
const interval = setInterval(() => {
sendMessage({ type: 'request_health' });
}, 30000);
return () => {
unsubscribe();
clearInterval(interval);
};
}, []);
return health;
}Troubleshooting
故障排查
Port Already in Use
端口已被占用
bash
undefinedbash
undefinedError: Address already in use
Error: Address already in use
Solution: Use a different port
Solution: Use a different port
HERMES_HUD_PORT=8080 hermes-hudui
undefinedHERMES_HUD_PORT=8080 hermes-hudui
undefinedWebSocket Connection Failed
WebSocket连接失败
Symptom: Dashboard loads but shows "disconnected" status, no real-time updates.
Causes:
- Backend not running
- Firewall blocking WebSocket
- Port mismatch between frontend and backend
Solution:
bash
undefined症状: 仪表板加载成功但显示“已断开连接”状态,无实时更新。
原因:
- 后端未运行
- 防火墙阻止WebSocket连接
- 前端与后端端口不匹配
解决方案:
bash
undefinedVerify backend is running
Verify backend is running
ps aux | grep hermes-hudui
ps aux | grep hermes-hudui
Check logs for WebSocket errors
Check logs for WebSocket errors
tail -f ~/.hermes-hud/logs/server.log
tail -f ~/.hermes-hud/logs/server.log
Ensure frontend points to correct WebSocket URL
Ensure frontend points to correct WebSocket URL
Check frontend/.env or frontend/src/config.js
Check frontend/.env or frontend/src/config.js
undefinedundefinedMissing Hermes Data Directory
缺少Hermes数据目录
Symptom: Dashboard shows "No data found" or empty tabs.
Cause: Hermes agent hasn't run yet or data is in non-standard location.
Solution:
bash
undefined症状: 仪表板显示“未找到数据”或标签页为空。
原因: Hermes Agent尚未运行,或数据存储在非标准位置。
解决方案:
bash
undefinedVerify Hermes data exists
Verify Hermes data exists
ls -la ~/.hermes/
ls -la ~/.hermes/
If data is elsewhere, set environment variable
If data is elsewhere, set environment variable
HERMES_DATA_DIR=/path/to/hermes/data hermes-hudui
undefinedHERMES_DATA_DIR=/path/to/hermes/data hermes-hudui
undefinedReplay Export Fails
重放导出失败
Symptom: Export button doesn't create files or throws permission error.
Cause: Insufficient permissions on directory.
~/.hermes-hud/replays/Solution:
bash
undefined症状: 导出按钮未创建文件或抛出权限错误。
原因: 目录权限不足。
~/.hermes-hud/replays/解决方案:
bash
undefinedCreate directory with correct permissions
Create directory with correct permissions
mkdir -p ~/.hermes-hud/replays
chmod 755 ~/.hermes-hud/replays
mkdir -p ~/.hermes-hud/replays
chmod 755 ~/.hermes-hud/replays
Check disk space
Check disk space
df -h ~
undefineddf -h ~
undefinedFrontend Build Errors
前端构建错误
Symptom: fails during .
./install.shnpm run buildCause: Node.js version < 18 or missing dependencies.
Solution:
bash
undefined症状: 在执行时失败。
./install.shnpm run build原因: Node.js版本低于18或缺少依赖。
解决方案:
bash
undefinedCheck Node.js version
Check Node.js version
node --version # Should be 18+
node --version # Should be 18+
Update Node.js (via nvm)
Update Node.js (via nvm)
nvm install 18
nvm use 18
nvm install 18
nvm use 18
Clean install
Clean install
cd frontend
rm -rf node_modules package-lock.json
npm install
npm run build
undefinedcd frontend
rm -rf node_modules package-lock.json
npm install
npm run build
undefinedTheme Not Persisting
主题未持久化
Symptom: Theme resets to default on page reload.
Cause: localStorage disabled or browser privacy mode.
Solution:
- Disable private/incognito mode
- Check browser console for localStorage errors
- Verify site isn't blocked in browser settings
症状: 页面刷新后主题重置为默认。
原因: localStorage被禁用或浏览器处于隐私模式。
解决方案:
- 关闭隐私/无痕模式
- 检查浏览器控制台是否有localStorage错误
- 验证浏览器设置未阻止该站点
Gateway Tools Show "Unavailable"
网关工具显示“不可用”
Symptom: All gateway-managed tools show unavailable status.
Cause: Hermes agent not configured with gateway credentials or direct API keys.
Solution:
bash
undefined症状: 所有网关管理工具显示不可用状态。
原因: Hermes Agent未配置网关凭证或直接API密钥。
解决方案:
bash
undefinedConfigure Nous Tool Gateway (if using gateway)
Configure Nous Tool Gateway (if using gateway)
In Hermes agent config (~/.hermes/config.json):
In Hermes agent config (~/.hermes/config.json):
{
"gateway": {
"enabled": true,
"api_key": "${NOUS_GATEWAY_API_KEY}"
}
}
{
"gateway": {
"enabled": true,
"api_key": "${NOUS_GATEWAY_API_KEY}"
}
}
Or configure direct API keys
Or configure direct API keys
{
"providers": {
"openai": {
"api_key": "${OPENAI_API_KEY}"
},
"anthropic": {
"api_key": "${ANTHROPIC_API_KEY}"
}
}
}
{
"providers": {
"openai": {
"api_key": "${OPENAI_API_KEY}"
},
"anthropic": {
"api_key": "${ANTHROPIC_API_KEY}"
}
}
}
Restart Hermes agent and HUD
Restart Hermes agent and HUD
undefinedundefinedPlatform Support
平台支持
- macOS: Full support
- Linux: Full support
- Windows: Use WSL (Windows Subsystem for Linux)
- macOS:完全支持
- Linux:完全支持
- Windows:使用WSL(Windows Subsystem for Linux)
Related Resources
相关资源
- Hermes Agent — The AI agent Hermes HUD monitors
- Hermes HUD TUI — Terminal UI companion
- Example Redacted Replay — Sample export artifact
- Hermes Agent — Hermes HUD监控的AI Agent
- Hermes HUD TUI — 终端UI配套工具
- Example Redacted Replay — 示例导出artifact