跳到主要内容

dsh-discord

已验证

@addozhang/dsh-discord · v0.5.0 · MIT · Web 界面

Discord adapter for DeepSeek Harness · DeepSeek Harness 的 Discord 适配器

安装

dsh plugin add @addozhang/dsh-discord

用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。

源码

标签

作者

说明文档

@addozhang/dsh-discord

English | 中文

npm CI license node dshfind

DeepSeek Harness 的 Discord 优先适配器:在 Discord 服务器中运行 DSH 会话——@机器人下一个任务,线程即开,回答流式输出,审批与提问以按钮形式送到手机上,随手即可回应。

零额外进程:适配器是 DSH 插件,直接挂载到你的 dsh web profile。会话状态保存在 DSH,持久绑定保存在 profile 的存储域中。

一次任务的完整生命周期:@提及锚定线程、工具活动行随回答流式编辑、最终以 Markdown 表格落地

功能

  • @提及驱动会话 — 在已绑定的频道中,被授权的 @机器人 <任务> 会锚定一个线程(你的消息成为首帖)、创建 DSH 会话,并且至多提交一次。线程内的后续消息无需 @ 即可排队。消息附带的图片会一并送达:在严格的大小与主机白名单约束下从 Discord CDN 下载,并作为 image parts 提交给多模态模型。
  • 流式渲染 — typing 指示、单条头消息原地编辑、逐工具活动行、代码围栏感知的长文分段、一次性收尾;Turn 结束时活动消息会被删除。
  • 审批与提问 — DSH 的 ask 渲染为按钮、下拉菜单与自由文本弹窗。所有权强制校验(提问者——或后续 Turn 的线程属主——才能点击),超时清扫 fail-closed,结算后的控件原地置灰。
  • 会话控制 — /steer、/stop、/queue list|remove 带运行所有权校验;/project bind|list|info 与 /session resume 管理 Guild↔工作区绑定与历史会话;/guild forget 供操作员清理。
  • 模型切换 — /model show 读取会话的实时模型目录;/model select 走交互式 provider → 模型 → 推理强度级联,也可直接填写 provider/model 应用。默认对所有授权成员开放,可收紧为仅 Host 操作员。
  • 权限切换 — /permission show / set 读写会话权限预设(沙箱 + 审批捆绑档位),走宿主自己的 /permission 命令路径,journal 自动记审计;danger-full-access 需按钮二次确认。
  • 设置卡片,开箱双语 — Token 引导与连接/断开(存入 Host 凭据服务,绝不写入设置或日志)、服务器白名单、自动归档与语言。所有 Discord 可见文案提供中英双语;Bot 默认跟随 DSH 语言偏好,也可从卡片固定。
  • 安全设计 — 显式服务器白名单内的 deny-first 授权。提及抑制双保险:每条请求携带 allowed_mentions,外加 wire body 的字节级提及中和。DSH 提交至多一次,并做保留 unknown 的对账——结果不明的投递绝不盲目重发。绑定重启后持久;READY 扫描会重建被删除的 category/控制频道,而把被删除的工作区频道视为用户意图(解除映射,workspace 保持可重新绑定)。

环境要求

  • dsh CLI(web profile)。dsh 与适配器的通道需匹配——见版本支持。
  • Node.js ^22.19.0 || >=24
  • 一个 Discord 应用(含 Bot 用户),并在开发者门户启用 MESSAGE CONTENT 特权 intent(Developer Portal → 你的应用 → Bot → Privileged Gateway Intents)

版本支持

两条通道并行发布,各自钉在经过真机验证的 dsh 宿主面上。适配器与 dsh CLI 请取同一行:

通道 适配器 dsh CLI 安装命令
stable 0.5.0 — npm latest 0.1.7-rc.1 — npm next dsh plugin --profile web add @addozhang/dsh-discord
next >=0.5.0-rc.4 — npm next 0.1.7-alpha — npm alpha dsh plugin --profile web add @addozhang/dsh-discord@next
  • 两行不可混搭。 适配器 >=0.5.0-rc.4(含 0.5.0)使用 0.1.7 的 profile-backed settings forms 与控制器服务,在更旧的宿主上无法加载(startup 探针会给出一条可操作的诊断后拒绝激活);0.5.0-rc.1–rc.3 对应 dsh 0.1.6-alpha;适配器 0.4.x 使用旧版 apiProxy 宿主面(该面已在 0.1.6-alpha 中移除)——它仍是 dsh 0.1.5 stable 线的配对,可用精确版本号安装(如 @addozhang/[email protected])。错配会在启动时失败。
  • 切换 dsh CLI 通道:npm install -g @deepseek-ai/dsh@next(0.1.7-rc.1,配适配器 0.5.0)或 npm install -g @deepseek-ai/dsh@alpha(0.1.7-alpha 线)。
  • next 刚发版后,@next 规格可能解析到过期的缓存版本。若装到的版本偏旧,请改用精确版本号安装(如 @addozhang/[email protected]),并核对 profile node_modules 中的 version 字段。

安装

使用 dsh CLI 安装——它会自动把包装进 profile 并注册 bundle。下面是 stable 通道;next 通道使用版本支持表中的 @next 命令(up / rm 同规格):

dsh plugin --profile web add @addozhang/dsh-discord

然后重启 dsh web 并刷新浏览器。dsh plugin 会自动对账 profile 的 bundle 列表——无需手动编辑。

升级与卸载使用同一条命令:

dsh plugin --profile web up @addozhang/dsh-discord   # 升级;bundle 列表会重新对账
dsh plugin --profile web rm @addozhang/dsh-discord   # 卸载;先执行 /guild forget 清理适配器记录

如果不用 CLI、手工管理 profile,等价做法是在 profile 目录里用 pnpm 安装本包,并在 dsh.profile.bundles 中自行登记:

{
  "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@addozhang/dsh-discord"] } }
}

配置

全部配置项位于 dsh-discord 设置命名空间,既可以在设置卡片中修改,也可以直接编辑 profile 的用户设置(settings.yaml):

配置项 默认值 说明
enabled false 适配器总开关;卡片 Connect 在 Token 存入后启动。
allowedGuildIds [] 服务器白名单。白名单之外零响应、零 DSH 调用。
memberUserIds / memberRoleIds [] 白名单 Guild 内的成员级授权。
administratorUserIds / administratorRoleIds [] 工作区管理员级(/project bind)。
deniedUserIds / deniedRoleIds [] 拒绝名单;优先级高于上述一切授权。
hostOperatorUserIds [] Host 操作员(/guild forget;启用 modelSelectOperatorOnly 后也包括 /model select)。
modelSelectOperatorOnly false 将 /model select 限制为 Host 操作员(仅 settings.yaml,卡片不展示)。默认 false:任何授权成员均可切换,且切换仍会更新 Host 默认。
permissionSelectOperatorOnly true 将 /permission set 限制为 Host 操作员(仅 settings.yaml)。默认 true——比 /model 更严,因为「完全权限」会同时解除沙箱与审批;可放开为任何授权成员可切换。
defaultVerbosity essential-tools 工具活动行粒度:text-only、essential-tools、full-tools。
language auto Bot 可见文案语言:auto 跟随 DSH 语言偏好(非中文渲染英文),或固定 zh/en。
streamUpdateIntervalMs 800 流式编辑合并间隔(250–10000)。
typingIntervalMs 7000 typing 心跳(1000–30000)。
approvalTimeoutMs 600000 审批超时(30000–86400000);超时自动拒绝。
questionTimeoutMs 1800000 问题超时(30000–86400000);超时取消所属 Turn。
threadAutoArchiveMinutes 1440 任务线程自动归档:60、1440、4320 或 10080。
dsh-discord:
  allowedGuildIds: ["1517134847850709032"]
  language: auto

设置卡片暴露三个高频项(服务器白名单、自动归档、语言)以及连接与 Token 面;其余键完全支持通过 settings.yaml 配置。非法的已存配置会保留最近一次有效配置。

Discord 设置卡片:连接状态、服务器白名单、归档、语言

初始设置

  1. 以至少以下权限把 Bot 邀请到你的服务器:查看频道、管理频道(适配器要创建自己的分类和工作区频道)、发送消息、创建公共线程、在线程中发送消息、上传文件、读取消息历史。
  2. 启动 profile 并打开 Web 界面。
  3. 在 Settings → Discord 中粘贴 Bot Token(开发者门户 → 你的应用 → Bot → Reset Token)并点击 Connect。Token 由 Host 凭据服务保存——绝不写入设置、日志或客户端。
  4. 填写 允许的服务器(服务器 ID 获取方式:Discord 开发者模式 → 右键服务器 → 复制服务器 ID)。白名单之外的一切都会被忽略。
  5. /model select 默认对任何授权成员开放(单人自用部署)。如需限制为 Host 操作员:在 hostOperatorUserIds 中加入其用户 ID,并把 modelSelectOperatorOnly 设为 true(settings.yaml)。/guild forget 始终需要 Host 操作员。
  6. 选择 Bot 语言,然后在已绑定的频道 @机器人 开始会话。

命令

命令 位置 说明
/project bind 任意频道 将 Guild 绑定到工作区(管理员;会创建主频道)
/project list / info 任意频道 列出工作区 / 查看当前频道绑定
/queue list, /queue remove 会话线程 查看与移除待处理队列
/steer, /stop 会话线程 插话或取消运行中的 Turn(仅属主)
/model show / select 会话线程 查看实时模型目录;select 不带参数时走交互式 provider → 模型 → 推理强度级联(默认对所有授权成员开放)
/session resume 项目频道 自动补全选择本工作区的历史会话(显示标题与时间,最新优先),恢复为当前频道的新线程;空白、已挂线程、subagent、已归档的会话不会出现。线程会渲染会话历史——回答与工具摘要之外,用户输入以引用行回显(插件/系统注入永不回显)。适配器重启后线程只补齐错过部分:持久化的渲染水位抑制已投递过的历史,已绑定会话在重连时自动重订阅,因此从 web UI 发起的回合也会落进对应线程
/guild forget 任意频道 仅操作员:移除适配器记录
/permission show / set 会话线程 查看或切换会话权限预设(仅可查看 / 工作区内修改 / 完全权限——沙箱与审批的捆绑档位,目录取自宿主实时配置)。set danger-full-access 先要求按钮确认;预设自动补全;默认仅 Host 操作员可切换(permissionSelectOperatorOnly 可放开)。任何入口(含 web UI)的切换都会在线程渲染一行系统消息

设计说明

  • 适配器为 function/namespace 插件(inject: ['sessionController', 'workspaceController', 'sessionQuery', 'webServer', 'credentials', 'settings', 'storageDomain', 'connection', 'commands', 'permissionPresets']),将 Discord Gateway、命令面、流式渲染器与设置卡片挂载到 DSH web profile。
  • 设置卡片是首次使用的引导面:Token 输入通过插件管理通道写入凭据服务的 DSH_DISCORD_BOT_TOKEN 引用,然后触发启动链。断开连接保留凭据;留空重连直接使用已存 Token。
  • 发布工作流通过 npm trusted publishing (OIDC) 认证——任何地方都不保存发布凭证。
  • 适配器启动链带代际计数,Connect/Disconnect 与初始启动竞争时只会产生一个 Gateway。
  • 凭据探测会回退到 resolve():Host 的 describe() 不识别环境变量来源的值——已连接的适配器不会被误报为未配置。
  • 适配器日志默认静默:流程记录走 Host 的 debug 级别,失败形态的事件升到 warn——默认级别下不会向 DSH 进程打印任何内容。
  • 链路级 trace:启动前设置 DSH_DISCORD_TRACE=1 可将 mux 帧、丢弃点与投递结果输出到 stderr(默认静默)。存在原因:Host 在该面上未为插件日志接线任何 exporter,也没有日志级别开关——logger.debug 输出不可见;Host 提供等价机制后应移除。

已知限制与推迟项

  • /preset、/skill、/host 保持注销状态 — 控制模块已实现并通过单元测试,待路由接线时回归(/preset 的会话线程守卫一并处理)。
  • verbosity 为全局设置(DSH 生态有按频道设置的先例)。
  • 经 Kimaki 对齐后有意推迟:reconcile-interactions 接线、ask 等待期暂停 typing、fail-closed 绑定/会话属主 store 接线、凭据轮换监听。
  • 已知张力:流式编辑 250ms 下限与高负载下 Discord 编辑预算的冲突(429 自愈),以及 typing 缺少时长上限看门狗。

开发

pnpm install --ignore-scripts
pnpm test          # 729 tests incl. gateway/REST twin E2E
pnpm typecheck
pnpm lint
pnpm build         # lib + client bundle

在 profile 中试用本地构建:

pnpm pack --pack-destination /tmp
dsh plugin --profile <your-profile> add file:/tmp/addozhang-dsh-discord-<version>.tgz

dsh plugin 会把相对路径锚定到调用目录,因此在已执行 pnpm build 的仓库里也可以直接 dsh plugin --profile <your-profile> add ../fiber。重复 pack + add 即可刷新已安装副本,然后重启 dsh web。

发布由 GitHub Actions 经 npm trusted publishing (OIDC) 完成(npm version <level> && git push --follow-tags)——任何地方都不保存发布凭证。实现遵循 openspec/changes/build-discord-native-adapter/ 中的 OpenSpec 变更(设计、能力 spec、验证清单、评审报告)。

许可证

MIT