Back to home

lcc815

dsh-debate-plugin

No description

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

dsh-debate-plugin

DeepSeek Harness 的辩论插件:/debate 人工命令发起一场正反对抗辩论,双方由立场锁定的 subagent 逐轮交锋,可选五段式中立评审;Web 端为每场辩论渲染专属卡片。

  • 逐轮 one-shot:每个辩手发言都是一个独立 subagent(persona 锁立场、对方上次发言注入 prompt),任何一轮异常即 fail-loud 终止
  • 中立评审:结构化五段输出——双方核心论点 / 论证质量 / 精彩交锋 / 未决分歧 / 综合评价
  • 完全独立:不写任何 session 事件、不注册投影;辩论记录存插件自己的 JSONL store,Web 卡片经 RPC 拉取
  • 命令输出:命令先返回“辩论已开始”确认,后台继续运行;完整辩论记录由 Web 卡片通过 Remote 轮询获取并渲染
  • 逐步完善中

安装

前提:宿主 profile 的 bundle 组合提供全部 peer 依赖(@deepseek-ai/dsh-base 即可覆盖)。

# 在 deepseek-harness checkout(或任意 dsh 安装位置)内
pnpm dsh plugin --profile debate add /path/to/dsh-debate-plugin
pnpm dsh --profile debate --dump-config   # 应出现 "# == dsh-debate-plugin" 配置层
  • 本地路径安装建立 link/junction 直连:插件仓库内 pnpm build 后产物立即生效,无需重新安装
  • git / registry 安装走包内 prepare 脚本(tsdown 构建 lib/index.jslib/client.js),devDependencies 随安装就位

用法

从命令菜单选择 /debate(或输入 /debate <辩题> 后发送):

/debate [--rounds N] [--no-judge] <辩题>
  --rounds N   逻辑轮数(每轮正反各一次发言),2-12,默认 3
  --no-judge   跳过评审环节

示例:

/debate 人工智能将取代程序员
/debate --rounds 2 --no-judge 远程办公利大于弊

运行中 Web 卡片显示"进行中"并每 1 秒轮询增量;辩手的本地 subagent 输出会以流式文本展示,并通过 MarkdownText 渲染 Markdown。完成后展示辩题、轮次流(正方 / 反方 · 开篇立论 / 驳论 / 结辩)与评审面板。运行中的辩论可从卡片中止;失败时记录错误并以失败态展示。

配置

schemastery 字段(写入 profile 配置):

字段类型默认说明
providerstringspawn正反辩手与评审 subagent 使用的 provider 名
dataDirstring~/.dsh-debate-plugin/debates.jsonl辩论记录 JSONL 文件路径

架构

首版走完全独立路线(B 路线):外部插件的自定义 session 事件尚无法进入 harness 的持久事件词汇表,因此辩论数据不落会话日志,全部住在插件自己的存储里。

graph LR
    U["/debate 命令"] --> C["command.ts 解析"]
    C --> E["engine.ts DebateService"]
    E --> S1["subagent 正方"]
    E --> S2["subagent 反方"]
    E --> S3["subagent 评审"]
    E --> ST["store.ts JSONL last-wins"]
    C -->|admission CommandResult| SL["session log command/run + command/done"]
    W["client DebateCard"] -->|RPC getByCommand| E
    SL -->|CommandNode fold| W
  • host 半(lib/index.js):手动解析参数并立即 admission → 后台逐轮 ctx.subagents.start;本地子会话的 assistant/chunk / assistant/message 事件折叠为节流的 live 快照,写入 JSONL。DebateService extends TypertRemoteService,暴露 list / get / getByCommand 读方法和 cancel 控制方法
  • client 半(lib/client.js):手写 Remote 贡献(全严格 zod codec)经 $mount 挂载,嵌套 consumer plugin(inject remote.debate)认领 conversation.chat.commandview slot 的 debate key,把通用命令卡升级为辩论卡;轮询传输失败时保留最后快照
  • 构建约束:lib 半永不 minify(Typert 网关靠方法参数名反射发现 Remote);client 半复刻官方 client preset 的 loader 契约——window.__ModuleLoader__.load 工厂包裹、平台模块 external(冻结模块表)、CSS Modules 经 lightningcss 内联并自注入 <style data-plugin>

Model Experience / Known Limitations

  • 命令需经命令菜单 claim 发送:程序化填充或粘贴的完整命令行不经输入状态机,会作为普通消息发给模型
  • 命令-only 会话(无任何用户消息)保持 Hero 界面,不渲染消息流与卡片——在有消息流的会话里执行 /debate 才能看到卡片;回放历史会话时卡片按 commandId 重新拉取记录
  • 无凭证 fail-loud:headless 在 boot 阶段即 MISSING_CREDENTIAL 退出;web 模式凭证惰性校验,辩论在第一个辩手 subagent 处失败并落失败记录
  • npm 上 @deepseek-ai/dsh-* 发布不完整(web-app 依赖链 404):开发联调需本地 checkout(见下节);运行时 peer 一律由宿主 profile 提供
  • --rounds 被 clamp 到 [2, 12];中止经 abort 信号传播,已完成轮次保留在记录里

开发

pnpm typecheck   # scripts/patch-dts.mjs 物化 @deepseek-ai/* 类型 + tsc
pnpm test        # vitest:engine / store / prompts / command / client 五组
pnpm build       # tsdown:lib/index.js + lib/client.js
  • scripts/patch-dts.mjs 从同级目录的 deepseek-harness checkout 把消费到的 @deepseek-ai/* 包物化进 node_modules(声明文件里的 .ts 相对后缀重写为 .js);无 checkout 时安静跳过,外部贡献者可正常 install/build
  • devDeps 刻意不装 @deepseek-ai/*pnpm-workspace.yamlautoInstallPeers: false
  • 联调:pnpm dsh plugin --profile debate add <本仓库路径> 后,在 checkout 里 pnpm dsh --profile debate(web,默认 http://127.0.0.1:3080)或 headless 一次性任务
  • 版本对齐:本地 checkout(0.1.0-rc.5)领先 npm(0.0.1-rc.1);本插件只使用两版间稳定的 API 面(subagents / commands / typert / client slots)

License

MIT