- Accueil
- Plugins
- Modèles et fournisseurs
- dsh-model-list
dsh-model-list
jsoncode/dsh-model-list
OpenRouter free-models browser plugin (dual-face): fetch OpenRouter models, filter the free ones (price 0 or :free), list them newest-first in a Settings tab with local search and full model info, and create a ready-to-use DSH model config (settings.yaml
Installer
dsh plugin --profile web add github:jsoncode/dsh-model-listREADME
dsh-model-list
dsh-model-list is a DeepSeek Harness (DSH) plugin that browses OpenRouter's model directory (the official openrouter.ai/models catalog) and adds any model — free variants included — to your DSH model list in one click.
- Model Hub entry (设置 → 模型聚合平台 / Model Hub): the Settings entry hosts one tab per provider
platform (OpenRouter today; the
PLATFORMSregistry makes future providers a one-line addition). All fetch logic runs host-side; the tab is the single entry point. - Show-in-menu toggle: a slide switch at the very top of the platform page. When on, a
【模型聚合平台 / Model Hub】 entry button appears in the host sidebar's footer action area and opens the
same directory in a large overlay. The preference persists in
localStorage(default off). - Dialog palette: the overlay and dialogs follow dsh-get-balance — a
rgba(0,0,0,.32)scrim withblur(12px) saturate(1.2), acolor-mix(bg-layer-1 78%)glass panel with aborder-l2hairline, 14px radius and a0 16px 48px rgba(0,0,0,.28)shadow,border-l1dividers, solidbutton-primary-fillfor primary buttons and active tabs / sub-tabs / filter chips,bg-baseinputs,bg-layer-2cards, andstate-*tokens for status colours. - Official directory, 1:1: the host fetches the official frontend endpoint
https://openrouter.ai/api/frontend/v1/models/find?active=true&fmt=cards&order=newest— once withvariant=standardand once withvariant=free(both return one card per model, no pagination) — and joins each card's weekly token usage from the response'sdata.analytics. The browser renders the official filter set client-side: search, sort (weekly usage / newest / context size / input price / output price / name), input & output modalities, prompt-pricing buckets (Free / <$1 / $1–$2 / $2–$5 / $5–$10 / >$10 per M tokens), context-length buckets (<8K / 8K–32K / 32K–128K / 128K–1M / >1M), capabilities (tools / reasoning / structured outputs), series and providers. Cards follow the official anatomy: author avatar, name, weekly usage, provider, description, and spec chips (context, max output, input/output price per M tokens, modality arrows, capability badges). - Full info per card: id (click to copy), provider, quantization, created date, supported parameters, moderated / forced-reasoning flags, upstream warnings, expandable full description. Layout adapts to narrow panels and mobile widths.
- "Add to model list" → one-click model config: the dialog takes an OpenRouter API token only when the
platform has no stored credential yet (live-checked via
GET /api/v1/keyon demand). Confirming then- stores the token through the host credentials service (
.credentials.yaml,OPENROUTER_API_KEY), - merges the model into the OpenRouter route in
settings.yaml(llm-pi-ainamespace — reuses the existingopenrouter/openrouter-free/ openrouter.ai route when one exists, preserving itsapiKeyEnvand model entries verbatim; otherwise createsopenrouter-freewith theopenai-completionsprotocol andhttps://openrouter.ai/api/v1), and - optionally sets it as the default model for new sessions (
agent-default-modelnamespace). The model is selectable in the chat composer's model selector immediately — no host restart.
- stores the token through the host credentials service (
- Robust fetching: every OpenRouter request retries up to 10 times (exponential backoff + jitter);
a failed refresh degrades to the cached list with a stale notice. Results are cached in
$DSH_HOME/dsh-model-list.json(6-hour freshness window). - Bilingual UI (中文 / English), no hardcoded paths.
Commands
| Script | What it does |
|---|---|
npm run check | tsc -b typecheck (host + client programs) |
npm run build | clean lib/, tsc -b, then tsdown bundles lib/index.js (host, ESM) + lib/client.js (browser, __ModuleLoader__ factory) |
npm run watch | tsdown watch mode |
npm run verify | simulate the host module loader against lib/client.js (factory shape + seed externals) |
npm run test:ops | offline host-logic tests (find/cards normalization, weekly-usage join, route detection, config-write orchestration, store round-trip incl. v1-cache rejection) |
npm run smoke | live smoke test against the real OpenRouter models/find endpoint |
npm run release | check + build + verify, then npm version patch and git push --follow-tags |
npm run publish:npm | check + build + verify, then npm publish --access public |
Installation
# Local development (link the workspace; picks up rebuilds of lib/ automatically)
dsh plugin --profile web add ./dsh-model-list
# Published: npm / tarball / GitHub
dsh plugin --profile web add dsh-model-list
dsh plugin --profile web add github:you/dsh-model-list#<sha>
dsh --profile web --dump-config # verify the layer
dsh --profile web # start (restart required for the host half to load)
Local development dependencies: the host loads
lib/index.jsthrough native Node ESM, so@deepseek-ai/schemasteryand@deepseek-ai/dsh-settingsmust be resolvable from the plugin directory. Either runpnpm installinside the plugin directory, or use the committedlib/build (this repository commitslib/, mirroring dsh-jenkins).
Usage
- Open Settings → 模型聚合平台 / Model Hub (or enable 在菜单中显示 / Show in menu at the top of the page and use the 【模型聚合平台】 button at the bottom of the host sidebar), pick the platform tab (OpenRouter).
- The directory arrives from cache when fresh (hit 刷新 to force a refetch). Use the search box, the variant dropdown, the output-modality tabs, the sort dropdown (weekly usage / newest / context / prices / name), and the filter groups (input modalities, discount, context length, prompt & output pricing, series, supported parameters, providers, model authors) — the official models-page set.
- Click 添加到模型列表 / Add to model list on a card:
- the token field appears only when the platform has no stored credential yet
(otherwise the existing
OPENROUTER_API_KEYis reused and noted in the dialog), - optionally tick 设为新会话的默认模型,
- confirm — the config is written and the dialog shows the exact route/model to pick in the composer's model selector.
- the token field appears only when the platform has no stored credential yet
(otherwise the existing
Adding a platform
src/client/components/FreeModelsSection.tsx: append{ id, labelKey }toPLATFORMSand mount the panel by id.- Copy
src/client/components/OpenRouterPanel.tsxas a starting point; ops carryplatform: '<id>'. src/host/ops.ts: extend therunOpplatform dispatch (fetch/filter per the platform's API, map its models ontoRouteModelProfile, and teachmodel-config.tsthe platform's credential ref and route naming).
Structure
├── src/host/*.ts # Host half: /dsh-model-list/api route (platform-dispatched ops),
│ # OpenRouter fetch+filter+sort (10 retries), cache store,
│ # model-config writer (settings + credentials services)
├── src/client/*.tsx # Browser half: settings.section shell with platform tabs,
│ # per-platform panel (search, cards), add-to-model-list dialog
├── lib/index.js # Host half build artifact (tsdown, ESM), committed
├── lib/client.js # Browser half build artifact (tsdown → __ModuleLoader__ factory), committed
├── scripts/ # verify-client.mjs, test-ops.mts (offline), smoke-openrouter.mts (live)
├── tsdown.config.ts # node half + client bundle banner wrapper
├── cordis.patch.yml # Bundle patch: plugin row referenced by package name
└── package.json # dsh.bundle + dsh.client(web) manifests + peerDependencies
Notes
- OpenRouter free models still require an account token (daily rate limits apply); the dialog says so.
- The write path is the sanctioned one:
settings.update('llm-pi-ai', …)validates against the llm-pi-ai schema (a bad profile is refused where it is written) and the adapter re-registers routes live, so no host restart is needed after adding a model. - Manual edits to an existing OpenRouter route (custom
apiKeyEnv, extra profile fields) are preserved: adding a model only rewrites that route'smodelsarray (merged by id, same id → replaced). - The plugin never touches settings/credentials files directly — everything goes through the host
services; its own cache file (
dsh-model-list.json) is the only file it writes.
Plugins associés
dsh-routing-suite
yjh051108/dsh-routing-suite
dsh-plugin-subscriptions
v1ki/dsh-plugin-subscriptions
dsh-commandcode-provider
mars-sea/dsh-commandcode-provider
dsh-workbuddy-connect
corrinehu/dsh-workbuddy-connect