hermes-web-ui 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -408
- package/bin/hermes-web-ui.mjs +111 -97
- package/dist/assets/{ChatView-WnNeYrS7.js → ChatView-BBqtEbUW.js} +20 -20
- package/dist/assets/ChatView-DC6_7Uwg.css +1 -0
- package/dist/assets/JobsView-sQ8sqrxF.js +356 -0
- package/dist/assets/LogsView-BN_TkDPi.css +1 -0
- package/dist/assets/LogsView-DukKyFJt.js +1 -0
- package/dist/assets/Modal-oIDM0xXN.js +232 -0
- package/dist/assets/Spin-zWt--szS.js +476 -0
- package/dist/assets/Tooltip-BGvPCNBt.js +1 -0
- package/dist/assets/Warning-B9_T2nKK.js +1 -0
- package/dist/assets/_plugin-vue_export-helper-V8xgnEJh.js +231 -0
- package/dist/assets/chat-CGF6ipPC.js +5 -0
- package/dist/assets/fade-in-scale-up.cssr-DQYNrBys.js +45 -0
- package/dist/assets/index-BsLYVWlc.js +307 -0
- package/dist/assets/index-DDAe8BhJ.css +1 -0
- package/dist/assets/{jobs-Cuol6Mqb.js → jobs-QHXENDTQ.js} +1 -1
- package/dist/assets/use-message-42wmA96q.js +117 -0
- package/dist/index.html +8 -6
- package/dist/server/config.d.ts +7 -0
- package/dist/server/config.js +12 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +154 -0
- package/dist/server/routes/logs.d.ts +2 -0
- package/dist/server/routes/logs.js +87 -0
- package/dist/server/routes/proxy-handler.d.ts +2 -0
- package/dist/server/routes/proxy-handler.js +82 -0
- package/dist/server/routes/proxy.d.ts +2 -0
- package/dist/server/routes/proxy.js +12 -0
- package/dist/server/routes/sessions.d.ts +2 -0
- package/dist/server/routes/sessions.js +69 -0
- package/dist/server/routes/upload.d.ts +2 -0
- package/dist/server/routes/upload.js +50 -0
- package/dist/server/routes/webhook.d.ts +2 -0
- package/dist/server/routes/webhook.js +33 -0
- package/dist/server/services/hermes-cli.d.ts +50 -0
- package/dist/server/services/hermes-cli.js +185 -0
- package/dist/server/services/hermes.d.ts +40 -0
- package/dist/server/services/hermes.js +118 -0
- package/package.json +19 -4
- package/dist/assets/ChatView-DrzZz5ex.css +0 -1
- package/dist/assets/JobsView-BF9wWdwU.js +0 -831
- package/dist/assets/Modal-CQVLL_Oc.js +0 -276
- package/dist/assets/_plugin-vue_export-helper-D5N3Hfca.js +0 -231
- package/dist/assets/chat-640V6r6N.js +0 -1
- package/dist/assets/index-4iFlrAYJ.js +0 -307
- package/dist/assets/index-CMJKLUKk.css +0 -1
- package/dist/assets/use-message-B8ClBznx.js +0 -117
- /package/dist/assets/{client-BxIiwrqC.js → client-ZYGCrm9m.js} +0 -0
package/README.md
CHANGED
|
@@ -1,434 +1,143 @@
|
|
|
1
|
-
# Hermes UI
|
|
1
|
+
# Hermes Web UI
|
|
2
2
|
|
|
3
|
-
Hermes Agent
|
|
3
|
+
Web dashboard for [Hermes Agent](https://github.com/EKKOLearnAI/hermes-agent) — chat interaction, session management, scheduled jobs, and log viewing.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Tech Stack
|
|
6
6
|
|
|
7
7
|
- **Vue 3** — Composition API + `<script setup>`
|
|
8
8
|
- **TypeScript**
|
|
9
|
-
- **Vite** —
|
|
10
|
-
- **Naive UI** —
|
|
11
|
-
- **Pinia** —
|
|
12
|
-
- **Vue Router** —
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
9
|
+
- **Vite** — Build tool
|
|
10
|
+
- **Naive UI** — Component library
|
|
11
|
+
- **Pinia** — State management
|
|
12
|
+
- **Vue Router** — Routing (Hash mode)
|
|
13
|
+
- **Koa 2** — BFF server (API proxy, file upload, session management)
|
|
14
|
+
- **SCSS** — Style preprocessor
|
|
15
|
+
- **markdown-it** + **highlight.js** — Markdown rendering and code highlighting
|
|
15
16
|
|
|
16
|
-
##
|
|
17
|
-
|
|
18
|
-
### 1. 配置 API Server
|
|
19
|
-
|
|
20
|
-
编辑 `~/.hermes/config.yaml`,启用 API Server:
|
|
21
|
-
|
|
22
|
-
```yaml
|
|
23
|
-
platforms:
|
|
24
|
-
api_server:
|
|
25
|
-
enabled: true
|
|
26
|
-
host: "127.0.0.1"
|
|
27
|
-
port: 8642
|
|
28
|
-
key: ""
|
|
29
|
-
cors_origins: "*"
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
重启 Gateway 使配置生效:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
hermes gateway restart
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### 2. 安装并启动
|
|
17
|
+
## Install and Run
|
|
39
18
|
|
|
40
19
|
```bash
|
|
41
|
-
# 全局安装
|
|
42
20
|
npm install -g hermes-web-ui
|
|
43
|
-
|
|
44
|
-
# 启动 Web 面板(默认 http://localhost:8648)
|
|
45
21
|
hermes-web-ui start
|
|
46
22
|
```
|
|
47
23
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# 克隆项目后
|
|
52
|
-
npm install
|
|
53
|
-
npm run dev
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## 项目结构
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
src/
|
|
60
|
-
├── api/
|
|
61
|
-
│ ├── client.ts # HTTP 请求封装(fetch + Bearer Auth)
|
|
62
|
-
│ ├── chat.ts # 对话 API(startRun + SSE 事件流)
|
|
63
|
-
│ ├── jobs.ts # 定时任务 CRUD
|
|
64
|
-
│ └── system.ts # 健康检查、模型列表
|
|
65
|
-
├── stores/
|
|
66
|
-
│ ├── app.ts # 全局状态(连接状态、版本、模型)
|
|
67
|
-
│ ├── chat.ts # 对话状态(消息、会话、流式输出)
|
|
68
|
-
│ └── jobs.ts # 任务状态(列表、CRUD 操作)
|
|
69
|
-
├── components/
|
|
70
|
-
│ ├── layout/
|
|
71
|
-
│ │ └── AppSidebar.vue # 侧边栏导航
|
|
72
|
-
│ ├── chat/
|
|
73
|
-
│ │ ├── ChatPanel.vue # 对话面板(会话列表 + 聊天区域)
|
|
74
|
-
│ │ ├── MessageList.vue # 消息列表(自动滚动、加载动画)
|
|
75
|
-
│ │ ├── MessageItem.vue # 单条消息(用户/AI/工具/系统)
|
|
76
|
-
│ │ ├── ChatInput.vue # 输入框(Ctrl+Enter 发送)
|
|
77
|
-
│ │ └── MarkdownRenderer.vue # Markdown 渲染(代码高亮、复制)
|
|
78
|
-
│ └── jobs/
|
|
79
|
-
│ ├── JobsPanel.vue # 任务面板
|
|
80
|
-
│ ├── JobCard.vue # 任务卡片
|
|
81
|
-
│ └── JobFormModal.vue # 创建/编辑任务弹窗
|
|
82
|
-
├── views/
|
|
83
|
-
│ ├── ChatView.vue # 对话页
|
|
84
|
-
│ └── JobsView.vue # 任务页
|
|
85
|
-
├── router/
|
|
86
|
-
│ └── index.ts # 路由配置
|
|
87
|
-
├── styles/
|
|
88
|
-
│ ├── variables.scss # SCSS 设计变量
|
|
89
|
-
│ ├── global.scss # 全局样式
|
|
90
|
-
│ └── theme.ts # Naive UI 主题覆盖
|
|
91
|
-
├── composables/
|
|
92
|
-
│ └── useKeyboard.ts # 键盘快捷键
|
|
93
|
-
└── main.ts # 应用入口
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## 功能特性
|
|
97
|
-
|
|
98
|
-
### 对话(Chat)
|
|
99
|
-
|
|
100
|
-
- 基于 `/v1/runs` + `/v1/runs/{id}/events` 的异步 Run + SSE 事件流
|
|
101
|
-
- 实时流式输出,工具调用进度可视化
|
|
102
|
-
- 多会话管理,会话历史持久化到 localStorage
|
|
103
|
-
- Markdown 渲染,代码块语法高亮与一键复制
|
|
104
|
-
|
|
105
|
-
### 定时任务(Jobs)
|
|
106
|
-
|
|
107
|
-
- 任务列表查看(含暂停/禁用任务)
|
|
108
|
-
- 创建、编辑、删除任务
|
|
109
|
-
- 暂停/恢复任务
|
|
110
|
-
- 立即触发任务执行
|
|
111
|
-
- Cron 表达式快速预设
|
|
112
|
-
|
|
113
|
-
### 其他
|
|
114
|
-
|
|
115
|
-
- 连接状态实时检测(30s 轮询)
|
|
116
|
-
- 纯黑白主题
|
|
117
|
-
- 键盘快捷键支持
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## API 接口文档
|
|
122
|
-
|
|
123
|
-
Base URL: `http://127.0.0.1:8642`
|
|
124
|
-
|
|
125
|
-
### 认证
|
|
126
|
-
|
|
127
|
-
除 `/health` 外,所有接口支持 Bearer Token 认证(如果服务端配置了 `key`):
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
Authorization: Bearer <your-api-key>
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
未配置 key 时所有请求放行。
|
|
134
|
-
|
|
135
|
-
### 通用错误格式
|
|
136
|
-
|
|
137
|
-
```json
|
|
138
|
-
{
|
|
139
|
-
"error": {
|
|
140
|
-
"message": "错误描述",
|
|
141
|
-
"type": "invalid_request_error",
|
|
142
|
-
"param": null,
|
|
143
|
-
"code": "invalid_api_key"
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
| 状态码 | 说明 |
|
|
149
|
-
|--------|------|
|
|
150
|
-
| 200 | 成功 |
|
|
151
|
-
| 400 | 请求参数错误 |
|
|
152
|
-
| 401 | API Key 无效 |
|
|
153
|
-
| 404 | 资源不存在 |
|
|
154
|
-
| 413 | 请求体过大(上限 1MB) |
|
|
155
|
-
| 429 | 并发超限(最大 10 个 Run) |
|
|
156
|
-
| 500 | 服务器内部错误 |
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
### 1. 健康检查
|
|
161
|
-
|
|
162
|
-
**GET** `/health` 或 `/v1/health`
|
|
163
|
-
|
|
164
|
-
无需认证。
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
{"status": "ok", "platform": "hermes-agent"}
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
### 2. 模型列表
|
|
173
|
-
|
|
174
|
-
**GET** `/v1/models`
|
|
175
|
-
|
|
176
|
-
```json
|
|
177
|
-
{
|
|
178
|
-
"object": "list",
|
|
179
|
-
"data": [
|
|
180
|
-
{
|
|
181
|
-
"id": "hermes-agent",
|
|
182
|
-
"object": "model",
|
|
183
|
-
"created": 1744348800,
|
|
184
|
-
"owned_by": "hermes"
|
|
185
|
-
}
|
|
186
|
-
]
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
### 3. Chat Completions(OpenAI 兼容)
|
|
193
|
-
|
|
194
|
-
**POST** `/v1/chat/completions`
|
|
195
|
-
|
|
196
|
-
| 字段 | 类型 | 必填 | 说明 |
|
|
197
|
-
|------|------|------|------|
|
|
198
|
-
| messages | array | Y | 消息数组,格式同 OpenAI |
|
|
199
|
-
| stream | boolean | N | 是否流式返回,默认 false |
|
|
200
|
-
| model | string | N | 模型名,默认 "hermes-agent" |
|
|
201
|
-
|
|
202
|
-
可选 Header: `X-Hermes-Session-Id` 指定会话 ID。
|
|
203
|
-
|
|
204
|
-
**stream=false 响应:**
|
|
205
|
-
```json
|
|
206
|
-
{
|
|
207
|
-
"id": "chatcmpl-xxxxx",
|
|
208
|
-
"object": "chat.completion",
|
|
209
|
-
"created": 1744348800,
|
|
210
|
-
"model": "hermes-agent",
|
|
211
|
-
"choices": [{"index": 0, "message": {"role": "assistant", "content": "回复内容"}, "finish_reason": "stop"}],
|
|
212
|
-
"usage": {"prompt_tokens": 100, "completion_tokens": 50, "total_tokens": 150}
|
|
213
|
-
}
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**stream=true 响应:** SSE 流(`Content-Type: text/event-stream`)
|
|
217
|
-
```
|
|
218
|
-
data: {"id":"chatcmpl-xxx","choices":[{"delta":{"content":"你"},"index":0}]}
|
|
219
|
-
data: [DONE]
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
---
|
|
223
|
-
|
|
224
|
-
### 4. Responses(有状态链式对话)
|
|
225
|
-
|
|
226
|
-
**POST** `/v1/responses`
|
|
227
|
-
|
|
228
|
-
| 字段 | 类型 | 必填 | 说明 |
|
|
229
|
-
|------|------|------|------|
|
|
230
|
-
| input | string / array | Y | 用户输入 |
|
|
231
|
-
| instructions | string | N | 系统指令 |
|
|
232
|
-
| previous_response_id | string | N | 链式对话的上一次响应 ID |
|
|
233
|
-
| conversation | string | N | 会话名称,自动链式到最新响应 |
|
|
234
|
-
| conversation_history | array | N | 显式传入对话历史 |
|
|
235
|
-
| store | boolean | N | 是否存储响应,默认 true |
|
|
236
|
-
| truncation | string | N | 设为 "auto" 自动截断历史到 100 条 |
|
|
237
|
-
| model | string | N | 模型名 |
|
|
238
|
-
|
|
239
|
-
> `conversation` 和 `previous_response_id` 互斥。
|
|
240
|
-
|
|
241
|
-
可选 Header: `Idempotency-Key` 幂等键。
|
|
242
|
-
|
|
243
|
-
```json
|
|
244
|
-
{
|
|
245
|
-
"id": "resp_xxx",
|
|
246
|
-
"object": "response",
|
|
247
|
-
"status": "completed",
|
|
248
|
-
"created_at": 1744348800,
|
|
249
|
-
"output": [{"type": "message", "role": "assistant", "content": "回复内容"}],
|
|
250
|
-
"usage": {"input_tokens": 100, "output_tokens": 50, "total_tokens": 150}
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
---
|
|
255
|
-
|
|
256
|
-
### 5. 获取 / 删除存储的响应
|
|
257
|
-
|
|
258
|
-
**GET** `/v1/responses/{response_id}` — 获取存储的响应
|
|
259
|
-
|
|
260
|
-
**DELETE** `/v1/responses/{response_id}` — 删除存储的响应
|
|
261
|
-
|
|
262
|
-
```json
|
|
263
|
-
{"id": "resp_xxx", "object": "response", "deleted": true}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
### 6. 启动异步 Run
|
|
269
|
-
|
|
270
|
-
**POST** `/v1/runs`
|
|
271
|
-
|
|
272
|
-
| 字段 | 类型 | 必填 | 说明 |
|
|
273
|
-
|------|------|------|------|
|
|
274
|
-
| input | string / array | Y | 用户输入 |
|
|
275
|
-
| instructions | string | N | 系统指令 |
|
|
276
|
-
| previous_response_id | string | N | 链式对话 ID |
|
|
277
|
-
| conversation_history | array | N | 对话历史 |
|
|
278
|
-
| session_id | string | N | 会话 ID,默认使用 run_id |
|
|
279
|
-
|
|
280
|
-
```json
|
|
281
|
-
{"run_id": "run_xxx", "status": "started"}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
### 7. SSE 事件流
|
|
287
|
-
|
|
288
|
-
**GET** `/v1/runs/{run_id}/events`
|
|
289
|
-
|
|
290
|
-
`Content-Type: text/event-stream`
|
|
291
|
-
|
|
292
|
-
**事件类型:**
|
|
293
|
-
|
|
294
|
-
| 事件 | 说明 |
|
|
295
|
-
|------|------|
|
|
296
|
-
| `run.started` | Run 开始 |
|
|
297
|
-
| `message.delta` | 消息内容片段(字段 `delta`) |
|
|
298
|
-
| `tool.started` | 工具调用开始(字段 `tool`、`preview`) |
|
|
299
|
-
| `tool.completed` | 工具调用完成(字段 `tool`、`duration`) |
|
|
300
|
-
| `run.completed` | Run 完成(字段 `output`、`usage`) |
|
|
301
|
-
| `run.failed` | Run 失败(字段 `error`) |
|
|
302
|
-
|
|
303
|
-
示例:
|
|
304
|
-
```
|
|
305
|
-
data: {"event":"message.delta","run_id":"run_xxx","delta":"你好","timestamp":...}
|
|
306
|
-
data: {"event":"tool.started","run_id":"run_xxx","tool":"browser_navigate","preview":"https://...","timestamp":...}
|
|
307
|
-
data: {"event":"tool.completed","run_id":"run_xxx","tool":"browser_navigate","duration":3.8,"timestamp":...}
|
|
308
|
-
data: {"event":"run.completed","run_id":"run_xxx","output":"完整回复","usage":{"input_tokens":100,"output_tokens":50,"total_tokens":150}}
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
### 8. 定时任务
|
|
314
|
-
|
|
315
|
-
#### 列出任务
|
|
316
|
-
|
|
317
|
-
**GET** `/api/jobs?include_disabled=true`
|
|
318
|
-
|
|
319
|
-
```json
|
|
320
|
-
{
|
|
321
|
-
"jobs": [
|
|
322
|
-
{
|
|
323
|
-
"job_id": "61a5eb0baeb9",
|
|
324
|
-
"name": "任务名",
|
|
325
|
-
"schedule": "0 9 * * *",
|
|
326
|
-
"repeat": "forever",
|
|
327
|
-
"deliver": "origin",
|
|
328
|
-
"next_run_at": "2026-04-12T09:00:00+08:00",
|
|
329
|
-
"last_run_at": "2026-04-11T09:04:25+08:00",
|
|
330
|
-
"last_status": "ok",
|
|
331
|
-
"enabled": true,
|
|
332
|
-
"state": "scheduled",
|
|
333
|
-
"prompt_preview": "...",
|
|
334
|
-
"skills": []
|
|
335
|
-
}
|
|
336
|
-
]
|
|
337
|
-
}
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
#### 创建任务
|
|
341
|
-
|
|
342
|
-
**POST** `/api/jobs`
|
|
343
|
-
|
|
344
|
-
| 字段 | 类型 | 必填 | 说明 |
|
|
345
|
-
|------|------|------|------|
|
|
346
|
-
| name | string | Y | 任务名称(最大 200 字符) |
|
|
347
|
-
| schedule | string | Y | Cron 表达式 |
|
|
348
|
-
| prompt | string | N | 任务 prompt |
|
|
349
|
-
| deliver | string | N | 投递目标(origin / local / telegram / discord) |
|
|
350
|
-
| skills | array | N | skill 名称数组 |
|
|
351
|
-
| repeat | integer | N | 重复次数,不传表示永久 |
|
|
352
|
-
|
|
353
|
-
响应包裹在 `{"job": {...}}` 中。
|
|
24
|
+
Open http://localhost:8648
|
|
354
25
|
|
|
355
|
-
|
|
26
|
+
### CLI Commands
|
|
356
27
|
|
|
357
|
-
|
|
28
|
+
| Command | Description |
|
|
29
|
+
|---------|-------------|
|
|
30
|
+
| `hermes-web-ui start` | Start in background (daemon mode) |
|
|
31
|
+
| `hermes-web-ui start --port 9000` | Start on custom port |
|
|
32
|
+
| `hermes-web-ui stop` | Stop background process |
|
|
33
|
+
| `hermes-web-ui restart` | Restart background process |
|
|
34
|
+
| `hermes-web-ui status` | Check if running |
|
|
35
|
+
| `hermes-web-ui` | Run in foreground (for debugging) |
|
|
358
36
|
|
|
359
|
-
|
|
37
|
+
### Auto Configuration
|
|
360
38
|
|
|
361
|
-
|
|
39
|
+
On startup, the BFF server automatically checks `~/.hermes/config.yaml` and ensures `platforms.api_server.enabled` is set to `true`. If modified, it backs up the original to `config.yaml.bak` and restarts the gateway.
|
|
362
40
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
#### 删除任务
|
|
366
|
-
|
|
367
|
-
**DELETE** `/api/jobs/{job_id}`
|
|
368
|
-
|
|
369
|
-
```json
|
|
370
|
-
{"ok": true}
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
#### 暂停任务
|
|
374
|
-
|
|
375
|
-
**POST** `/api/jobs/{job_id}/pause`
|
|
376
|
-
|
|
377
|
-
```json
|
|
378
|
-
{"job": {"job_id": "xxx", "enabled": false, "state": "paused", ...}}
|
|
379
|
-
```
|
|
41
|
+
## Development
|
|
380
42
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
{"job": {"job_id": "xxx", "enabled": true, "state": "scheduled", ...}}
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
#### 立即触发任务
|
|
390
|
-
|
|
391
|
-
**POST** `/api/jobs/{job_id}/run`
|
|
392
|
-
|
|
393
|
-
```json
|
|
394
|
-
{"job": {"job_id": "xxx", "state": "scheduled", ...}}
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://github.com/EKKOLearnAI/hermes-web-ui.git
|
|
45
|
+
cd hermes-web-ui
|
|
46
|
+
npm install
|
|
47
|
+
npm run dev
|
|
395
48
|
```
|
|
396
49
|
|
|
397
|
-
|
|
50
|
+
This starts:
|
|
51
|
+
- Frontend: http://localhost:5173
|
|
52
|
+
- BFF Server: http://localhost:8648 (proxies to Hermes on 8642)
|
|
398
53
|
|
|
399
|
-
|
|
54
|
+
### Build
|
|
400
55
|
|
|
401
56
|
```bash
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
57
|
+
npm run build
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Outputs to `dist/` (frontend + compiled BFF server).
|
|
61
|
+
|
|
62
|
+
## Project Structure
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
hermes-web-ui/
|
|
66
|
+
├── bin/
|
|
67
|
+
│ └── hermes-web-ui.mjs # CLI entry (start/stop/restart/status)
|
|
68
|
+
├── server/src/
|
|
69
|
+
│ ├── index.ts # BFF entry (Koa app bootstrap)
|
|
70
|
+
│ ├── config.ts # Configuration (port, upstream, etc.)
|
|
71
|
+
│ ├── routes/
|
|
72
|
+
│ │ ├── proxy.ts # API proxy to Hermes (/api/*, /v1/*)
|
|
73
|
+
│ │ ├── upload.ts # File upload (POST /upload)
|
|
74
|
+
│ │ ├── sessions.ts # Session management via Hermes CLI
|
|
75
|
+
│ │ ├── webhook.ts # Webhook receiver
|
|
76
|
+
│ │ └── logs.ts # Log file listing and reading
|
|
77
|
+
│ └── services/
|
|
78
|
+
│ └── hermes-cli.ts # Hermes CLI wrapper (sessions, logs, version)
|
|
79
|
+
├── src/
|
|
80
|
+
│ ├── api/ # Frontend API layer
|
|
81
|
+
│ ├── stores/ # Pinia state management
|
|
82
|
+
│ ├── components/
|
|
83
|
+
│ │ ├── layout/AppSidebar.vue # Sidebar navigation
|
|
84
|
+
│ │ ├── chat/ # Chat components
|
|
85
|
+
│ │ └── jobs/ # Job components
|
|
86
|
+
│ ├── views/
|
|
87
|
+
│ │ ├── ChatView.vue # Chat page
|
|
88
|
+
│ │ ├── JobsView.vue # Jobs page
|
|
89
|
+
│ │ └── LogsView.vue # Logs page
|
|
90
|
+
│ └── router/index.ts # Router configuration
|
|
91
|
+
└── dist/ # Build output (published to npm)
|
|
92
|
+
├── server/index.js # Compiled BFF
|
|
93
|
+
├── index.html # Frontend entry
|
|
94
|
+
└── assets/ # Frontend static assets
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Features
|
|
98
|
+
|
|
99
|
+
### Chat
|
|
100
|
+
- Async Run + SSE event streaming via BFF proxy
|
|
101
|
+
- Session management via Hermes CLI
|
|
102
|
+
- Multi-session switching with message history
|
|
103
|
+
- Markdown rendering with syntax highlighting and code copy
|
|
104
|
+
- File upload support (saved to temp, path passed to API)
|
|
105
|
+
|
|
106
|
+
### Scheduled Jobs
|
|
107
|
+
- Job list view (including paused/disabled jobs)
|
|
108
|
+
- Create, edit, pause, resume, and delete jobs
|
|
109
|
+
- Trigger immediate job execution
|
|
110
|
+
- Cron expression quick presets
|
|
111
|
+
|
|
112
|
+
### Logs
|
|
113
|
+
- View Hermes agent/gateway/error logs
|
|
114
|
+
- Filter by log level, log file, and search keyword
|
|
115
|
+
- Structured log parsing with HTTP access log highlighting
|
|
116
|
+
|
|
117
|
+
### Other
|
|
118
|
+
- Real-time connection status monitoring
|
|
119
|
+
- Hermes version display in sidebar
|
|
120
|
+
- Auto config check on startup
|
|
121
|
+
- Minimalist dark theme
|
|
122
|
+
|
|
123
|
+
## Architecture
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
Browser → BFF (Koa, :8648) → Hermes API (:8642)
|
|
127
|
+
↓
|
|
128
|
+
Hermes CLI (sessions, logs, version)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The BFF layer handles:
|
|
132
|
+
- API proxy to Hermes (with header forwarding)
|
|
133
|
+
- SSE streaming passthrough
|
|
134
|
+
- File upload to temp directory
|
|
135
|
+
- Session CRUD via Hermes CLI
|
|
136
|
+
- Log file reading and parsing
|
|
137
|
+
- Static file serving (SPA fallback)
|
|
412
138
|
|
|
413
|
-
|
|
414
|
-
curl -X POST http://127.0.0.1:8642/v1/runs \
|
|
415
|
-
-H "Content-Type: application/json" \
|
|
416
|
-
-d '{"input":"你好"}'
|
|
417
|
-
|
|
418
|
-
# 监听 Run 事件流
|
|
419
|
-
curl http://127.0.0.1:8642/v1/runs/{run_id}/events
|
|
420
|
-
|
|
421
|
-
# 列出任务(含已暂停)
|
|
422
|
-
curl "http://127.0.0.1:8642/api/jobs?include_disabled=true"
|
|
139
|
+
---
|
|
423
140
|
|
|
424
|
-
|
|
425
|
-
curl -X POST http://127.0.0.1:8642/api/jobs \
|
|
426
|
-
-H "Content-Type: application/json" \
|
|
427
|
-
-d '{"name":"测试任务","schedule":"0 9 * * *","prompt":"执行测试"}'
|
|
141
|
+
## License
|
|
428
142
|
|
|
429
|
-
|
|
430
|
-
curl -X POST http://127.0.0.1:8642/api/jobs/{job_id}/pause
|
|
431
|
-
curl -X POST http://127.0.0.1:8642/api/jobs/{job_id}/resume
|
|
432
|
-
curl -X POST http://127.0.0.1:8642/api/jobs/{job_id}/run
|
|
433
|
-
curl -X DELETE http://127.0.0.1:8642/api/jobs/{job_id}
|
|
434
|
-
```
|
|
143
|
+
[MIT](./LICENSE)
|