dsh-web-search-ddg
aooyoo
Zero-token DuckDuckGo search provider for the DeepSeek Harness (DSH) web seam — local headless browser, no API key, no m…
PROJECT TOPICS
PROJECT README
在 dsh web 界面里按住快捷键说话,语音识别成文本后自动作为用户消息发送给 agent,实现不用打字操控 DeepSeek Harness。
这一节写给负责安装/维护本插件的 agent:照步骤执行即可,每步都标了文件路径、要插入的确切内容和幂等注意。
~指用户主目录(Windows 下即C:\Users\<用户>)。
npx @deepseek-ai/dsh web(dsh CLI 可用)。~/.dsh/profiles/web/,里面有 package.json 和 cordis.patch.yml。把仓库内容复制到 ~/.dsh/plugins/dsh-voice-input/,最终结构必须是:
~/.dsh/plugins/dsh-voice-input/
├── package.json
├── README.md
└── lib/
├── index.js # host 半(Node 侧)
└── client.js # browser 半(浏览器侧)
不要带 node_modules/、.git/,也不要复制运行时才生成的 ~/.dsh/voice-input.config.json(里面有 apiKey)。
编辑 ~/.dsh/profiles/web/package.json,在 dependencies 里加一行(已存在则跳过):
"dsh-voice-input": "file:../../plugins/dsh-voice-input"
路径是 profile 目录的相对路径(profiles/web → 上两级 → plugins/dsh-voice-input)。加完在 profile 目录跑一次安装让 symlink 生效(npm install,或由 dsh 启动时自动处理)。
编辑 ~/.dsh/profiles/web/cordis.patch.yml,在顶层数组里 insert: 列表中追加(同一个 id 不要重复):
- id: voice-input
name: dsh-voice-input
id 是 loader 内部标识(其它配置可用它定位),name 必须等于 package.json 的包名。config: 段可省略——它只是默认值/base 层,前端填的会覆盖。
npx @deepseek-ai/dsh web
若报 EADDRINUSE: address already in use 127.0.0.1:3080:说明已有一个实例在跑,这不是插件问题。要么直接用它,要么先停掉旧的(Windows:netstat -ano | findstr :3080 找到 LISTENING 的 PID,再 taskkill /PID <pid> /F)。
# host 半已加载:应返回 {engine, shortcut, xiaomiCloud:{...hasKey}, ...}
curl http://127.0.0.1:3080/voice-config
# browser 半已装配:应返回 JS,开头是 window.__ModuleLoader__.load
curl http://127.0.0.1:3080/plugins/dsh-voice-input/client.js
两个都 HTTP 200 即装配成功。再让人在浏览器打开 http://127.0.0.1:3080,输入框右侧应出现🎤和⚙。
推荐让人在浏览器点⚙填。agent 也可直接写 ~/.dsh/voice-input.config.json(含 key,勿提交 git):
{
"engine": "xiaomi-cloud",
"shortcut": "ctrl+m",
"confirmBeforeSend": true,
"xiaomiCloud": {
"baseURL": "https://api.xiaomimimo.com/v1",
"model": "mimo-v2.5-asr",
"language": "auto",
"apiKey": "<小米云 key>"
}
}
分层优先级:该文件(前端层)> cordis.patch.yml 的 config:(base)> 内置默认。
| 现象 | 根因 | 处理 |
|---|---|---|
启动报 EADDRINUSE ... 3080 |
已有实例占用端口 | 用现有实例,或 taskkill 掉旧的再起 |
识别报 HTTP 404 |
误把小米当 OpenAI /audio/transcriptions |
小米是 /chat/completions,确认 engine: xiaomi-cloud 且插件为最新 |
识别报 HTTP 400 base64 not valid |
上传的不是 wav/mp3 | 浏览器半会自动转 WAV;确认 client.js 已装配最新版 |
| 识别报 model 相关错误 | model 大小写 | 必须全小写 mimo-v2.5-asr |
| 浏览器没有🎤⚙按钮 | browser 半未装配 | 检查 package.json 的 exports 与 dsh.client(见下) |
package.json 必须有:"type": "module",
"exports": { ".": "./lib/index.js", "./client": "./lib/client.js", "./package.json": "./package.json" },
"dsh": { "client": { "inject": ["@deepseek-ai/dsh-client-runtime", "@deepseek-ai/dsh-client-locale"], "platform": "web" } }
缺了 exports/dsh.client,browser 半不会被打进 __DSH_BOOT__(按钮不出现)。
lib/index.js 用命名导出 apply / inject / name,不要 default export(否则 cordis 加载报错)。POST {baseURL}/chat/completions,音频是 base64 data URI(data:audio/wav;base64,...)放 messages[0].content[].input_audio.data,asr_options.language 在请求顶层(auto/zh/en),识别文本取 choices[0].message.content,只收 wav/mp3,model 全小写 mimo-v2.5-asr。openai-compatible 引擎才走标准 POST {baseURL}/audio/transcriptions(multipart 表单)。MediaRecorder(webm) → decodeAudioData → OfflineAudioContext 重采样 16kHz 单声道 → 16-bit WAV 上传(两种引擎都接受 wav)。~/.dsh/voice-input.config.json;apiKey 只写不读(GET /voice-config 只回 hasKey),不经过浏览器。Ctrl+M),松开停止 → 自动识别;默认先填入输入框待确认再发送(⚙里可关掉,改回松开即发)Ctrl+Space 输入法切换、Alt+Space 窗口菜单)xiaomi-cloud(默认)/ openai-compatible / web-speech(浏览器原生,免配置)env:NAME 从环境变量读npx @deepseek-ai/dsh web,浏览器打开 http://127.0.0.1:3080。web-speech 免配置),可先点「测试连接」确认配置可用。Ctrl+M(或自定义快捷键)说话,松开即识别——默认把文本填入输入框待你核对,确认后按 Enter 发送;若想松开即发,在⚙里取消勾选「识别后需确认再发送」。| 引擎 | 端点 / 协议 | 需要配置 |
|---|---|---|
xiaomi-cloud |
POST {baseURL}/chat/completions,base64 input_audio,仅 wav/mp3 |
baseURL / apiKey / model=mimo-v2.5-asr |
openai-compatible |
POST {baseURL}/audio/transcriptions(multipart) |
baseURL / apiKey / model |
web-speech |
浏览器 Web Speech API(Chrome/Edge),零配置、免费 | 无 |
lib/index.js,Node 侧)注册四个 HTTP 端点:GET /voice-config —— 下发引擎、快捷键、确认发送开关与非敏感配置(apiKey 只回 hasKey,不下发明文);POST /voice-config-update —— 合并前端表单并落盘 ~/.dsh/voice-input.config.json;POST /voice-config-test —— 用提交的临时配置(含可能新填的 key,不落盘)发一段短音验证 baseURL/key/model 链路,供「测试连接」按钮使用;POST /voice-transcribe —— 接收 WAV,按引擎分发到小米 chat/completions 或 OpenAI audio/transcriptions;ASR 错误按状态码映射成友好中文(401=key 无效 / 404=baseURL 或模型不对 / 429=限流…)。lib/client.js,浏览器侧)是 window.__ModuleLoader__.load 的 CJS bundle,React 组件注册到 conversation.input.right:🎤录音按钮(MediaRecorder → WAV → inputActions.setDraft/submit 发送)+ ⚙配置弹层(表单读写走上述 host 端点,快捷键按键捕获)。dsh-voice-input/
├── package.json # name/type:module/exports(. ./client ./package.json)/dsh.client
├── lib/
│ ├── index.js # host 半:配置持久化 + 三个 HTTP 端点 + 引擎分发
│ └── client.js # browser 半:🎤按钮 + ⚙配置弹层 + 录音转 WAV + 快捷键
└── README.md CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。