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
fan56
@fan56
⬇ 2
★ 0
main
安装
dsh plugin --profile web add github:fan56/dsh-model-sync
需要可复现安装时,可在仓库后追加 #commit 固定提交。
dsh plugin: keep llm-pi-ai provider routes' model lists in step with the pi.dev gateway, written through the official settings seam
该插件未提供要点说明,请参考仓库 README。
dshdsh-plugin
- 安装并启动 DeepSeek Harness:
npx @deepseek-ai/dsh web - 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
- 用 dsh plugins list 确认已安装,必要时重启 Harness 生效
插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。
| 代码仓库 | github.com/fan56/dsh-model-sync |
| 许可证 | 未标注(见仓库) |
| 主要语言 | main |
| 下载量 | 2 |
| GitHub 星标 | 0 |
| 最近推送 | 2026-08-29 |
| 收录日期 | 2026-09-19 |
| 分类 | 模型与提供方 |
事实信息来自公开插件目录快照(2026-10-03),介绍文案由本站再加工。
以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。
[简体中文](./README.zh-CN.md) | English
# dsh-model-sync
[](https://www.npmjs.com/package/@aiwayds/dsh-model-sync) · [GitHub](https://github.com/fan56/dsh-model-sync)
A dsh (DeepSeek Harness) Cordis plugin that keeps the model catalog of your `llm-pi-ai` provider routes in step with the pi.dev gateway's model listing — written into dsh `settings.yaml` through the official settings seam (`settings.mutate`), with zero patches to dsh internals.
https://github.com/user-attachments/assets/c3f9c8b1-ea5e-470c-b8a8-60a81fc5c20a
*A live recording of a dsh session running `/model-sync` (MP4, 1.5× speed) — drop reasons, per-route sync statuses and the change report in action. More demos in the [Demos issue](https://github.com/fan56/dsh-model-sync/issues/1).*
## Why
Model lists drift: providers ship new models, retire old ones, and adjust capabilities (`contextWindow`, `input` modalities, `thinkingFormat`, reasoning efforts). Keeping them in sync by hand is error-prone busywork. dsh-model-sync does it for you:
- **Add-only, change-only writes.** New models from pi.dev are merged in, existing ones updated, and unchanged routes are left completely untouched — the writer compares against the raw user segment and skips a route when nothing changed (`writer.ts`, `profilesEqual`, `reason: 'no-change'`).
- **No hand-maintained model lists.** The pi.dev remote catalog is the source of truth for the managed routes; your `settings.yaml` simply reflects it.
- **Scheduled refresh.** An auto round runs shortly after startup and then on a configurable interval, so the catalog stays current without any interaction.
## Features
- **pi.dev gateway sync.** Fetches each managed route's model list from `https://pi.dev/api/models/providers/` with ETag/304 revalidation and a persistent per-provider cache under `~/.dsh/models-store.json` (`remote-catalog.ts`). Transient failures and aborts keep the last-good cache; a 404/501 treats the route as absent for the round.
- **Default routes.** When `managedRoutes` is empty, these pi.dev routes are synced: `opencode-go`, `zai-coding-cn`, `minimax-cn`, `xiaomi-token-plan-cn` (`DEFAULT_ROUTES` in `src/index.ts`).
- **Two write modes** (`writeMode`):
- `settings` — the zero-patch pipeline: fetch → translate → `settings.mutate`. Self-contained; never touches `settings.yaml` directly, only via the official settings API.
- `overlay` (default, legacy) — delegates to the patched `dsh-llm-pi-ai` adapter's `piAiCatalog.refresh()` and merges pi.dev entries in memory (requires the optional patch).
- **Scheduled refresh.** `intervalMinutes` auto rounds (default 240 / 4h) plus a `startupDelaySeconds` initial delay (default 5); each round logs the same report a manual refresh produces. `0` disarms the interval (startup-only). The interval re-arms live when the config changes (`src/index.ts`).
- **Change reporting / diff.** Every round reports added/removed model ids (`diffModelIds`), and in `settings` mode added/removed/changed entries against the current raw settings (`diffEntries`, `diff.ts`). Dropped and degraded entries are reported with their reasons.
- **`modelSync` service.** Exposes a `modelSync` service (`syncNow()`) that a UI can call to force one refresh round and read the report.
- **`/model-sync` command.** The plugin registers a `/model-sync` slash command itself through the shared dsh command registry (`@deepseek-ai/dsh-commands`), so every interactive UI lists it automatically — no UI-side wiring. Running it forces one sync round on the spot and prints the same report the scheduled rounds log; the sync scope is decided by `managedRoutes` (arguments are ignored). The registry is an optional peer: hosts without a command registry still get the scheduled rounds and the `modelSync` service.
- **Translation rules.** pi.dev entries are translated into settings-writable model profiles (`translate.ts`): base-matching vs base-less classification, `reasoningEfforts` derivation (S2 gate), `compat` gating to `openai-completions` (S5 gate), `maxTokens` handling, and drop logic for mixed-protocol routes.
- **Safe-by-default options:**
- `keepBuiltinOnly: true` — keep built-in catalog models that are not (yet) on pi.dev, so adopting the sync doesn't delete models you already use.
- `dropUnserviceable: true` — drop unserviceable entries and continue; set to `false` to abort the whole route instead of writing a partial list.
- `forceMaxReasoningEffort` — force models with a non-empty `thinkingFormat` to max reasoning effort (ensures `reasoningEfforts` contains `max` and forces `compat.supportsReasoningEffort = true` on `openai-completions`).
- **Conflict-safe writes.** Writes carry the settings revision and retry once on `SETTINGS_CONFLICT` (`writer.ts`).
## Install
Requires Node ≥ 22.19 and a dsh profile. Install as a dsh plugin:
```bash
npm i @aiwayds/dsh-model-sync
dsh plugin add @aiwayds/dsh-model-sync
```
The package ships `cordis.patch.yml` (wired as `dsh.bundle.patch`), which mounts the plugin into the profile's assembly tree under the stable plugin id `dsh-model-sync` and registers the `model-sync` settings namespace.
As of dsh-tui-pi 1.0.2, this plugin is a default dependency of `@aiwayds/dsh-tui-pi` (mounted automatically through its `cordis.patch.yml`) — you normally don't need to install it separately; use `dsh plugin add @aiwayds/dsh-model-sync` only for standalone use.
## Usage
Configure the plugin under the `model-sync` namespace in `settings.yaml` — every key is optional:
| Key | Default | Description |
|---|---|---|
| `writeMode` | `'overlay'` | `'settings'` for the zero-patch pipeline; `'overlay'` 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 |
| `forceMaxReasoningEffort` | `false` | Force max reasoning effort on models with a non-empty `thinkingFormat` |
Example:
```yaml
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.
### 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.
## Development
```bash
npm run build # tsc → lib/
npm run check # tsc --noEmit typecheck
npm test # node --test (pretest builds): diff / translate / writer / remote-catalog / serviceability / command
```
Tests use per-route pi.dev fixtures under `test/fixtures/` and temp directories for the models store — they never touch the real `~/.dsh`.
Utility scripts under `scripts/`:
- `generate-builtin-snapshot.mjs` — regenerate `src/builtin-catalog-snapshot.ts` from the installed `@deepseek-ai/dsh-llm-pi-ai` catalog (`--generate` for dev, `--check` for CI).
- `verify-no-patch.mjs` — exits non-zero if any installed `dsh-llm-pi-ai` still carries the overlay patch signatures (`withRemoteCatalog` / `piAiCatalog`).
- `backup/backup-patched.mjs` — back up a patched `dsh-llm-pi-ai/lib/index.js` to `backups/`.
- `backup/restore-official.mjs` — restore the official unpatched `dsh-llm-pi-ai/lib/index.js` from npm, validated against the patch (`--dry-run` supported).
The repo also carries the reference patches that document the legacy overlay behavior: `docs-dsh-llm-pi-ai.patch` (pi.dev remote-catalog overlay for `dsh-llm-pi-ai`) and `docs-dsh-llm-pi-ai-compat.patch` (`supportsDeveloperRole` compat passthrough).
## License
MIT.
数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。