乐于分享
好东西不私藏

Hermes Agent 源码-TUI、Dashboard 与桌面应用

Hermes Agent 源码-TUI、Dashboard 与桌面应用

Hermes Agent 源码解析

第 18 讲:TUI、Dashboard 与桌面应用

基于 Hermes Agent v0.16.0 源码 · 2026-07-01

一、三端并行的 UI 架构

前几讲我们深入了 Hermes 的核心引擎。这一讲我们转向用户界面——Hermes 提供了三种交互方式:终端 TUI、Web Dashboard 和 Electron 桌面应用,三者共享同一套 Agent 核心。

📦 本讲核心文件

hermes_cli/curses_ui.py(872 行)— TUI 组件库

hermes_cli/subcommands/gui.py(63 行)— 桌面应用启动器

hermes_cli/subcommands/dashboard.py(143 行)— Web Dashboard

apps/desktop/ — Electron 桌面应用源码

二、TUI:终端交互界面

curses_ui.py 是 Hermes 的终端 UI 组件库,基于 Python 标准库 curses 实现。它为 hermes tools 和 hermes skills 提供交互式多选列表,支持键盘导航和模糊搜索。

1. 模糊搜索引擎

TUI 的核心亮点是模糊搜索——输入部分字符即可匹配,且匹配质量有精确的评分算法。这套算法是 TypeScript 版本 fuzzy.ts 的 Python 移植,确保三个界面(TUI、Web、Desktop)的搜索结果完全一致。

📄 curses_ui.py (第 59-110 行)

def _token_score(orig: str, lower: str, token: str) -> float | None:
    """评分一个 token 与目标的匹配度
    
    评分规则(与 TS 版本完全一致):
    - 连续字符匹配:+5 分
    - 词边界匹配:+3 分(如 camelCase 的 O 在 gptO 中)
    - 前缀匹配:+5 分
    - 精确匹配:+20 分
    - 分散匹配:-1~3 分(惩罚)
    """
    score = 0.0
    prev = -1
    search_from = 0
    
    for ch in token:
        idx = lower.find(ch, search_from)
        if idx < 0:
            return None
        
        score += 1
        if prev >= 0 and idx == prev + 1:
            score += 5  # 连续字符加分
        elif prev >= 0:
            score -= min(idx - prev - 1, 3)  # 分散惩罚
        
        if _is_boundary(orig, idx):
            score += 3  # 词边界加分
        if idx == 0:
            score += 5  # 首字符加分
        
        prev = idx
        search_from = idx + 1
    
    # 前缀匹配加分
    if positions[0] == 0 and positions[-1] == len(positions) - 1:
        score += 8
    
    # 精确匹配最高分
    if lower == token:
        score += 20
    
    return score

2. 多选列表与键盘导航

TUI 的另一个核心组件是多选列表,支持上下键导航、空格选中、回车确认。当终端不支持 curses 时,自动降级为纯文本编号列表。

📄 curses_ui.py (第 163-200 行)

@dataclass
class _SearchState:
    """curses 选择器共享的搜索状态"""
    active: bool = False
    query: str = ""

def _reconcile_cursor(filtered, cursor):
    """在过滤后的索引列表中恢复光标位置"""
    if not filtered:
        return cursor, 0
    if cursor not in filtered:
        cursor = filtered[0]
    return cursor, filtered.index(cursor)

def _move_filtered_cursor(filtered, cursor, pos, delta):
    """在过滤列表中移动光标,支持循环"""
    if not filtered:
        return cursor
    return filtered[(pos + delta) % len(filtered)]

三、Electron 桌面应用

Hermes 的桌面应用基于 Electron 构建,提供原生窗口体验。通过 hermes desktop 或 hermes gui 命令启动,自动安装 Node 依赖、构建应用并启动。

1. 启动流程

📄 gui.py (第 14-63 行)

gui_parser = subparsers.add_parser(
    "desktop",
    aliases=["gui"],
    help="Build and launch the native desktop app",
)
gui_parser.add_argument("--source",
    help="通过 electron . 启动开发模式")
gui_parser.add_argument("--build-only",
    help="仅构建不启动")
gui_parser.add_argument("--skip-build",
    help="跳过构建,直接启动已打包应用")
gui_parser.add_argument("--force-build",
    help="强制重新构建")
gui_parser.add_argument("--hermes-root",
    help="覆盖 Hermes 源码根目录")
gui_parser.add_argument("--cwd",
    help="设置初始项目目录")

2. 桌面应用架构

桌面应用技术栈

Electron 主进程

⬇️

Node.js 后端桥接

通过 IPC 与 Hermes CLI 通信

⬇️

React + Svelte 前端

聊天界面 + 会话管理 + 工具调用可视化

⬇️

Hermes Agent 核心

与 CLI/Gateway 共享同一套引擎

四、Web Dashboard

Dashboard 是 Hermes 的 Web 管理界面,提供会话监控、资源状态和技能管理功能。通过 hermes dashboard 命令启动。

📄 dashboard.py (第 1-143 行)

def cmd_dashboard(args):
    """启动 Web Dashboard
    
    Dashboard 提供:
    1. 实时会话监控
    2. 工具调用日志
    3. 记忆/技能管理
    4. 系统状态仪表盘
    """
    # 启动本地 HTTP 服务器
    dashboard_server = DashboardServer(
        port=args.port,  # 默认 8080
        auth=args.auth,  # 可选认证
    )
    dashboard_server.run()

五、三端统一设计

特性 TUI Desktop Dashboard
交互方式 键盘导航 鼠标 + 键盘 浏览器
技术栈 curses Electron + React Flask + HTML
模糊搜索 ✅ 原生支持 ✅ 原生支持 ✅ 原生支持
会话管理 ✅ ✅ ✅
工具可视化 文本 图形化 图形化

📖 系列导航

← 上一讲:第 17 讲:Hermes Agent 源码-Curator 编排器与后台自治

下一讲 →:第 19 讲:国际化与多语言支持

📚 全系列:Hermes Agent 源码解析

Hermes Agent 源码解析 · 第 18 讲 · 2026-07-01

基于 v0.16.0 · NousResearch/hermes-agent

关注公众号「AI技术推荐官」获取更多技术干货

相关学习资料