跳转至正文
ColliePWA

08/Documentation

语音输入与 Web Push

输入框中的麦克风,以及 agent 等待你操作时的通知

这两项功能默认均已禁用。您可以在编辑器中启用麦克风按钮,并启用在 agent 等待输入时触发的浏览器通知。

语音输入(可选)

一个输入框中的麦克风按钮,以及“设置”中的一个免提开关。点击按钮,说话,转录文本就会出现在消息框中供你查看并发送。开启免提时,它会自动为你发送:走的是和键入消息相同的受保护回复路径,绝不绕过。

只要输入框为空,麦克风就是行尾的圆形按钮;你键入的第一个字符会将其变回“发送”。你要么口述消息,要么键入消息,因此只有一个主要操作,而不是两个操作争夺输入框的宽度。

在运行 collie stt setup 之前,它并不存在。 不绘制按钮,没有音频离开手机,不保存凭据,不运行子进程。是不存在,而不是被禁用。提供商有两种:

提供商具体含义
openai-compatible任何支持 POST /audio/transcriptions 的端点:公共 OpenAI API、云端 Whisper 克隆版或 同一台机器上的本地引擎,这是零出站流量的选择下方)。
codex借用你已信任的 codex 二进制文件获取短期令牌。无需新账户,无需新密钥,以及一个包含同意步骤且你必须键入 yes私有、不受支持 端点(下方)。

设置是一项 CLI 操作,原因与 配对 相同:该接口接收凭据,因此应当在主机的键盘上完成。没有 Web 设置表单。

$ bin/collie stt setup
Which speech-to-text provider?
  openai-compatible  any endpoint that speaks POST /audio/transcriptions —
                     the public OpenAI API, or a local whisper.cpp / parakeet.cpp
                     server, which is the zero-egress choice and the one to prefer.
  codex              borrow your own `codex` sign-in. No new key, no new account —
                     and a private endpoint that may break without notice.
provider [openai-compatible]:
The API base, INCLUDING its version prefix — the provider appends /audio/transcriptions.
  local  http://127.0.0.1:8080/v1     (whisper.cpp / parakeet.cpp — nothing leaves the host)
  cloud  https://api.openai.com/v1    (room audio leaves this machine)
base URL: http://127.0.0.1:8080/v1
The model the endpoint understands. Empty takes Collie's default, gpt-transcribe.
model [gpt-transcribe]: whisper-1
API key [none]:
The language you speak, as a two-letter ISO-639-1 code — en, de, tr, ja.
LEAVE IT EMPTY to let the model detect it, which is what you want if you mix languages in one
sentence. Name one only if short clips keep coming back in a language you did not speak: a few
seconds of accented audio is too little for the model to detect from, and it guesses.
spoken language [auto-detect]: en
✓ speech-to-text configured — /home/you/.local/state/collie/stt.json (owner-only)
  Live immediately — no restart needed. The bridge re-reads this file per request.
  Check it end to end with `collie stt test`.

上述每个问题都有对应的 flag(--provider · --url · --model · --key · --lang),因此配置运行不需要终端。将密钥留空是一种受支持的模式:调用无密钥端点时完全不带 Authorization 请求头,而不是带一个空请求头。

仅在出现一种失败情况时才值得设置口述语言。 留空(默认值)时,模型会自行检测语言,这正是在一句话中混合两种语言的人所需要的。如果 片段总是以你未说过的语言返回,请设置此项:几秒钟带口音的音频不足以完成检测,模型会进行猜测。可以使用双字母代码,或由 Collie 为你缩减范围的地区标签(en-GBen)。它仅适用于 openai-compatible 提供商;codex 端点不接受语言参数,collie stt status 会明确指出这一点,而不是让你误以为支持。

较长的录音会获得较长的超时限制。 浏览器对单个片段的时间预算是该片段大小的函数,而非固定数值:它假定上行速率持续为 256 kb/s,并在此基础上加上桥接器自身的提供商超时上限,因此 8 MiB 的最大值允许略低于六分钟的时间。Collie 愿意录制的片段就是它愿意等待的片段。上传进行期间,Collie 会停止轮询并停止升级连接横幅的提示状态:手机上行被你自己的音频占满不是停机故障,绝不能被报告为故障。

是否生效? stt test 会通过真实服务商发送 0.2 秒生成的静音音频,手机能录制的每种容器格式各发送一次:

$ bin/collie stt test
provider: openai-compatible (http://127.0.0.1:8080/v1, model whisper-1, language en)
sending:  0.2 s of generated silence as audio/wav (the setup probe) … ✓ 214 ms
  transcript: (empty) — expected from silence, and the empty answer still proves the pipeline.
sending:  0.2 s of generated silence as audio/webm;codecs=opus (Chrome, Android, Firefox) … ✓ 198 ms
sending:  0.2 s of generated silence as audio/mp4 (Safari, iOS) … ✓ 190 ms

空转录结果即为通过:静音转录结果为空,而我们要验证的正是这个往返过程。如果失败,错误信息会指明其类型(身份验证、端点、响应格式)。然后在手机上重新加载 Collie:消息框旁会出现一个麦克风。collie stt status 会说明已配置的内容以及各项设置的来源(文件,或优先级更高的环境变量);collie stt off 会移除 stt.json,按钮随即消失,无论哪种操作都无需重启。

容器支持取决于具体服务商

手机从不录制 WAV。它在 Chrome、Android 和 Firefox 上录制 WebM 容器的 Opus,在 Safari 和 iOS 上录制 MP4 容器的 AAC,并直接按原样发送这些字节。能转录 WAV 的服务商仍可能对这两种格式返回 400,导致每次听写都因“refused”而失败,而 stt test 看起来却正常。这就是 stt test 发送全部三个音频片段的原因:在配置阶段而非手机端发现拒绝情况。

一个于 2026-09-01 在 OpenRouter 的 POST /v1/audio/transcriptions 上验证的案例:

格式mistralai/voxtral-small-24b-2507-sttopenai/whisper-large-v3-turbo
wav
ogg/opus
webm/opus否,400
mp4/m4a AAC否,400

解决方法在于模型,而非密钥:将同一个 OpenRouter 密钥指向支持全部四种格式的 openai/whisper-large-v3-turbo

bin/collie stt setup --provider openai-compatible \
  --url https://openrouter.ai/api/v1 --model openai/whisper-large-v3-turbo --key <key>

被拒绝的转录现在会指明上游状态码及发送时使用的容器格式,因此手机上的错误信息会显示服务商拒绝了哪种格式。(#148,感谢 @drewbitt)

零出站流量:将其指向你自己的引擎

选择 openai-compatible 提供商的原因是:为其提供本地基础 URL,房间内的音频绝不会离开主机。有两个引擎提供与 OpenAI 兼容的转录端点:whisper.cpp 自带的 server,以及 mudler/parakeet.cpp(MIT)。按照各自的说明构建或安装其中一个,在回环地址上运行它,然后将 --url 指向它:

bin/collie stt setup --provider openai-compatible --url http://127.0.0.1:8080/v1

这就是全部的集成逻辑:Collie 不关心由哪个引擎响应。

Mistral 的 Voxtral 无需专门支持,遵循此约定的其他任何组件也一样,这就是抽象接口的意义。vLLM 在 /v1/audio/transcriptions 上提供开放权重的 Voxtral 模型,因此本地模型与任何其他引擎使用相同的 --url。托管模型则是发送给 Mistral 自身基地址的相同请求:

bin/collie stt setup --provider openai-compatible \
  --url https://api.mistral.ai/v1 --model voxtral-mini-latest --key <key> --lang en

Voxtral Mini Transcribe 支持 13 种语言,并接受 Collie 已在发送的相同 ISO-639-1 language 字段。在信任它之前先用 collie stt test 验证:"兼容 OpenAI" 是每个端点自身的声明,该指令正是用于检查此项。

codex 提供方:你所接受的内容

collie stt setup --provider codex 会输出同意声明块并暂停,直到你输入 yes。直白地说:录音会发送到通过 你的 登录授权的 未记录且不受支持的 ChatGPT 端点,因此你的 ChatGPT 账号将承担速率限制和封禁风险,并且它可能在没有任何通知的情况下失效。

Collie 优先使用自身名称请求该端点。仅当该真实身份被拒绝时,它才会回退到 Codex CLI 的请求头,且该回退逻辑会写入配置,以 collie stt status 能够回读的形式保存。Collie 绝不会读取或存储 ~/.codex/auth.json;你已信任的二进制文件仍然是唯一接触它的组件。

上述所有内容的推理依据(为何被拒绝两次、发生了什么变化以及接口为何设计成这样)见 ADR 0029

Web Push(可选)

默认禁用。设置需要三个步骤。发送端库(web-push)在构建期间作为可选依赖项引入:

collie push-keys     # 1. generate + write the VAPID keys
collie restart       # 2. Collie reads them at start
#                      3. on your phone: Settings → notifications

push-keys 命令生成密钥对,并将文件权限模式为 600 的 COLLIE_VAPID_PUBLICCOLLIE_VAPID_PRIVATE 写入活动的 .env,在二进制安装中为 ~/.config/collie/.env,在 Herdr 安装中为 Herdr 插件配置目录中的相应文件。

传入联系 URI 作为参数以设置 RFC 8292 subject 声明:

collie push-keys mailto:you@example.com

在由 Herdr 管理的安装中,这两个步骤均以 action 形式提供(herdr plugin action invoke push-keys --plugin herdr.collierestart)。Herdr action 不接受位置参数,因此设置 subject 需要在 shell 中直接运行命令。

密钥处理细节:

除非传入 --force,否则该命令拒绝覆盖现有密钥。更换密钥会使所有当前订阅失效,要求每台设备重新订阅后才能再次接收通知。在现有配置上提供 subject 参数仅更新联系地址,并保留当前密钥。

注意。 在 0.8.0 之前的 Herdr 版本中,操作固定为初始插件安装期间缓存的集合(ADR 0006)。在运行 herdr plugin install 之前,push-keyspush-test 操作不会出现。请改用直接运行 bash scripts/collie-ctl.sh push-keys。包装脚本会将命令直接传递给二进制文件。

测试所有已订阅设备的推送路径:

collie push-test                     # or: push-test "Title" "Body"

推送需要一到两秒。如果命令报告推送已禁用,请重启服务以便加载生成的密钥。如果报告没有已订阅的设备,请在手机浏览器中完成步骤 3。

Web Push 需要安全上下文(HTTPS)。这由 tailscale serve(MagicDNS 证书)或终止 TLS 的外部反向代理(变体 C)提供。纯 HTTP 配置(COLLIE_SERVE_MODE=http)缺少安全上下文,浏览器会禁用“设置”中的订阅控件。

当 agent 进入 blockeddone 状态时,Collie 会发送通知,并将 agent 消息放入正文中。点击通知会直接在 Web UI 中跳转到该 agent。

由于主屏幕重新安装和 service-worker 重置会创建新端点且不一定会返回 HTTP 410,失效订阅可能会随时间累积。当设备重新注册时,Collie 会更新记录。你可以直接查看和删除已存储的端点:

# one line per device: service, since, user agent, endpoint tail
bin/collie push list
bin/collie push forget <substring>   # or: push forget --all

在 GitHub 上编辑本页