DSH XD Pool
XDTrees/dsh-xdpool把本机 WorkBuddy 桌面 App 登录过的所有账号自动并入 DSH 模型池:多账号轮换自动容错、实时积分,模型目录按模型标注积分倍率与限时免费 / 夜间折扣。
DSH 网页端模型能力管理插件:控制推理档位、上下文与输出上限、输入模态及网关兼容预设,双语界面。
Model Capability Manager — manage the llm-pi-ai provider routes of DeepSeek Harness (DSH Web) from a dedicated Model Capability page in the in-app settings: per-model thinking levels, context window, output cap, input modalities, per-route defaults, gateway compatibility fields, one-click presets, and an EN/中文 switchable UI.
简体中文说明 · Report Bug · Request Feature
DSH stores provider configuration in the active profile's llm-pi-ai.providers entry. Editing profile patches by hand is error-prone, and two classes of problems bite people often:
compatible-mode, Moonshot/Kimi, Zhipu/BigModel, MiniMax, Volcengine Ark, SiliconFlow, Baidu Qianfan and other gateways may reject developer role messages or reasoning_effort echoes the way the OpenAI/Anthropic dialects expect. Turning compat.supportsDeveloperRole on against such a gateway produces 400-style errors.off / minimal / low / medium / high / xhigh / max) each need a wire value the upstream provider understands (e.g. low → "low" for one vendor, "h3" for another). Max-thinking configs and per-model reasoningEfforts are tedious to author by hand.This plugin gives you a GUI for all of it, plus one-click presets that bake in dialect-safe configurations (see Presets).
| Settings entry | Section overview (EN) |
|---|---|
| Model editor (EN) | Gateway compatibility fold (ZH) | Section overview (ZH) |
|---|---|---|
name, contextWindow, maxTokens — capacity fields accept plain numbers or K/M suffixes (262144, 256K, 1M).models lists and DSH 0.1.7 catalog-preserving modelOverrides entries.input modalities — text / image checkboxes with de-duplication.off/minimal/low/medium/high/xhigh/max), each level with its own wire value. Empty non-off levels are prevented (the Host rejects them), and a one-click fill all levels with the same value button is included.compat editor (folded away by default).displayName, baseURL, api (openai-completions / openai-responses / anthropic-messages).defaultContextWindow, defaultMaxTokens, defaultInput, reasoning, thinkingBudgets (minimal/low/medium/high), cacheRetention, transport.compat editor, including DSH 0.1.7 finish-reason, thinking-budget, max_output_tokens, Baseten and vLLM controls, plus an Advanced fold for timeouts, image limits, headers, and raw JSON.api.json only when you click Load catalog; Fetch latest catalog explicitly refreshes it. Each local route can be mapped to a models.dev provider or excluded.name, context limit, output limit, and supported text/image inputs are independently selectable. Reasoning is opt-in because provider wire semantics vary: explicit effort lists are mapped, reasoning: false disables reasoning, and toggle-only/unknown formats preserve the manual value.localStorage for 24 hours. A failed refresh can use that stale last-known-good catalog; without a valid cache, the operation stops without touching settings.| Preset | What it does |
|---|---|
| Safe gateway | compat.supportsDeveloperRole=false, supportsReasoningEffort=true — for gateways that reject developer role messages (DashScope compatible-mode, Kimi/Moonshot, Zhipu, MiniMax, Ark, SiliconFlow, Qianfan, …) |
| OpenAI native | developer role + reasoning_effort + thinkingFormat=openai + maxTokensField=max_completion_tokens |
| DeepSeek dialect | thinkingFormat=deepseek, developer role on, reasoning_effort on |
| Qwen dialect | thinkingFormat=qwen, developer role off, reasoning_effort on |
| Max thinking (7 levels) | every model declares all 7 levels, reasoning=high, generous thinkingBudgets |
| Text only | defaultInput=['text'] and per-model input=['text'] |
| Image ready | defaultInput=['text','image'] and per-model input=['text','image'] |
model-capability.customPresets in the active profile configuration.llm-pi-ai user section with one root-level ConfigForms mutation; it is not a merge. Any route that was added to the user section after the preset was saved will be deleted. This is not an additive recipe — treat the preset as a full snapshot.authorization, api-key, etc.) are blocked in the headers editor, and the headers dict is stripped from every provider route when saving a custom preset (credentials travel as apiKeyEnv reference names, never as literal header values). Existing presets that were saved before this safeguard are detected at startup and reported in the advisory checks.supportsDeveloperRole on (hint: use Safe gateway), reasoning levels that map to no wire value, models without an explicit contextWindow, and routes without models.model-capability.language), not just to the browser session.All writes go through the DSH settings service with revision fencing (expectedRevision), the same pattern the built-in Models page uses; conflicting concurrent edits are retried via the live mirror. If the page is opened from a non-loopback origin (where writes are not allowed), every control is disabled with a hint.
Requires a DSH installation with the web app (any profile that serves the browser UI), DSH ≥ 0.1.7-rc.2. Plugin v1.4.0 migrated to the ConfigForms/volatile-Config settings kernel introduced by this DSH line.
Upgrading from an older DSH: DSH 0.1.7 imports legacy
settings.yamlsections into the active profile once and renames the old file tosettings.yaml.imported. The plugin'smodel-capabilityentry participates in that migration; do not copy the imported file back over the profile configuration.
dsh plugin --profile web add dsh-plugin-model-capability # latest stable, or pin @<version>
Then restart dsh --profile web (the running Web UI is not hot-reloaded on plugin install). The Model Capability entry appears under Settings.
For other profiles, replace web with your profile name.
Pin the exact version when you need a specific release — see Getting the latest version below. Installing without a version may resolve to an older release cached locally or on the registry CDN.
A new release is only picked up when all three caches agree — the npm registry
CDN metadata, your local pnpm store, and the profile's lockfile. Any one of them
stale means dsh plugin add dsh-plugin-model-capability (no version) keeps
installing the old build. To guarantee you get the newest version:
Check what the registry currently has:
npm view dsh-plugin-model-capability version
If this does not show the version you expect, the registry CDN still serves
stale metadata — wait ~1–2 minutes and retry (npm publishes are usually
visible in seconds, but the packument metadata is cached per-TTL).
Uninstall any previously installed copy first (see Uninstall
below). The profile lockfile (node_modules/.pnpm/lock.yaml /
pnpm-lock.yaml) otherwise keeps the old version pinned.
Install with the exact version — this bypasses metadata resolution:
dsh plugin --profile web add dsh-plugin-model-capability@<version>
# e.g. dsh plugin --profile web add dsh-plugin-model-capability@1.1.1
Clear stale local caches if the profile still reports an old version:
pnpm store prune # remove unreferenced store packages
or, for the profile itself:
cd "$HOME/.dsh/profiles/web"
pnpm store prune
Verify what actually got installed:
grep -A2 '"dependencies"' "$HOME/.dsh/profiles/web/package.json"
(Windows PowerShell: Select-String -Path "$HOME\.dsh\profiles\web\package.json" -Pattern "model-capability")
The version shown next to dsh-plugin-model-capability must match the version you intended to install.
Restart the web UI — the plugin is loaded at startup, never hot-reloaded:
dsh --profile web
Registry note: an already-published version can never be overwritten. If a bad
build got released under 0.1.2, the fix is a new version (0.1.3, 1.1.1, …),
not a re-publish — which is exactly why "install the latest" means pin the
version, not npm update.
dsh plugin --profile web remove dsh-plugin-model-capability
If the command reports no such dependency found (a broken install whose
dependency entry is missing from package.json), remove it directly inside the
profile:
cd "$HOME/.dsh/profiles/web"
pnpm remove dsh-plugin-model-capability
After either step, restart dsh --profile web.
To verify the plugin is fully gone:
"$HOME/.dsh/profiles/web/package.json" — no dsh-plugin-model-capability
entry under dependencies"$HOME/.dsh/profiles/web/node_modules/dsh-plugin-model-capability" — directory
no longer exists"$HOME/.dsh/profiles/web/pnpm-lock.yaml" — no dsh-plugin-model-capability
reference (0 hits)The host half also loads headlessly (it registers the settings schema); the settings UI itself needs the web app.
After installing the plugin and restarting DSH, the Model Capability page is available under Settings in the sidebar. Here is how to get started in three steps:
Navigate to Settings → Model Capability. You will see a list of all configured provider routes (e.g. openai, anthropic, dashscope, etc.), each with its models listed underneath.
The fastest way to get a working configuration is to use a one-click preset:
The preset fills in the recommended compat fields, thinking levels, and defaults automatically.
Click any model row to expand its editor. From there you can:
K/M suffixes, e.g. 128K, 1M).text / image).All changes are saved immediately through the DSH settings service with revision fencing — no manual YAML editing required.
Tip: If the page shows "Advisory checks" at the top, review them — they flag common misconfigurations like legacy gateways with
supportsDeveloperRoleenabled.
Open Sync from models.dev, click Load catalog (or Fetch latest catalog to bypass a fresh cache), verify or change each route-to-provider mapping, and choose the fields to update. Review the matched/changed/unmatched counts before clicking Apply previewed changes. This workflow complements manual editing and presets; it does not replace either one.
The adapter follows the models.dev shape provider.models[modelId] and currently reads name, limit.context, limit.output, modalities.input, reasoning, and reasoning_options. Unknown fields and unsupported modalities are ignored, so an upstream schema extension does not overwrite local configuration accidentally.
One npm package with two halves, installed as a profile bundle by dsh plugin add:
lib/index.js — the host half: exports a schemastery Config whose language and customPresets fields are volatile, letting DSH 0.1.7 project the model-capability form from the live plugin entry; it disables the generic generated page because this bundle supplies one.lib/client.js — the web client half: a classic-script bundle registered with the web shell's module loader. It follows the served llm-pi-ai namespace, injects a settings.section, obtains both forms through the shared ctx.configForms mirror, and drives all edits through queued path mutations with revision fencing.src/client/models-dev.js — validates and normalizes the remote catalog, owns the local cache/fallback policy, and creates non-destructive route replacements for the settings layer.cordis.patch.yml — declares the bundle row, so dsh plugin add wires the whole thing automatically (no manual patch editing).The llm-pi-ai schema itself is owned by DSH — this plugin only edits its values, so the Host keeps validating every write (assertServiceable etc.).
pnpm install
npm run build # esbuild → lib/client.js (loader-wrapped) + lib/index.js
npm test # mapping, preservation, cache, and fallback tests
Local testing: create a dev profile (e.g. web-dev), add the web app and the plugin, and restart the server on a separate port:
dsh plugin --profile web-dev add @deepseek-ai/dsh-web-app@0.1.7-rc.2
# add the local package, then note: `file:` dependencies are snapshotted —
# re-add after every rebuild, or replace the installed copy with a junction:
dsh plugin --profile web-dev add file:D:/path/to/dsh-plugin-model-capability
dsh --profile web-dev --port 3091 --no-open
Screenshots are captured with the included script (needs playwright-core and a local Chrome/Edge):
node scripts/screenshots.mjs [baseURL] [outDir]
node scripts/verify-dom.mjs [baseURL] # shadow-DOM-aware rendering checks
node scripts/e2e-write.mjs [baseURL] # end-to-end write smoke test (back up the profile config first!)
The DSH settings service only accepts writes from loopback origins (i.e. http://127.0.0.1:3080 or http://localhost:3080). If you are accessing the web UI from a different IP address or through a reverse proxy, every control on the page is disabled automatically and a hint is shown. Connect via localhost to make changes.
It sets compat.supportsDeveloperRole=false and supportsReasoningEffort=true. This is the safest choice for Chinese cloud gateways — DashScope (compatible-mode), Moonshot/Kimi, Zhipu/BigModel, MiniMax, Volcengine Ark, SiliconFlow, Baidu Qianfan, and others that do not accept the developer role message that OpenAI/Anthropic dialects send.
The plugin detects credential-shaped header names (e.g. authorization, api-key) in the headers field of a provider route. This is a safety advisory, not a block — but credentials should be stored as apiKeyEnv environment variable references instead of literal header values, especially when saving custom presets (the preset system strips headers automatically).
The plugin edits existing routes in the llm-pi-ai providers section. Add a provider from DSH's built-in Settings → Models page; once its profile exists, this plugin picks it up from the shared settings mirror. Catalog routes using modelOverrides remain catalog-backed instead of being converted to explicit model lists.
Click the model row to expand its editor and clear the fields you want to reset. The route-level defaults (set in the route editor) are used as fallbacks when a per-model value is empty.
The language choice (model-capability.language) is stored in the active profile configuration and survives restarts. If it keeps resetting, check that the profile is writable and that no other process is overwriting it.
thinkingBudgets only have minimal/low/medium/high when there are 6 thinking levels?This is not a bug — it is a deliberate schema design. DSH's thinking capability has two separate layers:
1. Thinking Levels (6 levels) — defined by pi-ai core:
minimal | low | medium | high | xhigh | max
All 6 levels can be configured with wire values in each model's reasoningEfforts.
2. Thinking Budgets (4 levels) — defined by dsh-llm-pi-ai schema:
minimal | low | medium | high
There is no xhigh or max budget field.
The thinkingBudgets controls custom token budgets for token-based providers (e.g. Anthropic/Bedrock). At runtime, when xhigh or max levels are used, the system falls back to default budgets:
const budget = options.thinkingBudgets?.[level] ?? defaultBudgets[options.reasoning];
So if you set thinkingBudgets.minimal/low/medium/high, those levels use your custom values, while xhigh and max use the provider's default token allocation strategy — no custom budget is needed for those levels.
Full step-by-step instructions (including a post-release checklist) are in
PUBLISHING.md. Summary:
npm publish — run after npm run build (the prepublishOnly hook rebuilds automatically). The package ships lib/, cordis.patch.yml, img/, license, the English README and the Chinese guide in docs/.package.json.Contributions are welcome! Here is how you can help:
The plugin is built with esbuild; run npm run build after making changes to the src/ files. See the Development section for local testing instructions.