Replaces the official tier list in the DSH model menu with an Effort slider panel mimicking Claude Code, and auto-completes reasoning tier metadata for any third-party model, enabling thinking intensity to actually take effect.
- Language
- TypeScript
- License
- BSD-3-Clause
- Branch
- main
Install
$ dsh plugin --profile web add dsh-effort-sliderRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin 2768651338/dsh-effort-slider for me: review the repository at https://github.com/2768651338/dsh-effort-slider first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
One-Line Positioning
Replaces the official effort selector in DeepSeek Harness's model menu with a Claude Code-style infinite-drag Effort slider panel; also enables any third-party custom models to have truly effective thinking intensity levels.
Core Capabilities
- Intercept the "Reasoning Level" row in the official model menu and pop up a Claude Code-style Effort slider panel (infinite drag, snap on release, WebGL flame follow)
- Automatically inject generic 5-level scale (OFF / Low / Medium / High / Ultracode) for third-party models that haven't declared reasoning metadata, making the official level list and this panel selectable and request validation passing
- Automatically complement line-level dictionary and protocol dialect (compat) for pi-ai custom models, translating levels to real online fields like reasoning_effort / thinking, with changes taking effect hot without restart
- After panel closes, the level value in the menu row and the "Model · Level" entry button above the input box continue to display the current level's corresponding color and glow
- Respect user's existing reasoningEfforts declarations (set to
falseor custom dictionary), never override - Provide 8 kinds of line dialects (OpenAI effort / DeepSeek / OpenRouter / Together / Z.AI / Qwen / string-thinking / ant-ling), and support overriding default dialect by route
Technical Implementation
- Language: TypeScript + React 18 (browser side uses JSX/TSX), host side pure TS
- Key Dependencies:
@deepseek-ai/cordis(host context),@deepseek-ai/dsh-settings(settings segment registration),@deepseek-ai/schemastery(configuration Schema validation),react-dom/client(panel rendering) - Architecture Pattern: DSH dual-half external plugin — host side
lib/index.jslistens tollm/adapters-updated/settings/updatedevents for metadata wrapping and pi-ai line-level supply; browser sidelib/client.jsperforms click interception on the "Reasoning Level" row in model menu and renders the panel with React 18; styles are injected by lightningcss inliningeffort.module.csshash as<style data-plugin> - Entry Files:
src/index.ts(host) /src/client/index.ts(browser)
Use Cases
- Configured multiple third-party provider models in DSH, but the official level selector doesn't work or won't take effect on most models
- Accustomed to Claude Code's infinite drag panel with flame effects and want the same interaction to adjust levels in DSH
- Want reasoning_effort field to actually reach the request body under different OpenAI-compatible endpoints (different line dialects)
Prerequisites & Compatibility
| Dependency | Min Version | Description |
|---|---|---|
| DSH | Not declared | Injected into host via dsh.bundle.patch, needs to use dsh plugin --profile web installation channel; after offline local installation, restart DSH once (README.md:96-104) |
| Node | Not declared | No explicit engines field |
| Platform | Cross-platform | No OS/CPU limitations on compatibility; verification in README only noted on Windows (README.md:88-91) |
| Native modules | None | Repository declares no native dependencies |
Installation
dsh plugin --profile web add dsh-effort-slider
Configuration Options
Configuration is written to the effort-slider segment under DSH's ~/.dsh/settings.yaml and can be applied hot:
| Config | Type | Description | Default |
|---|---|---|---|
enabled | Boolean | Whether to enable the host-side generic thinking intensity supply master switch; when closed, no longer supplement metadata for third-party models | true |
defaultDialect | Enum | Line dialect used when not overridden by route, 8 options available: effort (OpenAI-style reasoning_effort) / deepseek / openrouter / together / zai / qwen / string-thinking / ant-ling | effort |
routes.<route name> | Enum | Override line dialect for single provider route, value set same as above; falls back to defaultDialect when not specified | {} |
FAQ
Q: Do I need to restart DSH after installation?
A: Yes. Host-side patch must be injected at restart; after installation, restart DeepSeek Harness once, and press Ctrl+F5 in the web page to reload the browser-side script.
Q: What if I don't see the "Reasoning Level" row in the model menu?
A: If the model itself has no reasoning metadata and the host-side metadata supply didn't take effect, the "Reasoning Level" row won't appear. First confirm DSH has been restarted, and check if effort-slider.enabled is set to true in ~/.dsh/settings.yaml; if still ineffective, check the DevTools console for [effort-slider] intercept row: ... to determine if the interception layer is working.
Q: If I only write reasoningEffort in the panel, will it change my selected model?
A: No. The panel only calls selectModel({ reasoningEffort }) to write the level, keeping the model selection unchanged; models that don't support multi-level reasoning will display "Current model does not provide multi-level reasoning levels".
Q: Can third-party models really make thinking intensity take effect?
A: Yes. The host side does two things simultaneously: injects generic 5-level metadata for adapters that haven't declared reasoning; complements line-level dictionary and compat dialect for pi-ai custom models, which takes effect hot, then pi-ai translates the levels to real online fields like reasoning_effort / thinking / OpenRouter reasoning.effort.
Q: Can I configure different line dialects for different providers?
A: Yes. Specify the dialect for that route in effort-slider.routes.<route> (such as deepseek / openrouter / qwen etc.); when not written, it falls back to defaultDialect.
Q: How do I uninstall?
A: Execute dsh plugin --profile web remove dsh-effort-slider, and if you previously manually modified cordis.patch.yml, also delete the ui-effort-slider line, then restart DSH.
Q: Does this plugin read my conversation content or make network requests?
A: No. Host side doesn't read any user files, only writes its own settings segment; browser side only interacts with the local DSH's /api RPC endpoint, never reads credentials or conversation history.
Difficulty Level
Beginner — only one installation command + one DSH restart needed; if the default 5 levels work, no configuration needed at all; only need to configure defaultDialect by route when specific OpenAI-compatible endpoint fields are incorrect.
Known Issues & Limitations
- When the current model itself doesn't provide multi-level reasoning, the panel will display "Current model does not provide multi-level reasoning levels", cannot adjust (README.md:60)
- When the host's
llmorsettingsservice is not ready, the entire supply will be turned off and logeffort-slider: llm/settings service unavailable, at which point the panel will get empty directory/fallback scale (src/index.ts:76-79) - May conflict with skin plugins that also intercept the "Reasoning Level" menu (like dsh-ui-web's aurora skin), potentially showing two panels simultaneously; need to disable its interception in the other skin to avoid conflicts (README.md:165)
pi-aisettings segment registration happens after its adapter, and the registration process doesn't triggersettings/updatedevent; host side uses up to 30 seconds of ready retry as fallback; very short cold starts before this time may need to wait a few seconds (src/index.ts:82-120)
dsh-effort-slider
A Claude Code–style reasoning-effort slider for DeepSeek Harness — click Effort in the model menu, drag without steps, snap on release, with a WebGL fire trail; any third-party model/provider gets real, working thinking-effort control.
Click the Effort row (second row of the official model menu) instead of the built-in level list: an Effort slider panel pops up — OFF/MAX scale ticks, Low/Medium/High/Ultracode status shown live, and after the panel closes the effort value stays color-coded on the menu row and on the model-seat trigger button.
Features · Compatibility · Install / Uninstall · Quick Start · Configuration · Permissions & Data · How It Works · Troubleshooting · Development
Demo screenshots (menu-row coloring / model-seat trigger / Effort panel — effort level is color-coded):
| Menu row | Model-seat trigger | Effort panel |
|---|---|---|
![]() | ![]() | ![]() |
🔧 v0.2.5 — Fixed the real landing bug in universal effort provisioning: explicit
modelsarrays are now replaced as a whole (dsh-settings path ops cannot traverse array nodes, otherwisemodelsis corrupted, the schema rejects the write, and provisioning fails silently).🔧 v0.2.4 — Fixed universal effort provisioning never landing when the pi-ai settings section registers late: provisioning now retries until the section is ready (registration happens after the adapter and does not emit
settings/updated).🆕 v0.2.3 — The model-seat trigger button (「model · effort」 above the composer) also color-codes its effort name, persistent after the menu closes.
🔧 v0.2.2 — Fixed menu-row coloring breaking on whole-tree menu remounts: painting now does a full scan and re-paints on any DOM change (throttled), and infers the color from the effort text when the panel has not reported one yet.
🆕 v0.2.1 — After the panel closes, the effort value on the model menu's Effort row keeps its level color (OFF rose-gray / Low amber / Medium blue / High purple / Ultracode bright purple with glow).
✨ v0.2.0 — Any custom third-party model/provider gets working thinking-effort control (adapter metadata provisioning + pi-ai wire-level provisioning, hot-applied).
🎛️ v0.1.0 — Initial release: intercepts the official Effort menu and shows a Claude Code–style Effort slider panel.
Features
| Feature | Description |
|---|---|
| 🎚️ Stepless dragging | Continuous 0–100 dragging that writes reasoningEffort in real time (16 ms throttle, no request pile-up while dragging) |
| 🎯 Snap on release | Snaps to the nearest level on release / blur / keyboard end, with one confirmation write |
| 🔥 WebGL fire trail | Three-pass shaders (ignite → blur → composite); the fire front follows the thumb with spring damping |
| 🏁 OFF/MAX ticks | First/last levels always show OFF / MAX; middle levels show the API-returned name |
| 🎨 Level status | Effort name shown in the panel header, colored/glowing per level; menu row and model-seat trigger keep the same color after closing (v0.2.3) |
| 🌐 Universal effort | Third-party models without reasoning metadata automatically get the universal 5-level scale; pi-ai models get wire-level dictionaries patched in, hot-applied (v0.2.0) |
Only reasoningEffort is written — model selection is untouched. Models with no multi-level reasoning show 「当前模型不提供多档推理等级」 (no multi-level reasoning available).
Universal effort provisioning (v0.2.0)
Any custom third-party model/provider gets thinking-effort control that actually works on the wire:
- Adapter metadata provisioning (host): models without
reasoningmetadata get the universal 5-level scale injected (off/low/medium/high/max→ OFF/Low/Medium/High/Ultracode), so the official model menu and this panel are selectable and request validation passes; - Wire-level provisioning (host, pi-ai): for
llm-pi-aimodels missingreasoningEfforts, the dictionary andcompatwire dialect are patched in (hot-applied, no restart); pi-ai translates the level into real wire fields (reasoning_effort/thinking/ OpenRouterreasoning.effort, etc.); - Client fallback scale: if the directory returns no reasoning metadata, the panel still opens with the universal 5-level scale;
- Existing user declarations (
reasoningEfforts: falseor a custom dictionary) are always respected and never overwritten.
Supported wire dialects for custom endpoints (set effort-slider.defaultDialect or routes.<route>):
| Dialect | Wire effect |
|---|---|
effort (default) | OpenAI-style reasoning_effort: low/medium/high/max |
deepseek | thinking:{type} toggle + reasoning_effort |
openrouter | reasoning: { effort } (OpenRouter normalized) |
together / zai | reasoning.enabled / thinking:{type} + optional effort |
qwen | enable_thinking toggle |
string-thinking / ant-ling | thinking / reasoning.effort strings |
Compatibility
| Item | Value |
|---|---|
| DSH version | Official installer, web profile (verified on Windows) |
| Install mechanism | dsh plugin --profile web add (bundle patch + dual half) |
| Depends on | client runtime / connection / sessions channels of dsh-base / dsh-web-app |
Install / Uninstall
# Install (recommended, same bundle mechanism as dsh-navbar)
dsh plugin --profile web add github:2768651338/dsh-effort-slider#main
# Build locally and install (clone this repository)
pnpm build
dsh plugin --profile web add file:./dsh-effort-slider
After installing, restart DeepSeek Harness and press Ctrl+F5 once in the web page. The
lib/artifacts are committed, so GitHub installs need no local build.
| Action | Command |
|---|---|
| Upgrade | dsh plugin --profile web update dsh-effort-slider (or re-run add), then restart DSH |
| Uninstall | dsh plugin --profile web remove dsh-effort-slider, then remove its row from cordis.patch.yml if any |
Quick Start
- Install the plugin, restart DSH, press
Ctrl+F5. - Open the model menu above the composer → click Effort → the Effort slider panel appears.
- Drag to choose a level; it snaps on release. After the panel closes, the effort value keeps its color on the menu row.
- For custom models with no thinking effort, the panel opens with the universal 5-level scale; pi-ai models get their wire dictionaries patched on the host side (hot-applied).
A [effort-slider] intercept row: ... line in DevTools Console means interception is working.
Configuration
| Item | Details |
|---|---|
| Plugin options | effort-slider settings section (written to ~/.dsh/settings.yaml, hot-applied) |
| Defaults | enabled: true, defaultDialect: effort |
| Environment variables | None of its own; follows DSH's DSH_HOME resolution |
| Sensitive items | None — no keys, tokens, or credentials are read or stored |
effort-slider:
enabled: true # provisioning master switch
defaultDialect: effort # global default wire dialect
routes:
my-gateway: deepseek # per-route override
Permissions & Data
| Scope | What it touches |
|---|---|
| Files (read) | None — no user files are read or written (settings go through DSH's settings service) |
| Network | None — the browser half only talks to the local DSH /api RPC endpoint |
| Credentials | Never read |
| User data | Not read (no access to conversation content/messages/prompts; only the current session's reasoningEffort via the sessions channel) |
How It Works
| Half | File | Role |
|---|---|---|
| Host | lib/index.js | Universal effort provisioning: adapter metadata wrapping (universalReasoning) + pi-ai wire patches (buildProvisionOps, idempotent, respects user declarations) + the effort-slider settings section; listens to llm/adapters-updated / settings/updated for hot application |
| Browser | lib/client.js | Captures clicks on the model menu's Effort row → shows the Effort panel; throttled selectModel({ reasoningEffort }) writes; a MutationObserver keeps the menu-row level color alive after the panel closes |
The browser half follows the official external-plugin convention: classic script +
window.__ModuleLoader__.loadfactory;react/react-dom/client/react/jsx-runtimeare platform externals;effort.module.cssis hashed and inlined by lightningcss, injected as<style data-plugin>when the factory runs.
Troubleshooting
| Symptom | Fix |
|---|---|
| No Effort row in the model menu | The model declares no reasoning metadata and host provisioning is not in effect — confirm DSH was restarted and check effort-slider.enabled in ~/.dsh/settings.yaml |
| Panel says 「当前模型不支持思考强度调节」 | Universal fallback not active — upgrade to v0.2.0+ and restart |
| Dragging has no effect | Check whether the target endpoint's wire dialect matches (see the dialect table) or set defaultDialect for that route |
| Conflicts with other skin plugins | If another skin that intercepts the Effort row is installed (e.g. the aurora skin of dsh-ui-web), disable its interception to avoid double panels |
| Version still shows old after restart | file: installs are snapshot copies — use the github: spec or re-run add before restarting |
| Where are the logs? | Host errors: DSH startup log; client errors: browser DevTools (F12) Console |
Project Structure
src/
index.ts host half: universal effort provisioning (adapter metadata + pi-ai wire + settings section)
effort-core.ts pure logic: dialect → wire mapping, provisioning patches (unit-tested)
client/
index.ts browser half: intercept the Effort row + panel anchor + menu-row coloring
css-modules.d.ts
effort/
EffortPanel.tsx Effort panel (levels / ticks / slider / glow)
useWebglFire.ts WebGL2 three-pass fire loop (spring follow + idle sleep)
shaders.ts vertex / ignite / blur / composite shaders
effortColors.ts level → color mapping (panel and menu row share it)
effort.module.css panel styles (inlined via lightningcss)
cordis.patch.yml bundle patch (inserts the ui-effort-slider row)
lib/ built artifacts (client.js ships with sourcemap)
test/ host.spec.mjs unit tests + host-apply.spec.mjs + client.smoke.mjs
Development
pnpm install
pnpm build # tsdown → lib/index.js (host half) + lib/client.js (browser half)
pnpm test # host unit tests + apply integration test + jsdom smoke (intercept/render/snap/fallback/coloring/teardown)
Contributing. Fork → change → pnpm build → run pnpm test → open a PR against main. Small fixes (docs, tests) are welcome without prior discussion; report issues with the DSH version and the exact error.
License & Security
License: BSD-3-Clause — see LICENSE. The UI implementation references the aurora skin of the community dsh-ui-web project (BSD-3-Clause); full upstream notices and license texts are in THIRD_PARTY_NOTICES.md.
Security: this plugin reads no credentials and sends nothing over the network (only talks to the local DSH). To report a security issue privately, use GitHub's Report a vulnerability on the Security tab — do not open a public issue with exploit details.
BSD-3-Clause © 2768651338
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/2768651338/dsh-effort-slider)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.


