dsh-custom-provider
dsh(DeepSeek Harness)Web 设置页扩展插件:新增「自定义模型 / Custom models」设置分区(排在 Models 之后),补上官方 Models 页面不提供的能力编辑——
- 子代理模型白名单(页面顶部卡片,全部下拉选择,不手填)
- 委派时模型自选:启用后
subagent 工具增加可选 provider/model/reasoning_effort 参数并注册 list_subagent_models 工具,每次委派可从白名单自选;白名单外路由在创建子代理前被拒;
- 省略显式选择的委派沿用父会话当前路由(
agent-default-model 只决定新会话的出厂路由,与本卡片无关)。
- 0.6.0 起移除了「固定默认模型」(静态
agentOptions)半卡:它写在 host 面 tool-subagent 行,而 web 层禁用 host 面委派行、由 agent preset 接管,功能从未生效。
- 逐模型能力
- 图片输入支持:
llm-pi-ai 每模型 input(目录路由写 modelOverrides.<modelId> 外科覆盖,声明路由整表重写 models);llm-deepseek 每模型 inputModalities;
- Reasoning effort 映射:
llm-pi-ai 每模型 reasoningEfforts(勾选等级进选择器,值为线路拼写;off 可留空;false = 非推理模型)+ 路由级默认 effort(reasoning 字段);llm-deepseek effort 集合固定且锁定路由级,此页只提供路由级字段。
只显示已激活的路由;休眠(未配置)路由隐藏并在顶部提示隐藏条数。写入走官方 Models 页同一 wire(settings.mutate path ops + namespace revision 围栏),两页共存不冲突,保存即生效无需重启。
安装
dsh plugin --profile web add "github:homily707/dsh-custom-provider"
# 本地开发:dsh plugin --profile web add link:<本仓库检出路径>
dsh plugin add 只管依赖,装完还需把 dsh-custom-provider 加进 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 数组才会被加载。重启 dsh web(或 dsh --profile web)后刷新页面,设置面板即出现「自定义模型」分区。
导航图标(宿主补丁,可选)
设置面板左列的图标是宿主包 dsh-client-ui-settings-general 里按 section id 硬编码的 navIcon() 映射(models→数据图标,未知 id 默认齿轮),插件侧无挂钩。要让本分区与「模型」页同图标,需给宿主文件加一行(dsh 升级会覆盖,需重打):
python3 - <<'EOF'
f = '<dsh 安装目录>/node_modules/@deepseek-ai/dsh-client-ui-settings-general/lib/client.js'
s = open(f).read()
old = '\t\tif (id === "agent-presets") return'
new = '\t\tif (id === "custom-provider") return (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconDataOutline16, {\n\t\t\tclassName: SettingsRoot_module_css_default.navIcon,\n\t\t\tsize: 16\n\t\t});\n' + old
assert s.count(old) == 1
open(f, 'w').write(s.replace(old, new))
EOF
# 然后重启 dsh web 并刷新页面
工作方式
- 浏览器半侧(
client.js)以 window.__ModuleLoader__.load({id, factory}) 的 lazy-CJS 工厂格式手写,经 dsh.client / exports["./client"] 由 client-modules 半侧扫入 boot graph,从 /plugins/dsh-custom-provider/client.js 提供,无需重建 Web app;注册进 settings.section list slot。
- Host 半侧(
index.js)注册 GET/PUT /model-capabilities/subagent webserver 路由:子代理卡片写入 $DSH_HOME/cordis.patch.yml(home 级用户补丁层)中由本插件托管的标记块(# >>>/<<< dsh-custom-provider subagent (managed))——只改写标记块内内容,文件中其他手工条目与注释逐字节保留;写前整文件 parse 校验,写用 tmp+rename。web profile 的 patchReload 为 live,保存后 dsh 热加载补丁行;其他 profile 需重启。仅对之后创建的会话生效。
- 取数:
api.llm.providers({})、ctx.settingsScope.describe() mirror、api.llm.models({})、remote.llm.listProviders + remote.session.modelCatalog(下拉选项)。
- 冲突(
settings-conflict)时提示收起重开;推送来的 invalidation 会自动刷新页面数据。
已知限制
- deepseek 路由无逐模型 effort 映射(适配器锁定在路由级);pi-ai 逐模型字段只有能力映射,没有「每模型默认档」——默认档只有路由级一档。
- 子代理模型自选策略在会话创建时采样记录,改动只对之后的新会话生效。
- loader patch 的
config 是整键替换,托管块全量重声明 dsh-base 的 tool-subagent 基线;dsh 升级若改变基线需同步 index.js 的 BASE_TOOL_CONFIG。
- 省略显式选择的委派走父会话路由、不经白名单校验(dsh 设计:纯继承豁免策略);如需控制省略路径落点,调
agent-default-model(~/.dsh/settings.yaml)或 composer 当前模型。
English
A dsh (DeepSeek Harness) web Settings extension adding a "Custom models" section: a subagent delegation allow-list card (the per-delegation model-choice toggle plus the subagent-model-selection allowed routes, mounted through a managed marker block of $DSH_HOME/cordis.patch.yml and the ordinary settings wire), and per-model image-input / reasoning-effort mapping for llm-pi-ai / llm-deepseek routes. Writes go through the same settings.mutate wire as the Models page, so both coexist; saves hot-apply on the web profile. The static fixed-route (agentOptions) knob was removed in 0.6.0 — on web profiles it landed on the host-plane tool-subagent row that dsh-web-app disables in favor of agent presets, so it never reached the running tool.
License
MIT