Hermes WebUI 扩展怎么注册自定义 TTS 引擎并接入播放链路
【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui
如果你自托管了 Hermes WebUI,并且已经有一个本地 TTS 服务(例如跑在127.0.0.1:50021的 VOICEVOX),想让它和内置的 Browser / Edge / ElevenLabs 一起出现在Settings → TTS Engine下拉框里,本文说明如何通过 WebUI 扩展机制完成注册并接入播放链路。完成后的结果是:你注册的引擎会同时被两条播放路径使用——免提语音模式(voice mode)的自动朗读,以及每条消息上的 "Listen" 按钮——核心负责选择和播放,扩展只负责产出音频。
前置条件:扩展的运行边界
注册 TTS 引擎依赖 WebUI 的扩展机制,先确认两点:
- 扩展代码与 WebUI 同源执行,拥有当前登录会话的全部 API 权限。文档明确要求:只启用你自己写的、或你完全信任的扩展;共享给不完全信任的用户时不要启用扩展。
- 扩展的 JS 文件必须能通过 WebUI 的静态扩展目录或一键安装机制注入页面,扩展本身无法注册新的后端路由——TTS 音频由核心播放,扩展的
synthesize只返回音频字节。
扩展资产的注入受 URL 规则约束:必须是同源路径,归一化后以/extensions/或/static/开头,不能带 scheme、host、fragment、反斜杠等。不符合的 URL 会被直接忽略而不是注入,这也是诊断阶段"脚本没生效"最常见的根因。
编写扩展脚本:调用window.registerHermesTtsEngine
在扩展 JS 文件中调用window.registerHermesTtsEngine(descriptor)。descriptor 需要三个字段:
window.registerHermesTtsEngine({ id: 'voicevox', // [a-z0-9_-],且不能是内置引擎 label: 'VOICEVOX (local)', // 显示在下拉框(textContent 插入,无 HTML 注入) // synthesize(text, opts) -> Promise<ArrayBuffer | Blob | TypedArray> 音频数据。 // opts 携带用户已保存的 { voice, rate, pitch }(引擎可以忽略)。 synthesize(text, opts) { return fetch('http://127.0.0.1:50021/...', { /* ... */ }) .then(r => r.arrayBuffer()); } }); // 成功返回 true,descriptor 被拒绝时返回 false以上是docs/EXTENSIONS.md中的文档示例,fetch的目标地址和请求体是占位写法(/...与{ /* ... */ }),需要替换成你自己 TTS 服务的真实合成接口。替换时必须保证该请求最终返回音频字节流。
字段规则:
id:必须满足 slug 规则[a-z0-9][a-z0-9_-]{0,31},且不能遮蔽内置引擎 id(browser、edge、elevenlabs),这三个是保留字。重复注册同一个 id 会就地更新(idempotent),而不是新建。label:以textContent插入下拉框,不是innerHTML,不需要考虑转义。synthesize(text, opts):必须返回音频字节(ArrayBuffer、Blob或 typed array)。核心会强制转换为ArrayBuffer,然后通过和 Edge 引擎完全相同的<audio>生命周期播放(包括语音模式下的 stop/rearm)。promise 被 reject、或结果为空/无效时是优雅失败:"Listen" 按钮弹 toast 提示,语音模式下会允许重新触发朗读,而不是挂死。- 返回值是
true(注册成功)或false(descriptor 被拒绝),扩展可以据此打日志排查。
opts参数携带的是用户在 WebUI 中保存的{ voice, rate, pitch }值;引擎可以选择使用或忽略,这一点由文档明确允许。
把扩展接入 WebUI 并启动
最直接的注入方式是环境变量的手动配置(来自docs/EXTENSIONS.md的 Manual / advanced configuration):
export HERMES_WEBUI_EXTENSION_DIR=/path/to/my-extension/static export HERMES_WEBUI_EXTENSION_SCRIPT_URLS=/extensions/app.js ./start.sh适用条件与说明:
HERMES_WEBUI_EXTENSION_DIR是可选的,覆盖默认的 WebUI 托管目录(STATE_DIR/extensions,例如~/.hermes/webui/extensions/)。一旦设置,它必须指向一个已存在的目录——WebUI 不会自动创建管理员指定的路径,目录缺失或无效等价于扩展被禁用。HERMES_WEBUI_EXTENSION_SCRIPT_URLS中的条目必须是/extensions/下的路径;HERMES_WEBUI_EXTENSION_DIR目录下的文件会以/extensions/...的形式对外提供(例如目录里的app.js对应/extensions/app.js)。静态处理器是沙箱化的:拒绝路径穿越(含编码穿越)、不服务 dotfile、拒绝解析到目录外的符号链接,失败统一返回不暴露本地路径的 404。- 如果不用环境变量,也可以走Settings → Extensions一键安装:安装目标为 WebUI 托管目录,无需任何环境变量,下一次应用外壳渲染时自动加载。
如果你的 TTS 引擎不止一个脚本、或有多个扩展资产,可以用 manifest 文件代替长串环境变量:把extensions.json放在扩展目录内,然后加HERMES_WEBUI_EXTENSION_MANIFEST=extensions.json再启动;manifest 里的裸相对路径会解析为/extensions/<路径>。
验证注册结果与播放链路
按顺序核对以下三点,全部来自文档给出的行为描述:
- 注册调用本身:
window.registerHermesTtsEngine返回true表示成功;返回false表示 descriptor 被拒绝,优先检查id是否合法、是否撞了保留的内置 id。 - 下拉框出现:打开Settings → TTS Engine,你的引擎 label 应出现在 Browser / Edge / ElevenLabs 旁边。能选到它,说明核心已接管选择与播放。
- 两条播放路径:分别用每条消息的 "Listen" 按钮和语音模式的自动朗读各触发一次。合成失败(服务没起、接口报错、返回空数据)时的可观察现象是:"Listen" 按钮弹 toast,语音模式下可重新触发——这是文档定义的优雅失败路径,不是崩溃。
另外两个诊断入口:
- Settings → Extensions面板展示与后端相同的脱敏扩展状态;
- 认证管理员可以调用只读的
GET /api/extensions/status查看注入的资产 URL、manifest 计数、脱敏后的 sidecar 声明和警告码。注意该端点和面板不会返回HERMES_WEBUI_EXTENSION_DIR、解析后的 manifest 路径、原始环境变量值或被拒绝的 URL 字符串,所以"资产没被注入"问题要靠警告码和注入 URL 列表反推。
网络与限制
- 如果
synthesize里调用本地服务(文档示例是 VOICEVOX 的http://127.0.0.1:50021),该请求受页面 CSPconnect-src约束:loopback(http://127.0.0.1:*、http://localhost:*等)已包含在默认策略中,本地服务不需要额外配置;非 loopback 的受信来源需要用HERMES_WEBUI_CSP_CONNECT_EXTRA在启动前追加精确 origin。文档同时要求按调用位置如实声明permissions.network_external。 - 核心拥有选择、下拉项和播放;扩展只产出音频。想改播放行为、加新的后端路由都不在扩展能力范围内——扩展不能注册 WebUI 后端路由。
- 完整契约与更多示例(manifest 结构、URL 规则、
/api/extensions/status字段语义)见 docs/EXTENSIONS.md;该 API 的引入背景记录在 CHANGELOG.md 中 "Extensions can now register a custom text-to-speech engine" 条目,核心播放实现位于 static/boot.js 与 static/ui.js,行为测试在 tests/test_extension_tts_engine_registration.py。
【免费下载链接】hermes-webuiHermes WebUI: The best way to use Hermes Agent from the web or from your phone!项目地址: https://gitcode.com/GitHub_Trending/he/hermes-webui
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考