dsh-plugin-model-provider-readout
August 18, 2026 · View on GitHub
DSH Web 客户端插件:在 composer 工具行右侧、模型选择器按钮正左侧显示 「模型提供方 |」——与右下角模型按钮连读即「模型提供方 | 模型」, 数据与官方选择器同源、实时同步(在模型选择器里切换模型,标签立即跟随)。
┌────────────────────────────────────────────────────┐
│ … DeepSeek | [deepseek-v4-flash ▾] (发送)│
└────────────────────────────────────────────────────┘
↑ 本插件的提供方标签
特性
- 纯增量:挂在
conversation.input.right(list 槽位,工具行右端、模型座位 正左方),不替换、不抢占任何官方 UI。 - 数据与官方
ModelSelect完全同一条通路:ui-model-selection的ctx.modelDirectories每会话共享目录,current = { provider, model }由 Host 上报,选择器切换模型后立即反映。 - 零运行时依赖:源代码刻意不带运行时
import(React 由宿主注入),lib/编译产物可直接作为动态注册代码体使用。 - 子代理会话自动隐藏(Agent 绑定 RPC 不可用时渲染空)。
- 目录未就绪/加载失败时渲染空,不打扰界面;错误面由官方选择器承担。
为什么不做成替换右下角模型按钮
conversation.input.model 是 single 槽位、被官方 ModelSelect 占用,
抢占意味着整段重写选择器(下拉、目录加载、selection、effort…),官方
升级即冲突。本插件选择其正左方的可加性槽位 conversation.input.right,
零风险且视觉上直接贴着模型按钮。
目录结构
dsh-plugin-model-provider-readout/
├── src/index.ts # host 半部(空 apply:让 Loader 行挂上 dsh.client 包)
├── src/client/index.ts # client 半部(唯一事实来源,标准 client-plugin 形状)
├── lib/index.js # host 编译产物(已提交)
├── lib/client/index.js # tsc 中间产物(普通 ESM)
├── lib/client.js # DSH 静态 client bundle(安装时由 ./client 导出)
├── dynamic/client-body.js # 动态注册代码体(lib 经 scripts/to-dynamic.mjs 转换)
├── cordis.patch.yml # 组合补丁:插入 model-provider-readout 行(安装必备)
├── scripts/to-dynamic.mjs # lib → 动态代码体 转换脚本
├── tsconfig.json # 严格模式,ES2020,零依赖
├── package.json # 插件元数据(dsh.bundle.patch + dsh.client.platform=web)
└── README.md / LICENSE
构建
仅需 TypeScript,无任何其他依赖:
npm install --save-dev typescript # 或复用任意 tsc
pnpm run build # tsc + 静态 bundle + 动态代码体
pnpm pack # → 可安装 tarball(dsh plugin add 也支持 file: 路径)
lib/ 已提交,克隆后无需构建即可安装使用。
安装到自己的 harness(git 链接,一条命令)
拿到本仓库的 git 链接后,任何人的 DSH 机器都可以让 harness 自己完成 安装与注册:
dsh plugin --profile web add git+https://github.com/<你的用户名>/<仓库>.git
内部发生的事:
dsh plugin在 web profile($DSH_HOME/profiles/web)里跑pnpm add, 克隆仓库并按package.json的name安装;- 安装成功后自动对账:包声明了
dsh.bundle.patch,即自动追加进dsh.profile.bundles层叠(无需手改任何配置); cordis.patch.yml把插件行插入组合:model-provider-readout→@dsh-external/dsh-plugin-model-provider-readout;- 重启 harness(或 web host)后,clientModules 扫描 loader 条目发现
dsh.client声明,把lib/client.js作为/plugins/.../client.js挂进页面 —— 标签出现在模型按钮左侧。
重启是唯一需要的手动步骤(clientModules 对插件集合的判定按进程缓存, "plugin-set changes take effect on restart")。重启前本机当前进程不受影响。
零构建:仓库没有 prepare 脚本、lib/ 已提交,pnpm ≥10 不会触发
allowBuilds 审批,安装后无需任何额外命令。
卸载:
dsh plugin --profile web remove @dsh-external/dsh-plugin-model-provider-readout
快速开始(给使用者,免重启的即时方案)
不想重启 harness 时,可以在单个会话里动态注册:
git clone <仓库链接>,打开dynamic/client-body.js;- 在 DSH Web GUI 的会话里把文件内容交给 Agent,说"按动态 Cordis 插件注册这段客户端代码";
- 在 UI 批准授权后,提供方标签立即出现在模型按钮左侧。
动态注册随进程存活,重启后需要重新注册;
dsh plugin安装则是持久的。
数据契约(依赖官方包,均已随 dsh web 挂载)
| 依赖 | 说明 |
|---|---|
slots | 槽位注册(conversation.input.right,list,id/order/inject) |
sessions | subagentAddress(sessionId) 判断子代理会话 |
modelDirectories | ui-model-selection 的每会话 ModelDirectory(store + load()) |
三者缺失时插件保持等待不激活(inject 硬依赖语义)。
License
MIT