dsh-voice-input
把语音输入接进 DeepSeek Harness:输入框左侧多一个麦克风按钮,说完话转写结果直接落进输入框,不用切窗口、不用复制粘贴。录音时输入框上方会出现一条实时状态条(电平、计时、边说边出的文字、完成、取消)。

无构建步骤、无运行时依赖:宿主半边只用 Node 内置 fetch / FormData / Blob,浏览器半边只 require react 与 shell 的静态 UI 原语。
- 两种引擎,一个按钮:没配接口时用浏览器自带的语音识别(零配置、边说边出字);配了接口就用你的转写服务(质量更高、可完全离线)。
自动引擎按当前配置自己选。 - 本机后端一键准备:设置页里直接装 / 起本机 Whisper、装 / 起 Ollama、拉模型 —— 宿主运行插件自带的 PowerShell 脚本,你只点按钮,不用去翻命令行。没有 Ollama 的人有安装脚本,已经有 Ollama 的人可以把自己写的启动脚本丢进
user-scripts/,选中 Ollama 时自动调用。 - API Key 不进配置:从 DSH 凭证库按引用读取(默认
VOICE_ASR_API_KEY),每次转写现取 —— 轮换 Key 对下一次录音立即生效,cordis.patch.yml和浏览器页面里永远没有明文。 - 错误直接给出下一步:401 → 换 Key;404 → 地址要不要带
/v1;413 → 缩短录音或调上限;超时 → 调超时或换本地服务;浏览器识别network→ 改用接口引擎。 - 模型侧能自查:注册了
voice_input_status工具,可以直接问 DeepSeek「语音输入为什么没反应」,它读出实际配置并指出该改哪一项。
它长什么样
| 位置 | 内容 |
|---|---|
| 输入框左侧工具行(回形针右边) | 麦克风按钮:空闲时是麦克风图标,录音中是电平条,转写中是转圈 |
| 输入框上方 | 只有录音 / 转写 / 有未处理错误时才出现的状态条:电平、0:07 计时、实时文字、完成、取消录音、知道了 |
| 设置 → 语音输入 | 引擎、服务类型、接口地址、模型、检测本机模型、语言、提示词、API Key、插入方式、自动发送、超时与上限 |
| 设置 → 语音输入 → 本机后端(一键准备) | 三张卡片(本机 Whisper / Ollama / 云端)+ 每个后端的状态与一键动作、脚本设置、自定义脚本、最近一次运行的输出与日志 |
| 模型工具 | voice_input_status:诊断当前是否就绪,指向 Ollama 时还会列出本机哪些模型能听 |
快捷键:Alt+M 开始 / 结束录音;录音中按 Esc 取消且不写入输入框。
环境要求
- DeepSeek Harness
0.1.5-rc.1或更新(@deepseek-ai/dsh-client-connection、dsh-credentials、dsh-tools、schemastery由 harness 以 peer 形式提供)。 - Node.js 22+(宿主半边用到
AbortSignal.any、FormData、Blob)。 - 一个现代浏览器。浏览器引擎需要
SpeechRecognition(Chrome / Edge 有,Firefox 没有);接口引擎需要MediaRecorder+getUserMedia(三者都支持)。
安装
# 先看要改什么
./install.ps1 -DryRun
# 装进 web profile
./install.ps1
# 装完刷新 Web UI,打开 设置 → 语音输入
脚本做三件事:把插件(含 lib/ 与 scripts/)复制到 $DSH_HOME\profiles\<profile>\plugins\dsh-voice-input;创建 user-scripts\ 放你自己的脚本;在 cordis.patch.yml 里加一段**带标记的**托管行(-Uninstall 只删这一段,不动手写的行)。浏览器半边不需要额外声明:它通过包内 package.json 的 dsh.client 被 web 运行时发现。
托管行里同时写好两个目录,所以装完就有能点的一键按钮,不需要手填路径:
# >>> dsh-voice-input (managed by install.ps1) >>>
- insert:
- id: voice-input
name: './plugins/dsh-voice-input/lib/index.js'
config:
localAsrDir: 'C:\Users\you\voice-input\local-asr'
userScriptDir: 'C:\Users\you\voice-input\user-scripts'
# <<< dsh-voice-input <<<
localAsrDir 指向源码树里的 local-asr/,不复制它:那里面是几 GB 的虚拟环境和模型权重,页面只需要找到它的 setup.ps1 / start.ps1。复制完成后脚本还会回读校验 5 个动作脚本确实在安装目录里 —— 目录复制过来但是空的,是「按钮全点了没反应」这种最难查的故障。
写入是「临时文件 + 改名」的原子替换,写完还会回读校验那段标记行确实在文件里 —— 因为正在运行的 DSH(尤其是它打开的「插件」设置页持有 profile 补丁层的一份快照)有可能把自己的视图写回这个文件,把刚装的这一行抹掉。脚本检测到这种情况会明确报错并退出,而不是留下一个看起来装好了、实际没装的插件。遇到这个报错:重启 DSH,再跑一次脚本。
装完后如果「设置」里看不到语音输入,先确认
cordis.patch.yml里还有id: voice-input那段;没有就重启 DSH 再装一次。
卸载:
./install.ps1 -Uninstall
不要和
dsh plugin --profile web add dsh-voice-input同时用:两者解析到同一个包,而同一个包有两个活跃 Loader 来源是组合错误。
配置:四条路,从快到好
1. 什么都不配(浏览器引擎) 刷新页面直接点麦克风。Chrome / Edge 会用它自己的在线识别,边说边出字。缺点很实在:它依赖浏览器厂商的服务,中国大陆通常不可用(表现为一直不出字,或状态条报「浏览器识别服务不可达」)。
2. 配一个云端转写接口(推荐) 设置 → 语音输入 → 点「快速填充」里的一颗预设,再粘贴 API Key、保存。预设会一次填好服务类型、API 地址与模型名:
| 预设 | 服务类型 | API 地址 | 模型 |
|---|---|---|---|
| OpenAI | OpenAI 兼容 | https://api.openai.com/v1 |
whisper-1 |
| 硅基流动 | OpenAI 兼容 | https://api.siliconflow.cn/v1 |
FunAudioLLM/SenseVoiceSmall |
| Groq | OpenAI 兼容 | https://api.groq.com/openai/v1 |
whisper-large-v3-turbo |
| Ollama | Ollama | http://127.0.0.1:11434/v1 |
由「检测本机模型」填入 |
| 本地 whisper.cpp | OpenAI 兼容 | http://127.0.0.1:8080/v1 |
whisper-1 |
只要服务兼容 OpenAI 的 POST /audio/transcriptions(multipart,file + model),就能直接用;apiBase 填服务根地址,插件在其后拼 /audio/transcriptions。
3. 本机 Ollama(结论:目前转写不了)
Ollama 自己路由 POST /v1/audio/transcriptions(已实测:multipart 的 file + model 会进入它的音频管线,不是 404),但它要求模型带音频投影(audio / mmproj),而 Ollama 0.34 的官方模型库里一个都没有。这一点是实际验证过的,不是推测:
| 实测 | 结果 |
|---|---|
ollama pull gemma3n:e2b(Ollama 模型页明确宣传「Audio Data Extraction: Transcribe spoken language」,5.24 GB) |
拉下来后 capabilities 只有 ["completion"],model_info 40 个键里没有任何 audio 键 |
用 gemma3n:e2b 请求 /v1/audio/transcriptions |
400 Multimodal data provided, but model does not support multimodal requests. —— 这个转换连多模态都不支持 |
| 用文本模型请求同一接口 | 500 audio input is not supported - hint: ... provide the mmproj |
| 上游状态 | 音频输入仍是未合并的提案(ollama#11798、ollama#15243) |
插件对这块的处理是:先问清楚,再给出路,而不是把一个 500 丢给用户。它读取 GET /api/tags,对每个模型 POST /api/show 检查 model_info 里有没有 *.audio.* 键(不能只看 capabilities:在这个版本里能听和不能听的模型都只报 completion),逐个标注 可听 / 仅文本 / 未检测,并在上传之前就把结论讲明白。「模型名不存在」和「模型不会听」因此是两条不同的提示,各自带上本机名单。
判定逻辑是对的,坏消息是它判定出的结果是「本机没有能听的模型」,而且现在也拉不到 —— 这正是 gemma3n:e2b 那次 5.24 GB 下载证明的。所以本地转写走第 4 条路。
4. 本地转写(本地推荐 whisper.cpp / faster-whisper) 起一个说 OpenAI 协议的本地转写服务,把「服务类型」留在「OpenAI 兼容」、地址指向它,即可完全离线:
- faster-whisper-server:原生就是 OpenAI 的
/v1/audio/transcriptions,插件直接可用。 - whisper.cpp 的
whisper-server:只有/inference一个端点,需要用它的--request-path/--inference-path把路径对齐成/v1/audio/transcriptions(参数名取自它自己的 README;本机没有验证过这条,因为它的 v1.9.4 release 不带 Windows 二进制)。 - 任何其他兼容 OpenAI
/audio/transcriptions(multipart,file+model,返回{text})的服务都行。
而且你不需要把地址填进去。 没配 apiBase 时,插件会依次探测 127.0.0.1 的 8081 / 8080 / 8000 / 9000 端口(只探本机,永远不碰远端地址),发现 OpenAI 兼容的转写服务就直接用它。设置页的「自动发现本机转写服务」可以关掉。
一条命令就能用的本地方案:local-asr/
仓库里的 local-asr/ 是一个完全离线的 Whisper 服务,已经在这台机器上装好、跑通、实测过:
cd local-asr
.\setup.ps1 # 建环境 + 装依赖 + 下载模型(只需一次,约 600 MB)
.\start.ps1 # 启动,前台运行,Ctrl+C 停止
然后刷新 DSH 网页,点麦克风说话即可 —— 不需要在设置里填任何东西。
实测结果(本机 CPU,int8):
| 输入 | 大小 | 耗时 | 结果 |
|---|---|---|---|
| 5.55 秒中文(16 kHz WAV) | 173 KiB | 7.4 s | 欢迎大家来体验打磨院推出的语音识别模型 |
| 同一段(webm/opus,浏览器真实格式) | 61 KiB | 7.7 s | 同上 |
浏览器录出来的是 webm/opus 而不是 WAV,所以两种容器都测了 —— 服务端用 PyAV(自带 ffmpeg 库)解码,不需要系统装 ffmpeg。
为什么是这些参数、端口为什么是 8081 而不是 8080、GPU 怎么开,都写在 local-asr/README.md 里(每一条都是本机实测后定下来的)。
服务类型(provider)的含义:
| 值 | 行为 |
|---|---|
auto |
按地址判断:指向本机、或其 /api/tags 有响应就当作 Ollama,否则按 OpenAI 兼容处理。非本机地址永远不会被探测,不会朝云端发多余的 /api/tags。 |
openai |
只按 OpenAI 契约处理,不做任何探测。 |
ollama |
强制按 Ollama 处理:启用本机模型检测与上传前的模型校验。 |
设置页里的一键准备(脚本动作)
「设置 → 语音输入 → 本机后端(一键准备)」把「去命令行跑个脚本」变成点一下。三张卡片,每张都先报告状态、再给出此刻能做的事:
| 卡片 | 状态从哪来 | 能点的动作 |
|---|---|---|
| 本机 Whisper(推荐) | scripts/local-asr-status.ps1 探测 8081/8080/8000/9000 的 /health |
检查状态、安装 / 重装(local-asr/setup.ps1)、启动(local-asr/start.ps1)、把发现的地址填进接口地址 |
| Ollama | scripts/ollama-status.ps1 读 ollama 命令 + /api/tags |
检查状态、安装 Ollama、启动 Ollama、拉取模型(要填模型名) |
| 云端服务 | 不需要脚本 | —— 填地址与 Key 即可 |
动作脚本都是插件自带的、纯 ASCII 的 PowerShell:
| 动作 id | 脚本 | 说明 |
|---|---|---|
local-asr.status |
scripts/local-asr-status.ps1 |
只读探测,前台执行 |
local-asr.setup |
<localAsrDir>\setup.ps1 |
后台执行,日志实时落盘 |
local-asr.start |
<localAsrDir>\start.ps1 |
后台执行;页面会轮询到「服务已运行」为止 |
ollama.status |
scripts/ollama-status.ps1 |
只读:是否安装、版本、服务是否在跑、有几个模型 |
ollama.install |
scripts/install-ollama.ps1 |
官方安装包,静默安装;镜像源逐个探测后才下载 |
ollama.start |
scripts/start-ollama.ps1 |
幂等;已在跑就直接返回。前台等待(最多 15 秒),所以页面能直接说清是「本来就在跑」「刚起来」还是「起不来」,而不是先回一句「已启动」 |
ollama.pull |
scripts/pull-ollama-model.ps1 |
按 -Model 拉取,模型名先过正则 |
选中 Ollama 时自动调用脚本。 在「服务类型」里点 Ollama 会同时做三件事:把接口地址填成 http://127.0.0.1:11434/v1(空着的时候 —— 没有地址的「Ollama」在宿主那边会被判回 OpenAI 兼容,等于没选)、读一次真实状态、运行你在「脚本设置」里指定的脚本。脚本留空表示自动判断:装了但没在跑就启动它,没装则只提示「点安装 Ollama」,不会替你下载 700 MB。想完全手动就关掉「切到 Ollama 时自动运行」。选中的脚本也可以是你自己放进 user-scripts/ 的那个。
「启动成功」不等于「能用」。 这是这个后端唯一真正反直觉的地方,所以页面直接给结论,不让你自己踩:选完 Ollama 之后它会读一遍本机模型清单,如果没有一个模型能听音频,卡片上会出现红字结论,动作行里多一个 「改用本机 Whisper」 按钮 —— 点一下就切到本机 Whisper(已经在跑就只改地址;没在跑就顺手启动),不用手动改三个字段再保存。用 Ollama 录音失败时,输入框上方的状态条也会出现同一个按钮。原因很简单:0.34 的官方模型库里没有带音频投影的模型,所以「服务起没起」和「能不能转写」是两件事,前者的成功不能说明后者。
已经有 Ollama 的人:把你的启动脚本放进 user-scripts/(*.ps1),它就会出现在「自定义脚本」里;在「切到 Ollama 时运行的脚本」里选它,之后每次切到 Ollama 都会调用。user-scripts/example-start-ollama-audio.ps1.example 是一个可用的模板(起 ollama serve、按需 ollama pull、输出机器可读状态)。
DSH_RESULT <json> 一行是脚本与页面之间的约定:有它,页面把结果折叠成状态;没有也不影响,退出码为 0 即成功。日志写在插件目录下的 .script-logs\<动作>-<时间戳>.log(保留 3 天),「查看日志」读的就是最新那份;如果安装目录不可写(比如装在 Program Files 下),会自动落到系统临时目录并在页面里如实显示该路径。
这个能力的边界
让网页请求变成进程,是插件里唯一这样的地方,所以形状被刻意收窄:
- 浏览器只报一个动作 id,永远不报路径、不报命令行;id → 脚本文件的映射完全在宿主一侧。
- 脚本只从三个来源解析:插件自带的
scripts/、配置的localAsrDir、以及userScriptDir里以user:<文件名>形式暴露的*.ps1(文件名须匹配^[A-Za-z0-9][A-Za-z0-9._-]{0,63}\.ps1$)。目录遍历形状的 id 会被当作「没有这个动作」拒绝。 - 唯一的自由输入是模型名,先过
^[A-Za-z0-9][A-Za-z0-9._-]{0,63}(/…)?(:…)?$才会作为参数传给-Model。 - 关掉「允许设置页运行脚本」(
enableScripts)后所有动作一律拒绝。 - 每次调用都写宿主日志;路由本身挂在
ctx.connection.fetch上,Host/Origin 校验与签名 Cookie 鉴权先由 carrier 做完。 - 插件不认识你的脚本:它只按文件名启动,不读内容、不改内容。所以
user-scripts/里的东西写的是什么就执行什么 —— 那是你自己放进来的文件,请当作和手动跑它一样对待。
使用
- 光标放在输入框(或先打几个字,转写会接在后面)。
- 点麦克风按钮,或按 Alt+M。
- 说话。浏览器引擎会把中间结果实时写进输入框;接口引擎在状态条上显示电平和计时。
- **点状态条上的「完成」**结束录音并转写(也可以再点一次麦克风按钮,或再按一次 Alt+M)。接口引擎此时上传并转写,结束后把文字插入输入框。
- 想放弃这次录音:点「取消录音」,或按 Esc。
插入规则(追加 模式下):中文接中文不加空格、中英之间加一个空格、左括号后不加空格 —— 尽量贴近手写习惯。开启「转写完成后自动发送」后,文字落进输入框就会自动发送(插件会等输入框真正提交了新内容再发送,不会把上一次的内容发出去)。
设置项
设置页写的是 settings.yaml 里的 voice-input 命名空间;composition 那一行只放默认值。
| 字段 | 默认 | 说明 |
|---|---|---|
engine |
auto |
auto / browser / endpoint |
provider |
auto |
auto / openai / ollama,见上表 |
apiBase |
空 | 服务根地址,例如 https://api.openai.com/v1;留空 = 交给自动发现 |
autoDiscover |
true |
没填地址时探测本机 8081/8080/8000/9000 上的 OpenAI 兼容转写服务 |
model |
空 | 服务商文档里的模型名;留空时 OpenAI 兼容接口用约定名 whisper-1 |
language |
zh |
ISO-639-1;浏览器引擎据此选识别语言,填 auto 交给对方判断 |
prompt |
空 | 交给模型的上下文提示,明显改善专有名词与标点 |
apiKeyRef |
VOICE_ASR_API_KEY |
凭证引用名 |
insertMode |
append |
append 追加 / replace 替换整个输入框 |
autoSubmit |
false |
转写完成后是否自动发送 |
maxSeconds |
120 |
单次最长录音,到点自动停止并转写 |
timeoutMs |
60000 |
单次转写请求超时 |
maxAudioBytes |
12582912 |
单次录音上限(12 MiB),读取时即生效 |
enableTool |
true |
是否注册 voice_input_status 工具 |
enableScripts |
true |
是否允许设置页运行安装 / 启动脚本 |
localAsrDir |
安装时写入 | 存放 setup.ps1 / start.ps1 的目录(绝对路径),local-asr.* 动作靠它解析 |
userScriptDir |
安装时写入 | 自定义脚本目录(绝对路径);其中的每个 *.ps1 都是一个可运行动作 |
ollamaScript |
空 | 切到 Ollama 时运行哪个动作;留空 = 按状态自动判断 |
autoRunScript |
true |
把「服务类型」切到 Ollama 时是否自动运行 ollamaScript |
scriptTimeoutMs |
600000 |
前台等待型脚本的最长运行时间,超时会被终止并报告 |
超出这个页面能表达的约束(比如 maxSeconds 必须是正整数)由宿主的 validate 钩子在写入前拦下,不会存进去一半。
凭证
API Key 存在 $DSH_HOME\.credentials.yaml 的 refs 段(设置页会写,也可以手工编辑):
refs:
VOICE_ASR_API_KEY: sk-xxxxxxxx
查找优先级(由 dsh-credentials-local 决定):启动环境变量 > 凭证文件 > 项目 .env > $DSH_HOME\.env。启动 dsh 前 shell 里已有的同名变量会盖过凭证文件,状态行会如实显示来源。
已保存的 Key 不会回显 —— 凭证库只回答「是否已配置 / 来源」,页面拿不到值。想复核就重新粘贴一次点「测试连接」,或者问模型「语音输入为什么没反应」。
安全边界
- 音频只经过本机:录音以原始
audio/*字节 POST 到 DSH Web 服务器自己的/api/voice-input/transcribe,再由宿主转发给服务商。不上传第三方、不落盘、不写日志。走ctx.connection.fetch注册,所以 Host/Origin 校验和签名 Cookie 鉴权由 carrier 先做完了 —— 局域网里的陌生请求到不了这个路由,也就拿不到凭证。 - 按需取 Key:每次转写现取,插件不缓存、不打日志,也没有任何把 Key 写进配置的代码路径。
- 凭证库不是隔离:它以文件权限保护,但 agent 的工具进程以同一个 OS 用户运行,因此读得到该文件。要真正隔离密钥,需要换一种存储方式。
- 浏览器引擎的识别完全在浏览器与浏览器厂商之间进行,插件不参与,也无法审计其隐私行为。
已知限制
- 本地方案在 CPU 上是 0.7× 实时:5.55 秒语音约 7.5 秒转完。短句听写没问题,长录音要等;想更快就按
local-asr/README.md里写的方式开 GPU。 - 本地服务要自己启动 —— 但现在可以是页面里的一下:
local-asr/start.ps1是前台进程,关掉窗口服务就停了。装好localAsrDir后,设置页的「启动本机 Whisper」会把它拉起来并轮询到就绪;没装的话页面会如实报告「本机 8081 / 8080 / 8000 / 9000 上都没有转写服务在监听」。 - Ollama 目前不能转写:它的音频接口要求模型带音频投影(audio / mmproj),而 0.34 的官方模型库里没有这样的模型(
gemma3n:e2b实测是纯文本转换)。插件的上传前校验会把这件事讲清楚。 - 「服务起来了」和「能转写」是两件事:
ollama.start会在 15 秒内如实回答「本来就在跑 / 刚起来 / 起不来」,但一台跑着 4 个文本模型的 Ollama 依然一个字都转不了。所以选完 Ollama,页面会接着读一遍模型清单,没有能听的模型就直接给红字结论 + 「改用本机 Whisper」按钮;录音失败时状态条也给同一个按钮。 - Ollama 的对话模型不适合直接转写:
/v1/audio/transcriptions在 Ollama 那边走的是聊天模板,所以插件会在没配置「提示词」时补一句「只输出转写文本」。若你改了提示词,请保留这句话。 model_info探测有预算:模型超过 16 个时,只判定前 16 个(当前配置的模型优先),其余标为「未检测」而不是「仅文本」。- 新建会话的第一屏没有麦克风:
conversation.input.left与 shell 自带的回形针按钮受同一条约束(sessionId === undefined时不渲染)。选中工作区/进入会话后即出现。 - 转录不进会话记录:转写只是写进输入框,和键盘输入没有区别;插件不保存音频,也不保存历史记录。
- 不能用语音操作模型侧的会话:录音是浏览器交互,模型无法替你按下麦克风。它只能回答「为什么不能用」。
- 浏览器引擎不显示电平:
SpeechRecognition自己占着麦克风,拿不到音频流,所以那条路径用脉冲点代替电平条。 - 取消是即时的,上传不是:转写请求一旦发出无法撤回(没有取消上传的按钮),Esc 只在录音阶段有效。
- 已经加载过客户端 bundle 的 profile 需要刷新页面才能拿到新版本。
开发
./install.ps1 -DevDeps # 把本目录的 node_modules 指向 profile 的(junction),仅供测试
npm test # 离线契约测试 + 脚本动作测试 + 已安装副本验证(78 项,不需要浏览器)
npm run test:smoke # 只跑离线契约测试
npm run test:scripts # 只跑脚本动作测试(含真实 PowerShell 执行)
npm run test:installed # 只验证 profile 里那份安装副本(没装就跳过)
npm run test:local # 对着本机 Whisper 服务跑真实语音端到端(没服务就跳过)
npm run test:ollama # 对着真实 Ollama 跑一遍(没有服务就自动跳过)
test/smoke.mjs不需要浏览器也不需要网络,62 项断言:浏览器半边(三个座席、inject列表、199 键中英词典的键集 / 占位符 / 重复键,以及在真实 hooks 运行时下渲染出的每一张后端卡片、每个按钮的接线、以及点击之后界面变成什么样)、宿主半边(六条 Connection 路由、字节上限、415/413、各错误码、上传前的模型校验)、本地服务自动发现(/models→/health→ 音频路由三级探测、autoDiscover开关、已配置地址优先于发现),以及 Ollama 那层嵌套 JSON 的 500。test/scripts.mjs19 项:结果行解析、白名单与目录遍历拒绝、模型名正则、enableScripts开关、非对象请求体、起不来的动作必须报失败而不是成功,以及真实执行(后台动作返回 pid 且日志里有输出、前台动作拿到退出码与DSH_RESULT、日志路由拒绝非动作 id、超时被终止)。test/installed-live.mjs3 项:挂载 profile 里那份安装副本,确认六条路由都在、5 个动作脚本真的复制过去了、并且真能跑起来(这一条抓到过「日志目录在只读安装目录里会 EPERM」)。test/local-asr-live.mjs对着真实本机服务跑:发现、状态投影、真实中文语音、以及浏览器真实容器 webm/opus。test/ollama-live.mjs对着真实 Ollama 跑 14 项,其中包括三个「设计前提」的验证(auto认出 Ollama、/v1/audio/transcriptions确实被路由、模型音频判定与model_info一致)。-UninstallDevDeps只删那个 junction。
文件
| 文件 | 角色 |
|---|---|
cordis.patch.yml |
bundle 层:挂载宿主半边的那一行 |
install.ps1 |
装进 profile / 卸载 / 干跑 / 开发依赖链接 |
lib/index.js |
宿主半边与包根:配置、凭证解析、服务类型判定、自动发现、路由注册、settings 命名空间 |
lib/asr.js |
转写客户端:multipart 组装、超时、错误映射、响应宽容解析 |
lib/local.js |
本机转写服务的自动发现(三级探测 + 短期缓存 + 只探回环地址) |
lib/ollama.js |
Ollama 支持:根地址推导、/api/tags + /api/show 模型发现与音频能力判定、服务类型探测、上传前校验 |
lib/routes.js |
六条 /api/voice-input/* 路由:流式字节上限读取、状态投影、本机模型清单、动作清单 / 执行 / 日志 |
lib/scripts.js |
命名动作执行器:白名单解析、参数校验、后台执行与日志、超时与结果行解析 |
lib/tools.js |
voice_input_status 工具 |
lib/client.js |
浏览器半边:麦克风座席、实时状态条、设置分页(含本机后端一键准备,手写 bundle,无构建) |
scripts/ |
插件自带的动作脚本(纯 ASCII 的 PowerShell) |
user-scripts/ |
放你自己脚本的目录(示例模板 + 说明) |
local-asr/ |
自带的完全离线 Whisper 服务(见 local-asr/README.md) |
test/harness.mjs |
各套件共用的挂载与请求派发 |
test/smoke.mjs |
离线契约测试 |
test/scripts.mjs |
命名动作执行器的契约与真实执行测试 |
test/installed-live.mjs |
对 profile 里那份安装副本的验证(可跳过) |
test/local-asr-live.mjs |
对真实本机转写服务的端到端验证(可跳过) |
test/ollama-live.mjs |
对真实 Ollama 的在线验证(可跳过) |
许可
MIT
No comments yet. Be the first to write one.