@aiwayds/dsh-model-sync
dsh plugin: keep llm-pi-ai provider routes' model lists in step with the pi.dev gateway, written through the official settings seam 适合使用pi.dev网关,需要自动同步最新可用模型列表而无需手动配置的用户。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:fan56/dsh-model-syncREADME
Read the full README ↗Usage
Configure the plugin under the dsh-model-sync settings entry — on dsh 0.1.7+ the entry id (the same stable id the bundle patch always mounted) is the settings namespace; edit it in the settings UI or your profile patch. Every key is optional, and every key is a volatile field, so edits apply without restarting the plugin. Upgrading from a pre-0.1.7 install: a legacy top-level model-sync: section in the old settings.yaml is imported once into the new entry automatically at the next plugin boot (the audit record lands in ~/.dsh/storages/dsh-model-sync/legacy-import.json):
| Key | Default | Description |
|---|---|---|
writeMode | 'settings' | Zero-patch pipeline; 'overlay' (deprecated since dsh 0.2.1) for the legacy patched-adapter mode |
intervalMinutes | 240 (4h) | Auto-refresh interval in minutes; 0 = startup-only |
startupDelaySeconds | 5 | Delay before the first auto refresh, so the llm adapter is ready |
refreshTimeoutMs | 120000 | Abort budget for one refresh round's network request (min 1000) |
managedRoutes | [] | Routes to sync; empty = the default pi.dev routes |
keepBuiltinOnly | true | Keep built-in-only models not present on pi.dev (smooth migration) |
dropUnserviceable | true | Drop unserviceable entries; false aborts the route instead |
syncNotify | false | Notify on changes (logger + /model-sync report) |
forceMaxReasoningEffort | false | Force max reasoning effort on models with a non-empty thinkingFormat |
providerNativeFetch | true | Union each mapped provider's first-party /models listing into the pi.dev result (additions only) |
keepDeprecatedBuiltin | false | Opt back into emitting builtin ids the official default model list dropped (dsh 0.1.7 removed deepseek-v4-flash / deepseek-v4-flash-vision-exp; dsh 0.2.0 removed omen-alpha on opencode-go and glm-4.7 / glm-5-turbo / glm-5.1 / glm-5.2 / glm-5.2-highspeed / glm-5v-turbo on zai-coding-cn; the snapshot keeps the data but no longer syncs them by default) |
Example (settings section dsh-model-sync; a legacy settings.yaml model-sync: section is not auto-imported by the dsh 0.1.7 host itself — the plugin recovers it once at boot, see above):
dsh-model-sync:
writeMode: settings
intervalMinutes: 30
managedRoutes:
- opencode-go
- zai-coding-cn
The plugin writes to the llm-pi-ai namespace (providers..models) — the same document the adapter consumes — and only for the routes it manages. During migration, keepBuiltinOnly preserves models that exist in your installed built-in catalog but aren't on pi.dev yet.
Capacity values are upper limits, not your runtime settings
Synced contextWindow / maxTokens describe what the model accepts at most, as advertised by the gateway listing — not what your deployment is configured for. dsh resolves the settings-written value over the installed catalog, and a written maxTokens becomes the request-level default. Pointing a route at a local or proxied endpoint that serves a smaller context (vLLM / Ollama and friends) while carrying catalog-sized capacities is a known recipe for the "output token limit reached" family of failures.
If you need a model to run under a smaller budget, set it in modelOverrides under the same route — the sync folds the fields into the synced list and re-applies them from its store every round:
providers:
zai-coding-cn:
modelOverrides:
glm-5.3:
contextWindow: 32768
Note that listing data itself can be noisy: values are sanity-gated (positive integers; maxTokens strictly below contextWindow), and stripped values show up in the sync report as DEGRADED lines with reasons.
Manual refresh: the /model-sync command
Type /model-sync in any interactive UI to force one sync round on the spot. The plugin registers the command in the shared command registry (@deepseek-ai/dsh-commands), and UIs discover it automatically. It returns the same report the scheduled rounds log. The sync scope is decided by managedRoutes; any arguments typed after the command are ignored. Hosts without a command registry degrade gracefully — the scheduled rounds and the modelSync service keep working.