dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
这是一个适用于 Deepseek Harness 的插件,向用户提供 GUI 下自定义且区分模型的发送 Prompt 注入功能。
DeepSeek Harness(下称 dsh)的一个插件:在设置页里,按注入点和模型配置要注入的提示词。
装好之后,设置里多出一项「dsh-prompt-inject」。里面是八个注入点,每个注入点下可以写若干条规则,规则可以自己排序、单独开关、指定对哪些模型生效。改完自动保存,下一轮对话就用新值。
{{model}} 这类模板字段,发送时换成这次请求的真实值。用 dsh 自带的插件命令,从 GitHub 装进你要用的 profile:
dsh plugin --profile web add github:XuezuoYS/dsh-prompt-inject--profile 填你平时启动的那个 profile:命令行跑 Web UI 就是 web,桌面版是 desktop。第一次用某个 profile 时,这条命令会先把它初始化出来。新装的组合包默认就是启用的,不用再开。
命令里的 github:所有者/仓库 是 pnpm 的简写形式,转发给 profile 目录里的 pnpm 执行。想把版本钉死、不让后面的推送悄悄改变实际跑的代码,就带上 commit:
dsh plugin --profile web add github:XuezuoYS/dsh-prompt-inject#<sha>本插件是纯 JS 的手写包,没有 prepare、install 之类的构建脚本,所以官方文档里 git 安装那道「授权构建」的坎在这里不存在(pnpm 10 只会拦带构建脚本的包)。
装完如果 dsh 正在跑,命令会告诉你是立刻生效还是要重启;重启一次 dsh 总是安全的。想确认装上了,可以只看配置层而不启动:
dsh --profile web --dump-config # 应该能看到一行 "# == dsh-prompt-inject"卸载会同时移除依赖和它贡献的配置层:
dsh plugin --profile web remove dsh-prompt-inject卸载不动你的规则文件,重装回来配置还在。
打开 设置 → dsh-prompt-inject,页面分两组:用户消息(前置词 / 后置词)和 system 段。system 组里各项按它们在 system 里出现的先后排列。
每个注入点是一个可折叠的小节,有规则的默认展开,点一下能收起。小节里点「+ 新增规则」写一条;同一个注入点的多条规则按列表从上到下的顺序拼接,中间空一行;不同注入点互不影响。
一条规则卡片上有这些东西:
元素 · 干什么 开关 · 关掉就不参与拼接,规则仍留在列表里 模型作用域 · 一枚胶囊,写着 全部 / 已应用 N 个模型 / 无应用,点它开弹层多选 文本 · 多行输入框,就是要注入的内容 ↑ / ↓ · 调整这一注入点内的顺序,首尾自动禁用 ⧉ · 复制一份,插在它后面 ✕ · 删除,删完 Toast 里给一次「撤销」,撤销会放回原来的位置
编辑后 500ms 自动提交,顶部一直显示保存状态:保存中 / 已保存 / 保存失败。没有单独的保存按钮,也不需要。写失败或版本对不上时会回滚到服务端的最新值并提示你,不会静默覆盖。
设置页里叫 · 键 · 怎么进 system · 落在哪 用户前置词 · user.prefix · 插入一条独立 user 消息 · 当前用户输入之前,每轮只注入一次 用户后置词 · user.suffix · 同上 · 当前用户输入之后,每轮只注入一次 system 头部 · system.personaHead · 替换官方那一段 · 官方 persona 头(order 0),官方用来说明当前调用的模型名 工具说明之前 · system.beforeTools · 新加一段 · order 950 工具说明之后 · system.afterTools · 新加一段 · order 3050 结构化输出之前 · system.middle · 新加一段 · order 9800 system 尾部 · system.personaTail · 替换官方那一段 · 官方 persona 尾(order 10200),0.2.1 起默认为空串 system 最末尾 · system.last · 新加一段 · order 10300,排在官方 persona 尾之后
system 那六项的两种做法分得很清楚:
细节和官方段位参照表见 docs/injectPoint.md。
这是设计决定,也是这个插件唯一需要你提前知道的代价,所以设置页在这两个小节顶部就写着这句话。
{前置词}原文{后置词};pi-ai 那类不合并,就是三条。想让某句话只在 system 里生效、不留在用户历史里,就配到 system 那几个注入点去。
规则正文里可以写这几个字段,发送时会换成这次请求的真实值:
字段 · 换成什么 {{model}} · 这次请求实际用的模型 id,比如 deepseek-flash {{provider}} · 这个模型属于哪个 provider,比如 deepseek-account {{cwd}} · 当前会话工作目录的绝对路径
model / provider 就是官方在用的两个提示词变量(官方 persona 头用的就是 {{model}})。cwd 从 0.2.1 起官方不再注册,插件自己从会话头兜底取,效果一样。设置页每个展开的小节顶部都有一行字段徽章,点一下就把 {{字段}} 插到最近编辑那条规则的光标处;一条规则都没有时,点徽章会直接新建一条。
渲染时机:
认不出来、这次拼错、或者取不到值的字段,{{名字}} 会原样保留,不报错、也不会让这次请求失败。名字不合法的(中文、大写)一律当普通文本。想真的写出 {{model}} 这几个字而不是让它被换掉,写成 {{ model }} 或者换个大小写就行。
/,比如 deepseek-account/deepseek-flash。无应用(虚线圈出)外加一句轻提示。已失效 并保持勾选,等你自己去取消;在你取消之前,它按不匹配处理,也就是不注入。~/.dsh/dsh-prompt-inject/rules.json(Windows 上一般是 C:\Users\.dsh\dsh-prompt-inject\rules.json,.dsh 文件夹路径由宿主决定)。
写入走原子替换,带跨进程文件锁,权限 0600。文件坏掉或者结构版本不认识时,它会带着时间戳改名成 rules.json..bad 留着(现场可查),然后用空配置继续跑,不会静默把你的规则清空。这个文件由插件自己读写,建议只在设置页里改。
结构长这样,一条规则就是一个对象,八个注入点每个都只是一串规则,没有例外:
{
"version": 1,
"revision": 12,
"slots": {
"user.prefix": {
"rules": [
{
"id": "r1",
"enabled": true,
"text": "总是用中文回答",
"models": { "all": true, "list": ["deepseek-account/deepseek-flash"] }
}
]
},
"system.beforeTools": { "rules": [] }
}
}revision 每次写入加一,用来挡掉两个窗口同时写的情况。
provider/model 匹配这件事,看卡片上的作用域结论和弹层就够了。engines.dsh(现在是 0.2.1-rc.2)。dsh 从 0.2.1 起会硬检查这条要求:不满足就把整个 bundle 静默跳过(只在启动诊断的 skippedBundles 里留一条原因,不报错),所以升级 dsh 之后插件「不见了」,第一件事就是改这个值。dsh 还在 developer preview,破坏兼容的改动是常态。一个 npm 包,两半:
lib/index.js,管配置文件、注入逻辑、HTTP 端点。lib/client.js,手写浏览器包,不走构建链,由 package.json 的 dsh.client 声明。设计文档在 docs/,都挺短:
文件 · 讲什么 docs/injectPoint.md · 注入点、官方段位、两种语义的由来与约束 docs/injectFormat.md · 前后缀的注入格式、模板字段与渲染时机 docs/injectScopeAndSetting.md · 规则模型、怎么算「这次是哪个模型」、配置文件位置 docs/settingGUI.md · 设置界面、数据通道(三个 /api 端点)、目录刷新的事件表
动手前值得知道的几件事:
lib/injectPoints.js 是权威的那份,lib/client.js 里内联了一份一模一样的(客户端半不能 import)。改表要两边一起改,.agents/checks/client-shape.mjs 会检查两边是否一致。@deepseek-ai/* 一律声明成 peerDependencies,不能装成本地依赖 —— 那样会变成两份模块实例,instanceof 和模块私有的 WeakSet 都会失效。require('@deepseek-ai/dsh-client-ui-primitives')。从 0.2.1 起它不再是磁盘上的独立包,而是 web 前端模块表里的 baseline 模块(require 照样解析得到),所以 dsh.client.inject 里不列它;peerDependencies 里那份只是标版本。新版 dsh.client 另有 external(声明非 baseline 的动态包)和 immediately,我们都没用到。/api 下面,鉴权由官方那层处理,插件自己不写;所以只支持 GET / HEAD / POST。npm test 跑纯 node 那组(clone 下来就能验,不依赖任何官方包);npm run test:host 跑要官方包那组,没临时解包会直接退出码 2 并打印怎么搭(npm run test:all 两类一起)。细节见 .agents/checks/README.md。