🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

语音回电通知StephenEvenson/dsh-plugin-elevenlabs-callback

DeepSeek Harnessspec-screened扫描:低风险在 GitHub 查看 ↗
未验证

任务完成或待批准时来电播报结果并语音下达指令

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 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

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群