← 返回列表
未验证
任务完成或待批准时来电播报结果并语音下达指令
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/2 · 已提供中文文档
DeepSeek Harness 插件:当一次运行完成或需要审批时,在你的手机上收到一个链接,通过 ElevenLabs 语音代理听取结果,并说出下一步该做什么
综合分
28.5
GitHub 分
28.5
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add StephenEvenson/dsh-plugin-elevenlabs-callback该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
信任档位:仅索引本站尚未对其实装验证,仅收录元数据
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站尚未做安装检查
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 24 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-llm@deepseek-ai/dsh-session@deepseek-ai/dsh-tools@deepseek-ai/dsh-user-approval@deepseek-ai/schemastery用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-plugin-elevenlabs-callback
dsh-plugin
dsh 0.1.1-rc.2
node ≥22
license
一个 DeepSeek Harness 插件,通过语音给你回电。
你给 harness 一个长任务然后走开。当这一轮结束、失败,或停下来请求批准时,插件会把一个链接发送到你的手机。打开链接就会与一个 ElevenLabs 语音代理开始对话,而它已经知道发生了什么。它会向你朗读简短版本,回答关于这次运行的问题,并且——一旦你确认了措辞——通过插件提供的 webhook 工具,把你的下一条指令(或你的批准/拒绝)直接送回会话。
在 ElevenLabs Agents API 和 dsh 插件 API 之上用一个周末构建而成。dsh 处于开发者预览阶段;此插件是针对 @deepseek-ai/dsh 0.1.1-rc.2 编写和测试的,当插件 API 发生变化时需要更新。
先决条件 · 安装 · 首次回电 · 配置 · 在没有 harness 的情况下试用 · 真实电话呼叫 · 故障排除
一次回电听起来是什么样的
代理: 嗨,我是你的 DeepSeek Harness,来电是关于 retry-refactor 的。它已经完成了。完成了。我把重试逻辑移到了 http/retry.ts,添加了带抖动的指数退避,并为此写了六个测试。想要更多细节,还是我该告诉它接下来做什么?
你: 告诉它再运行一次测试,如果通过就提交。
代理: 那么,你是想让我告诉它再运行一次测试,如果通过就提交?
你: 是的。
→ send_instruction → 该消息作为后续轮次进入会话
代理: 我已经发送了指令。它完成后会回电。
(转录自 pnpm live-check,文本模式,针对真实代理和真实 webhook 工具。)
随后,同样的循环针对一个真实的 dsh 会话运行(DeepSeek-V4-Flash,一个 40 秒的轮次,包含 14 次工具调用,修复了一个失败的测试并提交):插件发送了链接,语音代理根据会话日志总结了这次运行,口述的指令作为后续轮次到达会话——在 dsh UI 中显示为 Context injection · elevenlabs-callback · instruction given by voice callback。每条消息的回复在 0.9–1.9 秒后到达(平均 1.3 秒);webhook 在 2.6 毫秒内得到响应。后来从真实手机进行的一次运行(“improve the function”,口述)产生了一个 29 秒的后续轮次,该轮次重构了函数、通过了测试并提交,之后插件再次回电。
工作原理
sequenceDiagram
participant H as dsh 会话
participant P as 插件(在 dsh 进程内)
participant N as 你的手机
participant E as ElevenLabs Agents
H->>P: agent/status 空闲(会话日志中的 turn/end)
P->>P: 收集最后一条消息、工具调用、时长 → 简报
P->>N: 链接(终端 + 二维码、ntfy 推送、桌面,或任意命令)
N->>P: 打开链接,点击 Answer → 对话令牌
N->>E: 带动态变量的 WebRTC 通话(摘要、状态、简报 id)
E->>N: 语音摘要
N->>E: “让它重新运行测试并提交”
E->>P: POST /tools/send_instruction(X-Tool-Token,简报 id 由平台填充)
P->>H: agent.followup(message) — 或者如果仍在运行则 steer()
E->>N: “已发送。完成后它会回电。” → end_call
三个 webhook 工具已接入该 agent:get_run_details(完整的最后一条消息以及该轮次的每一次工具调用)、send_instruction 和 resolve_approval。debrief_id 参数在工具 schema 中被标记为动态变量,因此平台会从对话本身填充它,语言模型永远不必重复一个标识符。
审批是一场竞速:当某个工具正在等待许可时,插件会发送一个链接并且让正常的键盘提示继续运行。哪一方先响应哪一方获胜;另一方会被告知该事项已被处理。
前置条件
| 你需要 | 原因 |
|---|---|
| PATH 中有 Node.js ≥ 22 和 pnpm | dsh plugin 会驱动 pnpm 将插件安装到某个 profile 中 |
| DeepSeek Harness @deepseek-ai/dsh 0.1.1-rc.2,且已可正常工作 | 在添加此插件之前,npx @deepseek-ai/dsh web 必须能够自行启动并运行一个轮次(已配置模型提供方和 API key)——它只监听会话,不会创建会话 |
| 一个 ElevenLabs 账户和 API key | 插件会在首次启动时在你的工作区中创建一个 agent、三个 webhook 工具和一个工作区密钥。在 Settings → API Keys 下创建该 key;免费套餐每天足够进行几次回调(每月约 15 agent 分钟) |
| 一个公共 HTTPS URL,用于插件的小型服务器:要么 PATH 中有 cloudflared(无需账户;插件会自行打开一个快速隧道),要么将你自己的隧道 / 反向代理设置为 publicUrl | ElevenLabs 必须能够访问 webhook 工具,并且你的手机必须能够加载该页面。浏览器只允许在 HTTPS 上使用麦克风 |
| 一部手机(或任意设备),带有现代浏览器和麦克风 | 该页面使用 @elevenlabs/client 通过 WebRTC 运行通话 |
| 可选:ntfy 应用 | 将链接推送到你的手机,而不是从终端读取二维码 |
| 可选:一个 Twilio 号码 | 用于真正的电话铃声,而不是链接——参见真实电话呼叫 |
在 macOS 上使用 dsh 0.1.1-rc.2(撰写本文时 npm 上的 latest)测试通过。桌面通知在 macOS 上使用 osascript,在 Linux 上使用 notify-send。
安装
尚未发布到 npm —— 请从 GitHub 或本地检出安装。
从 GitHub 安装(pnpm 会获取源码并使用包的 prepare 脚本进行构建):
dsh plugin --profile web add github:StephenEvenson/dsh-plugin-elevenlabs-callback
在你允许之前,pnpm 会拒绝运行 git 依赖的构建脚本。如果第一次 add 打印了关于忽略构建脚本的警告,请将以下内容添加到 ~/.dsh/profiles/web/pnpm-workspace.yaml,然后再次运行相同的 add:
allowBuilds:
dsh-plugin-elevenlabs-callback: true
只对你信任的包授予此权限 —— 它会在安装时运行该包的构建。
从本地检出安装(无需构建权限;检出会被链接到 profile 中,因此 git pull && pnpm build 即可更新它):
git clone https://github.com/StephenEvenson/dsh-plugin-elevenlabs-callback.git
cd dsh-plugin-elevenlabs-callback && pnpm install && pnpm build
dsh plugin --profile web add "$PWD"
在不启动的情况下检查该层:
dsh --profile web --dump-config | grep -A2 "id: elevenlabs-callback"
提供 API 密钥并启动 profile。 该插件从进程环境中读取 ELEVENLABS_API_KEY(dsh 自己的 ~/.dsh/.env 不会导出给插件),或从 profile 补丁中读取 apiKey —— 参见配置:
export ELEVENLABS_API_KEY=sk_...
dsh web
启动时,该插件会绑定 127.0.0.1:7331,打开隧道,然后在 ElevenLabs 上创建(或更新)agent 及其三个工具。你将看到:
[elevenlabs-callback] ready — agent agent_…, links will point at https://….trycloudflare.com
之后每次启动都会复用同一个 agent 和工具(它们的 id 保存在 ~/.dsh/elevenlabs-callback/agent.json 中),并且只推送当前设置和公共 URL。
更新: 在链接的检出中,运行 git pull && pnpm build;对于 GitHub 安装,重新运行 add github:… 命令。之后重启 dsh web —— bundle 成员关系仅在重启时才会改变。
卸载:
dsh plugin --profile web remove dsh-plugin-elevenlabs-callback
然后重启 dsh web。该插件的状态保留在 ~/.dsh/elevenlabs-callback/ 中,agent 保留在你的 ElevenLabs 工作区中(在 Agents 下删除它);如果你想要一个干净的状态,请将两者都删除。
第一次回调
1. 在 dsh web UI 中,给 harness 一些需要超过 20 秒的任务(带测试的重构、跨文件的脚本化更改),然后离开。
2. 当该轮结束时,运行 dsh web 的终端会打印带有二维码的链接:
[elevenlabs-callback] Harness: my-project — Finished, waiting for you
[elevenlabs-callback] open on your phone: https://….trycloudflare.com/d/2p4yc6?k=…
当设置了 notify.ntfyTopic 后,同一个链接会被推送到 ntfy 应用;设置了 notify.desktop 后,它还会以桌面通知的形式出现。
3. 在手机上打开链接,点击 Answer,并允许使用麦克风。智能体先说话:哪个项目、发生了什么,以及 harness 最后一条消息的第一句话。
4. 询问细节(“它改了什么?”),或者告诉它接下来该做什么。智能体会把你的指令复述一遍,只有在你确认后才会发送。
5. 指令会作为后续轮次到达 dsh 会话(如果 harness 仍在运行,则作为 steer 消息)。当该轮次结束时,你会收到下一个链接。
对于审批,流程相同,只是由智能体来提问(“它想运行 rm -rf build。允许吗?”)并调用 resolve_approval;dsh 中的键盘提示会并行继续工作。
配置
设置位于你配置文件的 cordis.patch.yml 中(~/.dsh/profiles/web/cordis.patch.yml)。通过其 id elevenlabs-callback 定位到对应行。补丁会替换整个 config 对象,因此请重复写出所有你想保留的键:
- id: elevenlabs-callback
config:
apiKey: sk_... # 或者省略,并从环境变量导出 ELEVENLABS_API_KEY
triggers: { finished: true, error: true, approval: true, minTurnSeconds: 20 }
notify: { terminal: true, qr: false, desktop: true, ntfyTopic: my-private-topic, ntfyServer: https://ntfy.sh, command: "" }
| 键 | 默认值 | 含义 |
|---|---|---|
| apiKey | "" | ElevenLabs API 密钥;为空 = 从环境变量读取 ELEVENLABS_API_KEY |
| publicUrl | "" | 插件服务器可被访问的 https URL;为空 = 启动 cloudflared 快速隧道 |
| host, port | 127.0.0.1, 7331 | 插件服务器监听的位置(0 = 空闲端口) |
| stateDir | $DSH_HOME/elevenlabs-callback | 智能体/工具 id 以及生成的工具令牌 |
| agent.llm, agent.voiceId, agent.ttsModel | gemini-2.5-flash, Charlie, eleven_flash_v2 | 启动时推送的智能体设置(英语智能体需要 eleven_flash_v2 或 eleven_turbo_v2) |
| triggers.finished / .error / .approval | true | 哪些事件会发送链接 |
| triggers.minTurnSeconds | 20 | 短于该时长的已完成轮次会被忽略——你很可能正在看着 |
| linkTtlMinutes | 120 | 链接可以发起通话的时长 |
| notify.terminal, notify.qr | true | 将链接(以及二维码)打印到终端 |
| notify.desktop | false | macOS / Linux 桌面通知 |
| notify.ntfyTopic, notify.ntfyServer | "", https://ntfy.sh | 将链接推送到 ntfy 应用 |
| notify.command | "" | 任意 shell 命令;其环境中会获得 DSH_CALLBACK_URL、_TITLE、_BODY |
| phone.toNumber, phone.fromNumber | "" | 拨打真实电话,而不仅仅是发送链接——见下文 |
对 config 的补丁编辑会热重载;插件会重启其服务器,并使用新设置重新配置智能体。
在没有 harness 的情况下试用
cp .env.example .env # ELEVENLABS_API_KEY, TOOL_SHARED_SECRET
pnpm install
pnpm demo # --status finished | needs_approval | error
pnpm demo 使用同一个服务器、隧道和配置运行,附带一份虚构的汇报和一个假的 harness,它会打印语音代理发送的任何内容。它使用自己的代理(… (standalone demo)),因此绝不会重新接线插件的代理。在你的手机上打开打印出的链接并与它对话;或者在终端中以文本模式驱动它,这样不会消耗音频分钟数:
pnpm live-check --link "https://…/d/abc123?k=…"
这会通过 WebSocket 打开一次真实对话,发送一段四行脚本,并检查 send_instruction 是否通过公共 URL 被调用。在上述记录的运行中观察到:代理在每条消息后 1.0–2.1 秒回复(平均 1.4 秒);插件在 0.2 毫秒内响应了 webhook。
真实电话呼叫(可选)
链接在任何地方都能用;但电话铃声更悦耳。ElevenLabs 本身不销售号码,因此你需要从 Twilio(或任何 SIP 中继)带来一个号码:
1. 在 Twilio 控制台中:购买一个具有语音功能的号码(美国号码即时可用;其他国家需要地址/身份证明文件)。ElevenLabs 无法从 Twilio 试用账户导入号码(Twilio 错误 20003),因此必须先将账户升级为按量付费。
2. 在 ElevenLabs 仪表板中:Agents → Phone numbers → Import from Twilio,使用 Twilio 控制台中的 Account SID(AC…)和 Auth Token(不是 API 密钥)。
3. 在 profile 补丁中:
- id: elevenlabs-callback
config:
phone: { toNumber: "+61400000000", fromNumber: "+15550001111" }
从那时起,每次回调都会通过 POST /v1/convai/twilio/outbound-call 拨打你的电话,并使用与网页相同的动态变量——代理先说话,工具的工作方式完全相同——同时链接仍会作为后备发送。pnpm demo --call +61…(在 .env 中设置 PHONE_FROM)会在没有 harness 的情况下尝试它。Twilio 在 ElevenLabs 的代理分钟数之外按分钟收费。
故障排除
- cloudflared: command not found / “tunnel did not report a URL” — 安装 cloudflared,或运行你自己的隧道并设置 publicUrl。插件拒绝非 https URL,因为 ElevenLabs 不会调用它们。
- 一轮结束后没有链接 — 该轮短于 triggers.minTurnSeconds,被中断/中止,或在插件启动之前结束(只有启动后结束的轮次才计数)。检查终端中的 [elevenlabs-callback] 行;dsh web 不显示 ctx.logger 输出,因此所有面向用户的内容都用普通的 console.log 打印。
- 页面加载了但 Answer 失败 — 麦克风需要 HTTPS 和权限授予;在 iOS Safari 上,第一次点击必须是用户手势。早于 linkTtlMinutes 的链接会返回 404。
- 工具返回 401 — stateDir/tool-secret 中的共享令牌不再与 ElevenLabs 上的工作区密钥匹配。重启配置文件;插件会在每次启动时重新推送密钥值。
- 智能体抢话或使用了错误的语音/模型 — 修改补丁中的 agent.;插件会在下次启动时对运行中的智能体执行 PATCH。英语智能体必须使用 eleven_flash_v2 或 eleven_turbo_v2。
- 来自 ElevenLabs 的“异常活动”/配额错误 — 免费套餐的每月智能体分钟数在工作区内的所有智能体之间共享;pnpm live-check 使用文本模式,不消耗任何分钟数。
开发
pnpm install
pnpm test # 40 tests: debrief model, HTTP surface, session-log parsing, config schema,
and the whole loop inside a real Cordis context with a fake agent registry
pnpm typecheck # against the published @deepseek-ai/dsh- type definitions
pnpm build # tsc → lib/
每次 webhook 调用都会记录其延迟(tool=send_instruction status=ok latency_ms=0.2 …),并可在 /api/tool-log 查看。工具端点即使出现问题也会返回 200 并附带结构化的 ok/found 字段,这样语音智能体就能说明发生了什么,而不是因 HTTP 错误而卡住。
要在不重新安装的情况下进行迭代:按上述方式链接检出目录;在 pnpm build 之后,重启 dsh web。
安全说明
- 隧道仅暴露此插件的服务器,绝不暴露 dsh web UI。
- 每个链接都带有自己的随机密钥;没有它,页面和令牌端点会返回 404。链接会过期。
- ElevenLabs 使用首次运行时生成的令牌向工具进行身份验证,该令牌在他们那边存储为工作区密钥,在你这边存储在 stateDir 中;其他任何内容都会得到 401。
- 智能体是私有的(enable_auth),限制为一次并发调用、每天 50 次调用、每次调用 5 分钟。
- 指令只有在智能体复述并确认后才被送达;每轮回调只接受一条指令。
- 除了 ElevenLabs(以及你启用时的 ntfy / Twilio)之外,不会向任何地方发送任何内容;简报包含 harness 的最后一条消息和工具调用摘要,因此请像对待会话本身一样对待该链接。
兼容性
| dsh | 状态 |
|---|---|
| 0.1.1-rc.2(npm latest) | 已端到端测试,包括一次真实手机通话 |
| 0.1.2-alpha.x(GitHub main) | 未测试;插件 API 是开发者预览版,预计会发生变化 |
package.json 中的对等依赖范围是开放式的(>=0.1.1-rc.2);pnpm typecheck 针对固定的 rc.2 类型定义运行。
插件不会恢复已被销毁的会话;链接仍可用于读取,但 send_instruction 会提示会话已不存在。
布局
src/index.ts the Cordis plugin: config schema, triggers, approval race, delivery
src/harness.ts turns a dsh session log into a debrief (pure, unit-tested)
src/debrief.ts debrief store, per-link keys, spoken opening, dynamic variables
src/server.ts node:http 服务器:手机页面、令牌端点、三个 webhook 工具
src/notify.ts 终端 + 二维码、桌面、ntfy、shell 命令
src/tunnel.ts cloudflared 快速隧道
src/elevenlabs/ 以代码形式定义的 agent、最小 API 客户端、幂等配置
web/ 手机页面(基于 @elevenlabs/client IIFE 包的纯 HTML/JS)
scripts/ 演示(无需 harness)、实时检查(文本模式、真实工具)、配置
cordis.patch.yml dsh plugin add 合并到 profile 中的层
许可证
MIT