YuMo-233/dsh-subagent-model-switch ↗★ 0
dsh-subagent-model-switch
给 DSH 的队友/子代理会话头部加一个模型切换器:不重开会话、不丢上文,切换后下一 turn 即用新模型。 适合在复杂任务中需要动态调整子代理模型及推理强度的用户。
설치
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:YuMo-233/dsh-subagent-model-switchdsh-subagent-model-switch
给 DSH 的队友 / 子代理会话装一个只长在它们头上的模型切换器。
DSH 原生的模型切换器对 origin === "subagent" 的会话是硬禁用的(子代理会话拿不到模型目录,按下也没反应);子代理只能在启动那一刻决定模型,之后想换就只能重开一个。这个插件补上这一格:在子代理会话头部渲染与原生同款的下拉菜单,选完当场生效——不重开会话、不丢上下文,并且跨重启记住选择。
生效范围
| 会话 | 头部模型切换器 |
|---|---|
| 主会话(你亲手开的) | 原生切换器(本插件不介入) |
队友 / subagent / subagent_fork 等子代理会话 | 本插件的切换器 |
菜单
点头部按钮,三级选择:
- 模型 —— 按 provider 分组的全部可用模型(免费模型带
· x0.00之类的价格标记); - 推理强度 —— 该 provider 支持的 reasoning effort,含「提供商默认」;
- 继承父会话 —— 清除覆写,回到继承父会话的模型。
切换在下一次模型请求时生效:已经发出去的请求不打断,当前 turn 之后的调用即用新模型。
工作原理
不改会话日志(往里塞自定义事件类型会让整个日志读取失败),也不依赖原生 model selection:
- 插件监听
agent/created,只给header.origin === "subagent"的 agent 挂两个钩子; agent/request—— 等整条 waterfall 跑完,在回程改写provider/model,并把从父会话继承来的reasoningEffort清掉(除非本次选择显式指定);system-prompt/assemble—— 同步改写系统提示词里的provider/model变量,让提示词与实际请求一致;- 选择落盘在
DSH_HOME/storages/dsh-subagent-model-switch/overrides.json,重启后自动恢复。
两个钩子都用 prepend 注册:cordis 的 waterfall 是「先注册的在最外层」,而覆写发生在 next() 返回之后的回程——最外层最后改写,所以最终权威一定是我们。
安装
方式一:DSH 官方插件管理器(推荐)
在 DSH Desktop 的「插件」面板里填:
github:YuMo-233/dsh-subagent-model-switch
或直接填仓库地址 https://github.com/YuMo-233/dsh-subagent-model-switch。装完重启即可。
方式二:开发安装(link,改代码即时生效)
# 1. clone 到任意位置
git clone https://github.com/YuMo-233/dsh-subagent-model-switch.git
# 2. junction(或复制)进 DSH profile 的 node_modules
# Windows:
mklink /J "%DSH_HOME%\profiles\desktop\node_modules\dsh-subagent-model-switch" ""
# 3. 在 profile 的 package.json 里登记
# dependencies 加: "dsh-subagent-model-switch": "link:"
# dsh.profile.bundles 数组加:"dsh-subagent-model-switch"
# 4. 在 profile 的 cordis.patch.yml 里注册插件
- insert:
- id: subagent-model-switch
name: 'dsh-subagent-model-switch'
# 5. 重启 DSH Desktop
接口
宿主侧注册 subagentModelSwitch 服务(typert RPC):
| 方法 | 参数 | 返回 |
|---|---|---|
getModel | sessionId | 覆写 {provider, model, reasoningEffort?} 或 null(同步) |
setModel | sessionId, provider, model, reasoningEffort? | 归一化后的覆写对象 |
unsetModel | sessionId | null |
错误码:subagentModelSwitch/invalid-request、/session-not-found、/not-subagent、/invalid-model。
首参刻意叫
sessionId而不是session:网关按参数名做 typert 参数劫持,叫session会被会话查找接走,而它对子代理会话一律抛session/agent-busy。
能力边界
- 只覆盖
provider/model/reasoningEffort;上下文、工具、权限都不动。 - 只对子代理会话显示;主会话请用原生切换器。
- 覆写按会话 id 记账,会话结束后条目不会自动清理(无害;想彻底清干净就删掉
overrides.json,或在会话头部选「继承父会话」)。
开发
node --check index.js # 宿主半边
node --check client.js # 客户端半边(浏览器端手写 bundle,不走构建)
客户端半边的产物由 DSH 客户端模块注册表按 /plugins/??/client.js&rev= 提供,改完刷新页面即可。