hermes-web-ui-dashboard
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHermes Web UI Dashboard
Hermes Web UI Dashboard
Skill by ara.so — Hermes Skills collection.
Hermes Web UI is a full-featured web dashboard for Hermes Agent. It provides AI chat session management, usage analytics, platform channel configuration (Telegram, Discord, Slack, WhatsApp, Matrix, Feishu, WeChat, WeCom), scheduled cron jobs, model management, file browsing, multi-profile support, and gateway control through a responsive Vue 3 interface.
由ara.so提供的Skill——Hermes Skills合集。
Hermes Web UI 是一款功能完备的Web控制面板,专为Hermes Agent打造。它通过响应式Vue 3界面,提供AI聊天会话管理、使用数据分析、平台渠道配置(Telegram、Discord、Slack、WhatsApp、Matrix、飞书、微信、企业微信)、定时Cron任务、模型管理、文件浏览、多配置文件支持以及网关控制功能。
Installation
安装方式
Global npm Installation (Recommended)
全局npm安装(推荐)
bash
npm install -g hermes-web-ui
hermes-web-ui startAccess at http://localhost:8648
bash
npm install -g hermes-web-ui
hermes-web-ui startDocker Compose
Docker Compose部署
bash
undefinedbash
undefinedUsing pre-built image
使用预构建镜像
WEBUI_IMAGE=ekkoye8888/hermes-web-ui docker compose up -d
WEBUI_IMAGE=ekkoye8888/hermes-web-ui docker compose up -d
Or build from source
或从源码构建
docker compose up -d --build
docker compose up -d --build
View logs
查看日志
docker compose logs -f hermes-webui
Access at **http://localhost:6060**docker compose logs -f hermes-webui
访问地址:**http://localhost:6060**Auto-Setup Script (Linux/macOS)
自动安装脚本(Linux/macOS)
bash
bash <(curl -fsSL https://raw.githubusercontent.com/EKKOLearnAI/hermes-web-ui/main/scripts/setup.sh)bash
bash <(curl -fsSL https://raw.githubusercontent.com/EKKOLearnAI/hermes-web-ui/main/scripts/setup.sh)Development Setup
开发环境搭建
bash
git clone https://github.com/EKKOLearnAI/hermes-web-ui.git
cd hermes-web-ui
npm install
npm run dev- Frontend dev server: http://localhost:5173
- BFF server: http://localhost:8648
bash
git clone https://github.com/EKKOLearnAI/hermes-web-ui.git
cd hermes-web-ui
npm install
npm run dev- 前端开发服务器:http://localhost:5173
- BFF服务器:http://localhost:8648
CLI Commands
CLI命令
bash
undefinedbash
undefinedStart in background (daemon mode)
后台启动(守护进程模式)
hermes-web-ui start
hermes-web-ui start
Start on custom port
自定义端口启动
hermes-web-ui start --port 9000
hermes-web-ui start --port 9000
Stop background process
停止后台进程
hermes-web-ui stop
hermes-web-ui stop
Restart
重启服务
hermes-web-ui restart
hermes-web-ui restart
Check running status
查看运行状态
hermes-web-ui status
hermes-web-ui status
Update to latest version and restart
更新至最新版本并重启
hermes-web-ui update
hermes-web-ui update
or
或
hermes-web-ui upgrade
hermes-web-ui upgrade
Show version
查看版本
hermes-web-ui -v
hermes-web-ui -v
Show help
查看帮助
hermes-web-ui -h
undefinedhermes-web-ui -h
undefinedEnvironment Variables
环境变量配置
Configure the Web UI server (not Hermes Agent itself):
bash
undefined配置Web UI服务器(非Hermes Agent本身):
bash
undefinedWeb UI listen port
Web UI监听端口
export PORT=8648
export PORT=8648
Bind host (use :: for IPv6)
绑定主机(使用::支持IPv6)
export BIND_HOST=0.0.0.0
export BIND_HOST=0.0.0.0
Web UI data directory (auth token, logs, DB)
Web UI数据目录(包含认证令牌、日志、数据库)
export HERMES_WEB_UI_HOME=~/.hermes-web-ui
export HERMES_WEB_UI_HOME=~/.hermes-web-ui
Upload directory override
上传目录自定义
export UPLOAD_DIR=$HERMES_WEB_UI_HOME/upload
export UPLOAD_DIR=$HERMES_WEB_UI_HOME/upload
CORS origins
CORS允许来源
export CORS_ORIGINS=*
export CORS_ORIGINS=*
Disable authentication
禁用认证
export AUTH_DISABLED=1
export AUTH_DISABLED=1
Explicit bearer token (auto-generated if unset)
显式设置Bearer令牌(未设置则自动生成)
export AUTH_TOKEN=your-secret-token
export AUTH_TOKEN=your-secret-token
Initial Hermes profile
初始Hermes配置文件
export PROFILE=default
export PROFILE=default
Server log level
服务器日志级别
export LOG_LEVEL=info
export LOG_LEVEL=info
Bridge log level
桥接服务日志级别
export BRIDGE_LOG_LEVEL=info
export BRIDGE_LOG_LEVEL=info
File size limits
文件大小限制
export MAX_DOWNLOAD_SIZE=200MB
export MAX_EDIT_SIZE=10MB
export MAX_DOWNLOAD_SIZE=200MB
export MAX_EDIT_SIZE=10MB
Workspace base directory
工作区基础目录
export WORKSPACE_BASE=/opt/data/workspace
export WORKSPACE_BASE=/opt/data/workspace
Gateway host for profile config
配置文件对应的网关主机
export GATEWAY_HOST=127.0.0.1
export GATEWAY_HOST=127.0.0.1
Stop gateways on shutdown
关闭服务时停止网关
export HERMES_WEB_UI_STOP_GATEWAYS_ON_SHUTDOWN=true
undefinedexport HERMES_WEB_UI_STOP_GATEWAYS_ON_SHUTDOWN=true
undefinedDocker Environment Configuration
Docker环境配置
In :
docker-compose.ymlyaml
services:
hermes-webui:
image: ekkoye8888/hermes-web-ui:latest
container_name: hermes-webui
ports:
- "6060:8648"
environment:
- PORT=8648
- BIND_HOST=0.0.0.0
- HERMES_WEB_UI_HOME=/app/data/hermes-web-ui
- AUTH_DISABLED=0
- PROFILE=default
- LOG_LEVEL=info
- MAX_DOWNLOAD_SIZE=200MB
- WORKSPACE_BASE=/app/data/workspace
volumes:
- ./hermes_data:/app/data
restart: unless-stopped在中配置:
docker-compose.ymlyaml
services:
hermes-webui:
image: ekkoye8888/hermes-web-ui:latest
container_name: hermes-webui
ports:
- "6060:8648"
environment:
- PORT=8648
- BIND_HOST=0.0.0.0
- HERMES_WEB_UI_HOME=/app/data/hermes-web-ui
- AUTH_DISABLED=0
- PROFILE=default
- LOG_LEVEL=info
- MAX_DOWNLOAD_SIZE=200MB
- WORKSPACE_BASE=/app/data/workspace
volumes:
- ./hermes_data:/app/data
restart: unless-stoppedArchitecture
架构说明
Browser → BFF Server (Koa :8648) → Hermes Gateway (:8642)
↓
Hermes CLI (sessions, logs)
↓
~/.hermes/config.yaml (channel behavior)
~/.hermes/auth.json (credentials)
~/.hermes-web-ui/ (Web UI data)BFF Layer Responsibilities:
- API proxy with path rewriting
- SSE streaming from Hermes Gateway
- File upload/download (local, Docker, SSH, Singularity backends)
- Session CRUD via Hermes CLI
- Config and credential management
- WeChat QR login via Tencent iLink API
- Model discovery from credential pool
- Skills and memory management
- Log reading and parsing
Frontend: Vue 3 + TypeScript + Vite + Naive UI + Pinia + Vue Router
浏览器 → BFF服务器(Koa :8648) → Hermes网关(:8642)
↓
Hermes CLI(会话、日志)
↓
~/.hermes/config.yaml (渠道行为配置)
~/.hermes/auth.json (凭证信息)
~/.hermes-web-ui/ (Web UI数据)BFF层职责:
- 带路径重写的API代理
- 从Hermes网关获取SSE流
- 文件上传/下载(本地、Docker、SSH、Singularity后端)
- 通过Hermes CLI实现会话增删改查
- 配置与凭证管理
- 通过腾讯iLink API实现微信扫码登录
- 从凭证池自动发现模型
- Skill与内存管理
- 日志读取与解析
前端技术栈: Vue 3 + TypeScript + Vite + Naive UI + Pinia + Vue Router
Key Features & Usage
核心功能与使用说明
AI Chat Sessions
AI聊天会话
The Web UI maintains its own SQLite session database separate from Hermes' :
state.dbtypescript
// Create new chat session via Socket.IO
import { io } from 'socket.io-client';
const socket = io('http://localhost:8648');
socket.emit('chat-run', {
sessionId: 'session-123',
message: 'Hello, Hermes!',
model: 'gpt-4',
profile: 'default'
});
socket.on('chat-delta', (data) => {
console.log('Streaming chunk:', data.content);
});
socket.on('chat-done', (data) => {
console.log('Response complete:', data);
});Session Management:
- Sessions grouped by source (Telegram, Discord, Slack, etc.)
- Active sessions pinned to top with spinner
- Sessions sorted by latest message time
- Markdown rendering with syntax highlighting
- Tool call expansion (arguments/result)
- File upload and download support
- Ctrl+K global search across sessions
- Per-session model badge and token usage display
Web UI维护独立于Hermes 的SQLite会话数据库:
state.dbtypescript
// 通过Socket.IO创建新聊天会话
import { io } from 'socket.io-client';
const socket = io('http://localhost:8648');
socket.emit('chat-run', {
sessionId: 'session-123',
message: 'Hello, Hermes!',
model: 'gpt-4',
profile: 'default'
});
socket.on('chat-delta', (data) => {
console.log('流式响应片段:', data.content);
});
socket.on('chat-done', (data) => {
console.log('响应完成:', data);
});会话管理特性:
- 按来源(Telegram、Discord、Slack等)分组会话
- 活跃会话置顶并显示加载动画
- 按最新消息时间排序会话
- 支持语法高亮的Markdown渲染
- 工具调用展开(参数/结果)
- 文件上传与下载支持
- Ctrl+K全局会话搜索
- 单会话模型标识与令牌用量显示
Platform Channel Configuration
平台渠道配置
Configure 8 platforms from a unified interface. Settings write to:
- Credentials →
~/.hermes/.env - Behavior →
~/.hermes/config.yaml
Example Telegram Configuration:
yaml
undefined通过统一界面配置8种平台,设置内容将写入:
- 凭证信息 →
~/.hermes/.env - 行为配置 →
~/.hermes/config.yaml
Telegram配置示例:
yaml
undefined~/.hermes/config.yaml
~/.hermes/config.yaml
telegram:
mention_control: true
reactions_enabled: true
free_response_chats:
- -1001234567890
```bashtelegram:
mention_control: true
reactions_enabled: true
free_response_chats:
- -1001234567890
```bash~/.hermes/.env
~/.hermes/.env
TELEGRAM_BOT_TOKEN=your_bot_token_here
**Supported Platforms:**
- **Telegram:** Bot token, mention control, reactions, free-response chats
- **Discord:** Bot token, mention, auto-thread, reactions, channel allow/ignore
- **Slack:** Bot token, mention control, bot message handling
- **WhatsApp:** Enable/disable, mention control, mention patterns
- **Matrix:** Access token, homeserver, auto-thread, DM mention threads
- **Feishu (Lark):** App ID/Secret, mention control
- **WeChat:** QR code login (scan in browser)
- **WeCom:** Bot ID/Secret
The Web UI auto-restarts the gateway on config changes.TELEGRAM_BOT_TOKEN=your_bot_token_here
**支持的平台:**
- **Telegram:** Bot令牌、提及控制、消息反应、自由响应聊天组
- **Discord:** Bot令牌、提及要求、自动线程、消息反应、渠道允许/忽略列表
- **Slack:** Bot令牌、提及控制、机器人消息处理
- **WhatsApp:** 启用/禁用、提及控制、提及规则
- **Matrix:** 访问令牌、主服务器、自动线程、私信提及线程
- **飞书(Lark):** App ID/密钥、提及控制
- **微信:** 浏览器扫码登录
- **企业微信:** Bot ID/密钥
Web UI会在配置变更后自动重启网关。Model Management
模型管理
Models are auto-discovered from credential pool:
~/.hermes/auth.jsonjson
{
"providers": [
{
"name": "openai",
"type": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "${OPENAI_API_KEY}",
"models": ["gpt-4", "gpt-3.5-turbo"]
},
{
"name": "anthropic",
"type": "anthropic",
"base_url": "https://api.anthropic.com/v1",
"api_key": "${ANTHROPIC_API_KEY}",
"models": ["claude-3-opus-20240229"]
}
]
}Model Discovery API:
bash
undefined模型从凭证池中自动发现:
~/.hermes/auth.jsonjson
{
"providers": [
{
"name": "openai",
"type": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "${OPENAI_API_KEY}",
"models": ["gpt-4", "gpt-3.5-turbo"]
},
{
"name": "anthropic",
"type": "anthropic",
"base_url": "https://api.anthropic.com/v1",
"api_key": "${ANTHROPIC_API_KEY}",
"models": ["claude-3-opus-20240229"]
}
]
}模型发现API:
bash
undefinedFetch available models from provider
获取服务商可用模型
**Add Custom Provider:**
```typescript
// POST /api/models/providers
const response = await fetch('http://localhost:8648/api/models/providers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-auth-token'
},
body: JSON.stringify({
name: 'custom-llm',
type: 'openai-compatible',
base_url: 'https://api.custom-llm.com/v1',
api_key: process.env.CUSTOM_LLM_KEY,
models: ['custom-model-7b']
})
});
**添加自定义服务商:**
```typescript
// POST /api/models/providers
const response = await fetch('http://localhost:8648/api/models/providers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-auth-token'
},
body: JSON.stringify({
name: 'custom-llm',
type: 'openai-compatible',
base_url: 'https://api.custom-llm.com/v1',
api_key: process.env.CUSTOM_LLM_KEY,
models: ['custom-model-7b']
})
});Usage Analytics
使用数据分析
View token usage, session counts, estimated costs, and 30-day trends:
bash
undefined查看令牌用量、会话数量、预估成本及30天趋势:
bash
undefinedGet usage analytics
获取使用分析数据
**Response:**
```json
{
"totalTokens": 1500000,
"inputTokens": 800000,
"outputTokens": 700000,
"sessionCount": 245,
"dailyAverage": 8.2,
"estimatedCost": 12.45,
"cacheHitRate": 0.35,
"modelDistribution": {
"gpt-4": 60,
"claude-3-opus": 30,
"gpt-3.5-turbo": 10
},
"dailyTrend": [
{ "date": "2026-05-01", "tokens": 50000, "cost": 0.42 },
{ "date": "2026-05-02", "tokens": 48000, "cost": 0.38 }
]
}
**响应示例:**
```json
{
"totalTokens": 1500000,
"inputTokens": 800000,
"outputTokens": 700000,
"sessionCount": 245,
"dailyAverage": 8.2,
"estimatedCost": 12.45,
"cacheHitRate": 0.35,
"modelDistribution": {
"gpt-4": 60,
"claude-3-opus": 30,
"gpt-3.5-turbo": 10
},
"dailyTrend": [
{ "date": "2026-05-01", "tokens": 50000, "cost": 0.42 },
{ "date": "2026-05-02", "tokens": 48000, "cost": 0.38 }
]
}Scheduled Jobs (Cron)
定时任务(Cron)
Create and manage cron jobs for recurring tasks:
typescript
// POST /api/cron/jobs
const job = await fetch('http://localhost:8648/api/cron/jobs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
body: JSON.stringify({
name: 'Daily Report',
schedule: '0 9 * * *', // 9 AM daily
command: 'hermes agent run --prompt "Generate daily summary"',
enabled: true
})
});Cron Presets:
- Every hour:
0 * * * * - Daily at 9 AM:
0 9 * * * - Weekly Monday 9 AM:
0 9 * * 1 - Monthly 1st 9 AM:
0 9 1 * *
Job Operations:
bash
undefined创建并管理用于重复任务的Cron作业:
typescript
// POST /api/cron/jobs
const job = await fetch('http://localhost:8648/api/cron/jobs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
body: JSON.stringify({
name: '每日报告',
schedule: '0 9 * * *', // 每日上午9点
command: 'hermes agent run --prompt "Generate daily summary"',
enabled: true
})
});Cron预设规则:
- 每小时执行:
0 * * * * - 每日上午9点:
0 9 * * * - 每周一上午9点:
0 9 * * 1 - 每月1日上午9点:
0 9 1 * *
作业操作命令:
bash
undefinedList all jobs
列出所有作业
GET /api/cron/jobs
GET /api/cron/jobs
Pause job
暂停作业
PATCH /api/cron/jobs/:id/pause
PATCH /api/cron/jobs/:id/pause
Resume job
恢复作业
PATCH /api/cron/jobs/:id/resume
PATCH /api/cron/jobs/:id/resume
Trigger immediate execution
立即触发执行
POST /api/cron/jobs/:id/trigger
POST /api/cron/jobs/:id/trigger
Delete job
删除作业
DELETE /api/cron/jobs/:id
undefinedDELETE /api/cron/jobs/:id
undefinedMulti-Profile Management
多配置文件管理
Create isolated Hermes profiles with separate configs and caches:
typescript
// POST /api/profiles
const profile = await fetch('http://localhost:8648/api/profiles', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
body: JSON.stringify({
name: 'production',
cloneFrom: 'default' // Optional: clone existing profile
})
});
// Switch active profile
// POST /api/profiles/production/activate
// Export profile for backup
// GET /api/profiles/production/export
// Returns .tar.gz archive
// Import profile
// POST /api/profiles/import
// FormData with .tar.gz fileGateway Management per Profile:
bash
undefined创建独立的Hermes配置文件,包含各自的配置与缓存:
typescript
// POST /api/profiles
const profile = await fetch('http://localhost:8648/api/profiles', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
body: JSON.stringify({
name: 'production',
cloneFrom: 'default' // 可选:从现有配置文件克隆
})
});
// 切换活跃配置文件
// POST /api/profiles/production/activate
// 导出配置文件用于备份
// GET /api/profiles/production/export
// 返回.tar.gz压缩包
// 导入配置文件
// POST /api/profiles/import
// 上传.tar.gz格式的FormData文件按配置文件管理网关:
bash
undefinedStart gateway for profile
启动指定配置文件的网关
POST /api/profiles/:name/gateway/start
POST /api/profiles/:name/gateway/start
Stop gateway
停止网关
POST /api/profiles/:name/gateway/stop
POST /api/profiles/:name/gateway/stop
Get gateway status
获取网关状态
GET /api/profiles/:name/gateway/status
undefinedGET /api/profiles/:name/gateway/status
undefinedFile Browser
文件浏览器
Browse and manage files on remote backends:
typescript
// List directory contents
const files = await fetch('http://localhost:8648/api/files/list?path=/workspace', {
headers: { 'Authorization': `Bearer ${process.env.AUTH_TOKEN}` }
});
// Upload file
const formData = new FormData();
formData.append('file', fileBlob);
formData.append('path', '/workspace/data');
await fetch('http://localhost:8648/api/files/upload', {
method: 'POST',
headers: { 'Authorization': `Bearer ${process.env.AUTH_TOKEN}` },
body: formData
});
// Download file
GET /api/files/download?path=/workspace/output.txt
// Create directory
POST /api/files/mkdir
Content-Type: application/json
{ "path": "/workspace/new-dir" }
// Delete file
DELETE /api/files/delete?path=/workspace/old-file.txt
// Rename/move
POST /api/files/rename
{ "oldPath": "/workspace/old.txt", "newPath": "/workspace/new.txt" }Supported Backends:
- Local filesystem
- Docker containers
- SSH remote hosts
- Singularity containers
浏览并管理远程后端的文件:
typescript
undefinedGroup Chat (Multi-Agent)
列出目录内容
Create chat rooms with multiple agents and context compression:
typescript
import { io } from 'socket.io-client';
const socket = io('http://localhost:8648');
// Create room
socket.emit('room-create', {
name: 'Engineering Team',
agents: [
{ name: 'CodeReviewer', profile: 'default' },
{ name: 'Architect', profile: 'production' }
]
});
// Send message with @mention
socket.emit('room-message', {
roomId: 'room-123',
content: '@CodeReviewer can you review this function?',
userId: 'user-456'
});
// Receive agent reply
socket.on('room-agent-reply', (data) => {
console.log(`${data.agentName}: ${data.message}`);
});Features:
- @mention routing to specific agents
- Auto context compression when history exceeds token threshold
- Typing status and reply progress
- SQLite message persistence
- Invite code management
const files = await fetch('http://localhost:8648/api/files/list?path=/workspace', {
headers: { 'Authorization': }
});
Bearer ${process.env.AUTH_TOKEN}Authentication
上传文件
bash
undefinedconst formData = new FormData();
formData.append('file', fileBlob);
formData.append('path', '/workspace/data');
await fetch('http://localhost:8648/api/files/upload', {
method: 'POST',
headers: { 'Authorization': },
body: formData
});
Bearer ${process.env.AUTH_TOKEN}First run generates token in ~/.hermes-web-ui/.token
下载文件
cat ~/.hermes-web-ui/.token
GET /api/files/download?path=/workspace/output.txt
Use token in API requests
创建目录
curl -H "Authorization: Bearer your-token-here"
http://localhost:8648/api/sessions
http://localhost:8648/api/sessions
POST /api/files/mkdir
Content-Type: application/json
{ "path": "/workspace/new-dir" }
Disable auth (not recommended for production)
删除文件
export AUTH_DISABLED=1
hermes-web-ui start
**Username/Password Auth:**
After initial token auth, set up username/password via Settings page. Credentials stored in Web UI database.DELETE /api/files/delete?path=/workspace/old-file.txt
Web Terminal
重命名/移动
Integrated terminal with multi-session support:
typescript
// WebSocket connection for PTY
const ws = new WebSocket('ws://localhost:8648/terminal');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'create',
cols: 80,
rows: 24
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'output') {
console.log(data.data); // PTY output
}
};
// Send keyboard input
ws.send(JSON.stringify({
type: 'input',
data: 'ls -la\n'
}));
// Resize terminal
ws.send(JSON.stringify({
type: 'resize',
cols: 120,
rows: 30
}));POST /api/files/rename
{ "oldPath": "/workspace/old.txt", "newPath": "/workspace/new.txt" }
**支持的后端:**
- 本地文件系统
- Docker容器
- SSH远程主机
- Singularity容器Configuration Files
群组聊天(多Agent)
Hermes Config (~/.hermes/config.yaml
)
~/.hermes/config.yaml—
yaml
api_server:
host: 127.0.0.1
port: 8642
cors_origins: ["*"]
telegram:
mention_control: true
reactions_enabled: true
free_response_chats: []
discord:
mention_required: true
auto_thread: true
reactions_enabled: true
allowed_channels: []
ignored_channels: []
memory:
enabled: true
max_chars: 10000
agent:
max_turns: 10
timeout: 300
enforce_tools: false
privacy:
redact_pii: false创建包含多个Agent的聊天室,并支持上下文压缩:
typescript
import { io } from 'socket.io-client';
const socket = io('http://localhost:8648');Credentials (~/.hermes/auth.json
)
~/.hermes/auth.json创建聊天室
json
{
"providers": [
{
"name": "openai",
"type": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "${OPENAI_API_KEY}",
"models": ["gpt-4", "gpt-3.5-turbo"]
}
]
}Use environment variable references () instead of hardcoded keys.
${VAR_NAME}socket.emit('room-create', {
name: '工程团队',
agents: [
{ name: 'CodeReviewer', profile: 'default' },
{ name: 'Architect', profile: 'production' }
]
});
Common Patterns
发送带@提及的消息
Starting Web UI with Custom Config
—
bash
export PORT=9000
export LOG_LEVEL=debug
export AUTH_DISABLED=1
export HERMES_WEB_UI_HOME=/custom/path
hermes-web-ui startsocket.emit('room-message', {
roomId: 'room-123',
content: '@CodeReviewer can you review this function?',
userId: 'user-456'
});
Programmatic Chat Session
接收Agent回复
typescript
import { io, Socket } from 'socket.io-client';
class HermesChatClient {
private socket: Socket;
constructor(serverUrl = 'http://localhost:8648') {
this.socket = io(serverUrl);
}
sendMessage(sessionId: string, message: string, model = 'gpt-4'): Promise<string> {
return new Promise((resolve) => {
let fullResponse = '';
this.socket.emit('chat-run', {
sessionId,
message,
model,
profile: 'default'
});
this.socket.on('chat-delta', (data) => {
fullResponse += data.content;
});
this.socket.on('chat-done', () => {
resolve(fullResponse);
});
});
}
disconnect() {
this.socket.disconnect();
}
}
// Usage
const client = new HermesChatClient();
const response = await client.sendMessage('session-123', 'What is TypeScript?');
console.log(response);
client.disconnect();socket.on('room-agent-reply', (data) => {
console.log();
});
${data.agentName}: ${data.message}
**特性:**
- @提及路由至指定Agent
- 当历史消息超过令牌阈值时自动压缩上下文
- 输入状态与回复进度显示
- SQLite消息持久化
- 邀请码管理Batch Session Export
认证机制
bash
undefinedbash
undefinedExport all sessions from Web UI database
首次运行会在~/.hermes-web-ui/.token生成令牌
cat ~/.hermes-web-ui/.token
Returns JSON array of all sessions with messages
在API请求中使用令牌
undefinedcurl -H "Authorization: Bearer your-token-here"
http://localhost:8648/api/sessions
http://localhost:8648/api/sessions
Auto-Configure Platform on Startup
禁用认证(生产环境不推荐)
typescript
// Auto-configure Telegram on container startup
const configureTelegram = async () => {
const token = process.env.TELEGRAM_BOT_TOKEN;
if (!token) return;
await fetch('http://localhost:8648/api/platforms/telegram', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
body: JSON.stringify({
bot_token: token,
mention_control: true,
reactions_enabled: true
})
});
};export AUTH_DISABLED=1
hermes-web-ui start
**用户名/密码认证:**
完成初始令牌认证后,可通过设置页面配置用户名/密码,凭证将存储在Web UI数据库中。Troubleshooting
Web终端
Port Already in Use
—
bash
undefined集成式终端,支持多会话:
typescript
undefinedWeb UI auto-kills stale processes on startup
用于PTY的WebSocket连接
Manual check:
—
lsof -ti:8648 | xargs kill -9
const ws = new WebSocket('ws://localhost:8648/terminal');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'create',
cols: 80,
rows: 24
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'output') {
console.log(data.data); // PTY输出内容
}
};
Or start on different port
发送键盘输入
hermes-web-ui start --port 9000
undefinedws.send(JSON.stringify({
type: 'input',
data: 'ls -la\n'
}));
Gateway Not Starting
调整终端尺寸
bash
undefinedws.send(JSON.stringify({
type: 'resize',
cols: 120,
rows: 30
}));
undefinedCheck gateway status
配置文件说明
—
Hermes配置文件 (~/.hermes/config.yaml
)
~/.hermes/config.yamlyaml
api_server:
host: 127.0.0.1
port: 8642
cors_origins: ["*"]
telegram:
mention_control: true
reactions_enabled: true
free_response_chats: []
discord:
mention_required: true
auto_thread: true
reactions_enabled: true
allowed_channels: []
ignored_channels: []
memory:
enabled: true
max_chars: 10000
agent:
max_turns: 10
timeout: 300
enforce_tools: false
privacy:
redact_pii: falseView gateway logs
凭证文件 (~/.hermes/auth.json
)
~/.hermes/auth.jsonjson
{
"providers": [
{
"name": "openai",
"type": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": "${OPENAI_API_KEY}",
"models": ["gpt-4", "gpt-3.5-turbo"]
}
]
}建议使用环境变量引用()而非硬编码密钥。
${VAR_NAME}Manually start gateway
常见使用场景
—
自定义配置启动Web UI
hermes-web-ui restart
undefinedbash
export PORT=9000
export LOG_LEVEL=debug
export AUTH_DISABLED=1
export HERMES_WEB_UI_HOME=/custom/path
hermes-web-ui startAuthentication Token Not Found
程序化创建聊天会话
bash
undefinedtypescript
import { io, Socket } from 'socket.io-client';
class HermesChatClient {
private socket: Socket;
constructor(serverUrl = 'http://localhost:8648') {
this.socket = io(serverUrl);
}
sendMessage(sessionId: string, message: string, model = 'gpt-4'): Promise<string> {
return new Promise((resolve) => {
let fullResponse = '';
this.socket.emit('chat-run', {
sessionId,
message,
model,
profile: 'default'
});
this.socket.on('chat-delta', (data) => {
fullResponse += data.content;
});
this.socket.on('chat-done', () => {
resolve(fullResponse);
});
});
}
disconnect() {
this.socket.disconnect();
}
}Token stored in ~/.hermes-web-ui/.token
使用示例
cat ~/.hermes-web-ui/.token
const client = new HermesChatClient();
const response = await client.sendMessage('session-123', 'What is TypeScript?');
console.log(response);
client.disconnect();
undefinedSet explicit token
批量导出会话
export AUTH_TOKEN=my-secret-token
hermes-web-ui restart
bash
undefinedOr disable auth
从Web UI数据库导出所有会话
export AUTH_DISABLED=1
hermes-web-ui restart
undefinedDocker Volume Permissions
返回包含所有会话及消息的JSON数组
bash
undefinedundefinedFix permissions on host
启动时自动配置平台
sudo chown -R $(id -u):$(id -g) ./hermes_data
typescript
undefinedOr run container with host UID/GID
容器启动时自动配置Telegram
docker compose run --user $(id -u):$(id -g) hermes-webui
undefinedconst configureTelegram = async () => {
const token = process.env.TELEGRAM_BOT_TOKEN;
if (!token) return;
await fetch('http://localhost:8648/api/platforms/telegram', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization':
},
body: JSON.stringify({
bot_token: token,
mention_control: true,
reactions_enabled: true
})
});
};
Bearer ${process.env.AUTH_TOKEN}undefinedModel Discovery Fails
故障排查
—
端口已被占用
bash
undefinedbash
undefinedCheck auth.json syntax
Web UI启动时会自动终止僵死进程
—
手动检查并清理:
cat ~/.hermes/auth.json | jq .
lsof -ti:8648 | xargs kill -9
Verify API keys are set as env vars
或使用其他端口启动
echo $OPENAI_API_KEY
hermes-web-ui start --port 9000
undefinedTest provider endpoint manually
网关无法启动
curl -H "Authorization: Bearer $OPENAI_API_KEY"
https://api.openai.com/v1/models
https://api.openai.com/v1/models
undefinedbash
undefinedWebSocket Connection Errors
检查网关状态
javascript
// Check CORS configuration
export CORS_ORIGINS=http://localhost:5173,http://localhost:8648
hermes-web-ui restart
// Verify WebSocket path
const socket = io('http://localhost:8648', {
path: '/socket.io/',
transports: ['websocket', 'polling']
});Session Database Locked
查看网关日志
bash
undefinedSQLite lock issue - restart Web UI
手动重启网关
hermes-web-ui restart
hermes-web-ui restart
undefinedOr clear lock file
未找到认证令牌
rm ~/.hermes-web-ui/sessions.db-wal
rm ~/.hermes-web-ui/sessions.db-shm
undefinedbash
undefinedUpdate Fails
令牌存储在~/.hermes-web-ui/.token
bash
undefinedcat ~/.hermes-web-ui/.token
Clear npm cache and retry
显式设置令牌
npm cache clean --force
npm install -g hermes-web-ui@latest
export AUTH_TOKEN=my-secret-token
hermes-web-ui restart
Or reinstall from scratch
或禁用认证
npm uninstall -g hermes-web-ui
npm install -g hermes-web-ui
undefinedexport AUTH_DISABLED=1
hermes-web-ui restart
undefinedProduction Deployment
Docker卷权限问题
bash
undefinedbash
undefinedUse systemd service (Linux)
修复主机目录权限
cat > /etc/systemd/system/hermes-web-ui.service <<EOF
[Unit]
Description=Hermes Web UI
After=network.target
[Service]
Type=simple
User=hermes
Environment="PORT=8648"
Environment="AUTH_DISABLED=0"
Environment="LOG_LEVEL=info"
ExecStart=/usr/bin/hermes-web-ui start
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable hermes-web-ui
sudo systemctl start hermes-web-ui
```bashsudo chown -R $(id -u):$(id -g) ./hermes_data
Behind nginx reverse proxy
或使用主机UID/GID运行容器
server {
listen 80;
server_name hermes.example.com;
location / {
proxy_pass http://127.0.0.1:8648;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:8648;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
---
**Resources:**
- GitHub: https://github.com/EKKOLearnAI/hermes-web-ui
- npm: https://www.npmjs.com/package/hermes-web-ui
- Homepage: https://ekkolearnai.com
- Docker: https://github.com/EKKOLearnAI/hermes-web-ui/blob/main/docs/docker.md
- Development Guide: https://github.com/EKKOLearnAI/hermes-web-ui/blob/main/DEVELOPMENT.mddocker compose run --user $(id -u):$(id -g) hermes-webui
undefined—
模型发现失败
—
bash
undefined—
检查auth.json语法
—
cat ~/.hermes/auth.json | jq .
—
验证API密钥已设置为环境变量
—
echo $OPENAI_API_KEY
—
手动测试服务商端点
—
curl -H "Authorization: Bearer $OPENAI_API_KEY"
https://api.openai.com/v1/models
https://api.openai.com/v1/models
undefined—
WebSocket连接错误
—
javascript
undefined—
检查CORS配置
—
export CORS_ORIGINS=http://localhost:5173,http://localhost:8648
hermes-web-ui restart
—
验证WebSocket路径
—
const socket = io('http://localhost:8648', {
path: '/socket.io/',
transports: ['websocket', 'polling']
});
undefined—
会话数据库被锁定
—
bash
undefined—
SQLite锁定问题 - 重启Web UI
—
hermes-web-ui restart
—
或清理锁定文件
—
rm ~/.hermes-web-ui/sessions.db-wal
rm ~/.hermes-web-ui/sessions.db-shm
undefined—
更新失败
—
bash
undefined—
清理npm缓存并重试
—
npm cache clean --force
npm install -g hermes-web-ui@latest
—
或完全重新安装
—
npm uninstall -g hermes-web-ui
npm install -g hermes-web-ui
undefined—
生产环境部署
—
bash
undefined—
使用systemd服务(Linux)
—
cat > /etc/systemd/system/hermes-web-ui.service <<EOF
[Unit]
Description=Hermes Web UI
After=network.target
[Service]
Type=simple
User=hermes
Environment="PORT=8648"
Environment="AUTH_DISABLED=0"
Environment="LOG_LEVEL=info"
ExecStart=/usr/bin/hermes-web-ui start
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable hermes-web-ui
sudo systemctl start hermes-web-ui
```bash—
Nginx反向代理配置
—
server {
listen 80;
server_name hermes.example.com;
location / {
proxy_pass http://127.0.0.1:8648;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:8648;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
---
**相关资源:**
- GitHub: https://github.com/EKKOLearnAI/hermes-web-ui
- npm: https://www.npmjs.com/package/hermes-web-ui
- 官网: https://ekkolearnai.com
- Docker文档: https://github.com/EKKOLearnAI/hermes-web-ui/blob/main/docs/docker.md
- 开发指南: https://github.com/EKKOLearnAI/hermes-web-ui/blob/main/DEVELOPMENT.md