DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Model Provider — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
M

dsh-model-provider

Model Provider

Provider-first model selector for the DeepSeek Harness model seat: pick a provider, then a model from that provider — current model always shows Model · Provider; search and hardening (v0.3.2, verified against DSH 0.1.1-rc.2).

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:pc439527/dsh-model-provider#79c6c021e740a900bd581c7034dbefc1e0ee63bb
READMECompatibilityVersions
Plugin screenshotPlugin screenshot

Compatibility and provenance

Model Provider is published as dsh-model-provider and currently resolves to version 0.3.2. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/16/2026

Versions

0.3.2stable
9/16/2026
0.3.1stable
8/29/2026
0.3.0stable
8/24/2026

Related plugins

Loading related plugins…

Latest
0.3.2
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 1
Weekly downloads
0
Last push
8/31/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in models-usage.

Usage@linxin666/dsh-usageUsage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with the current session provider's today usage on the sidebar entryWhale Widgetdsh-whale-widgetDeepSeek balance whale widget in the bottom-right corner of the DSH Web interface: balance/today’s usage/peak-off-peak pricing, customizable bubble click sequence (text/balance/today/peak-off-peak/image/random phrases and parallel weighted selection), per-line styles and fonts, floating quick editinUsage Stats@ychris12138/dsh-usage-statsToken usage heatmap, provider balances, and subscription quotas for the dsh web GUICodex Connectdsh-codex-connectChatGPT OAuth and Codex models for DeepSeek Harness.

README

dsh-model-provider

License: MIT · Platform: DSH Web (client plugin)

English · 简体中文

Provider-first model selector for DeepSeek Harness (DSH): pick a provider first, then a model from that provider. The current model always reads as Model · Provider — without touching the harness's original model-calling or session-state logic.

In the DSH Web interface, the composer model seat is upgraded from "provider groups + full model list" to a three-level selector (v0.3.0):

Before                        After (this plugin v0.3.0)
DeepSeek V4 Flash             DeepSeek V4 Flash · OpenCode Go

Try opening the dropdown (still tidy even with many models):

Level 1 (root menu)           Level 2 (Provider)            Level 3 (Model)
├─ Model   DeepSeek V4 Flash >   ├─ opencode-go  8 models · current >   opencode-go
└─ Effort  High              >   ├─ luckikey     2 models        >   ├─ MiniMax-M3
🔍 Search providers               ├─ OpenRouter  20 models       >   ├─ Qwen3.7 Max
    (filters Provider rows)         ├─ DeepSeek     4 models       >   ├─ DeepSeek V4 Flash ✓
                                    └─ OpenRouterX  failed ⚠ retry    ├─ DeepSeek V4 Pro
                                 🔍 Search opencode-go models         └─ GLM-5.1
                                    (current provider only)
image image
  • Provider is its own level: the provider list pins the current provider to the top and marks it "· current"; the rest keep catalog order. The Model page renders only the selected provider's models — no more provider × model flattening.
  • Failed providers are a row too: a provider that failed to load no longer lives only in a warning banner — it is a normal Provider row ("failed ⚠ retry") that reloads on click.
  • Search (v0.3): both the Provider and Model pages have an inline search box — Provider page filters providers by name/ID; Model page filters only the current provider's models (no cross-provider search).
  • Model page header: entering a provider shows "‹ {provider}" + a "{N} models" subtitle, making it feel like its own page.
  • Lean trigger: shows Model · Provider by default; "· Effort" is appended only when you actively pick a non-default reasoning effort — no wasted horizontal space for "Default".
  • Esc walks back level by level: Model → Provider → root menu → close (clicking "‹" walks back the same way).
  • The Model · Provider [· Effort] trigger always matches the harness session state.

How it works

ConcernDetail
Extension pointOfficial Slot system: conversation.input.model (single slot, session scope) — no DOM hack
OverrideSame-named slot registered at priority: -1 — the slot renders the lowest-priority entry, so this component wins and the original seat is shadowed
DataReuses the harness's native modelDirectories service (per-session shared ModelDirectory); selection semantics and disable logic are unchanged; the provider list comes straight from state.groups, failures from state.failures
FallbackThe registration disappears on plugin unload (slots.inject effect teardown) and the original model seat is restored instantly and unchanged
NamespaceOwn locale dictionary modelProvider (zh/en) — no intrusion into harness copy

Compatibility

Verified against DeepSeek Harness 0.1.1-rc.2 (dsh CLI 0.1.1-rc.2 + web frontend). The APIs this plugin depends on are unchanged across the rc.8 → rc.2 release line:

Surfacerc.2 status
Slot compositionctx.slots.inject(key, cb) / slots.register with priority (ascending, lowest renders) + optional registrant — unchanged; same key at the same priority throws, a different priority shadows
Seat contractconversation.input.model (single slot, session scope): owner share locked, locale t seat, inject face { available, directory, load, select } — unchanged
Directory faceShared per-session ModelDirectory snapshot { current, routable, groups, failures, status, error } — unchanged
PrimitivesIconChevronDown/Left/RightOutline14, IconCheck/Search/WarningOutline16, Toast { text, icon, anchor, onDone } — unchanged
Design tokens--dsw-alias-*, --dsw-specific-menu, --dsw-shadow-lv3, --dsh-scrollbar-* — unchanged

peerDependencies now track the rc.2 line (^0.1.1-rc.2, same pins the first-party client packages use).

The component keeps the original ModelSelect interaction baseline (shared directory & selection RPC / keyboard arrows & Esc / failure retry & Toast / effort page), only turning the two-level flat list into three-level navigation:

  • Trigger: model name + · Provider (muted style); "· Effort" only when a non-default effort is chosen; title and aria carry the provider too
  • Root menu: Model (→ provider list) and Effort (→ current model's effort levels)
  • Provider page: "‹ Select provider" back to root; search filter; current provider pinned to top with a "· current" text mark (no full-row highlight); each row shows "N models"; failed providers render as retry rows
  • Model page: "‹ {provider}" + "{N} models" subtitle; search box filters only this provider's models; the selected row is marked with ✓ (composite providerId + modelId key — same-named models across providers don't collide)
  • Default effort: switching to a model automatically carries its defaultEffort into the selection (selectionFor is the single place that builds a Selection, so prebuilt choice and click-path semantics stay identical)

Layout

dsh-model-provider/
|- package.json            # dsh.client declaration (platform: web, inject list)
|- pnpm-workspace.yaml     # pnpm 11 setup (approves the esbuild build script)
|- build.mjs               # esbuild bundle script → lib/client.js (ModuleLoader format)
|- tsconfig.json           # noEmit typecheck (src + test)
|- src/
|  |- index.ts             # host half: empty apply (pure browser-surface plugin)
|  |- client.tsx           # client entry: apply() + slot wiring + compat exports
|  |- locale.ts            # modelProvider dictionary (zh/en)
|  |- model/
|  |  ├─ types.ts          # directory/selection wire types
|  |  └─ selection.ts      # pure functions: selectionFor / sortGroupsForCurrent /
|  |                       #   search filtering / Esc stack (shared by UI and tests)
|  |- components/
|  |  ├─ ModelSelector.tsx # trigger + menu shell + state orchestration
|  |  ├─ RootPane.tsx      # level 1: model / effort
|  |  ├─ ProviderPane.tsx  # level 2: providers (search + failed rows)
|  |  ├─ ModelPane.tsx     # level 3: single-provider models (search + composite key)
|  |  ├─ EffortPane.tsx    # reasoning effort
|  |  └─ StatusBlock.tsx   # directory load/error banner
|  |- hooks/
|  |  └─ useKeyboardNavigation.ts  # Esc stack + arrow-key focus
|  └─ model-provider.css   # scoped styles (dshmp- prefix + design tokens)
|- test/model.test.ts      # node --test unit tests (pure-function layer)
|- lib/                    # build output (host serves /plugins/<id>/client.js)
|- assets/icon.svg

Build

pnpm install        # first time: installs esbuild / typescript (npm works too, see below)
pnpm build          # node build.mjs → lib/client.js
pnpm typecheck      # tsc --noEmit
pnpm test           # node --test (no DOM needed; runs the pure-function layer directly)

The build script resolves esbuild via require.resolve("esbuild") from this package's own devDependency — no machine-specific hardcoded paths, so it builds on any machine. (With npm: npm i && npm run build; the committed lockfile is pnpm-generated and npm resolves it itself.)

The output is the standard DeepSeek Harness client-plugin format:

window.__ModuleLoader__.load({ id: "dsh-model-provider", factory: (require) => { ... return module.exports; } });

Installing into a Web profile

The right way (since v0.1.0): this package declares dsh.bundle.patch + ships cordis.patch.yml, i.e. the standard dsh plugin shape (same as dsh-balance-meter / dsh-context). Don't write it as a "bundle without metadata" — that triggers the startup check error: profile bundle "dsh-model-provider" declares no dsh.bundle in its package.json and a restart loop.

  1. Link the dependency into the profile (/data/.dsh/profiles/web/package.json):

    "dependencies": { "dsh-model-provider": "link:/data/opt/dev/dsh-provider-model" }
    "dsh": { "profile": { "bundles": [ ..., "dsh-model-provider" ] } }
    

    (Or use the official dsh CLI: dsh plugin --profile web add /data/opt/dev/dsh-provider-model — it reconciles into bundles automatically per the dsh.bundle.patch declaration.)

  2. pnpm install (materializes the link)

  3. Restart the web host (client-plugin set changes apply on restart): docker restart deepseek-harness or the equivalent dsh web restart

  4. Verify:

    curl -s http://127.0.0.1:3080/ | grep -o '"id":"dsh-model-provider"'
    curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3080/plugins/dsh-model-provider/client.js   # 200
    

    Changing only client.js (no plugin add/remove) needs no restart — rebuild and refresh the page.

Disabling / restoring the original UI

Remove this package from dsh.profile.bundles (or uninstall the plugin) and restart — the original ModelSelect seat becomes the only entry again and the UI is restored.

Roadmap

Shipped (v0.3.1):

  • v0.3 feature set: three-level selector (root → provider → single-provider model list), current-provider pin, failed-provider retry rows, inline search on both levels, lean Model · Provider [· Effort] trigger, consistent default effort
  • Verified against DeepSeek Harness 0.1.1-rc.2 (slot composition / seat contract / directory face / primitives / design tokens all unchanged in this line)
  • peerDependencies aligned to ^0.1.1-rc.2
  • node --test unit tests (current-pinning / same-named models / defaultEffort / Esc stack / search filtering)

Candidates:

  • Plugin settings page (display modes: plain groups / model + provider / both; whether the current model shows its provider)
  • Default model badge (depends on host wire exposing an isDefault field)
  • Recent-use / favorites / model capabilities (context length, pricing) display enhancements
  • Provider icons

License

MIT