dsh-thinking-effort
A DSH (DeepSeek Harness) plugin that adds configurable reasoning effort levels to hand-declared llm-pi-ai models and sets a default reasoning effort for subagents.
- 中文 README
- 日本語 README
- 한국어 README
- Installation guide
- 中文安装指南
- 日本語インストールガイド
- 한국어 설치 안내
- Changelog
- 日本語 changelog
- 한국어 changelog
Compatibility boundaries: DSH Runtime compatibility covers the Settings transport only: modern DSH exposes
remote.settings, while legacy DSH exposesconnection.api.settings. The plugin detects the available runtime capability and keeps the legacy fallback optional, so the settings page does not require a Remote provider on older DSH builds.Gateway Protocol compatibility is a separate layer. When the DSH schema exposes them, the plugin supports 15 common scalar
llm-pi-ai.compatfields, grouped into role/reasoning, format/output, streaming/tools, and storage/cache. Boolean fields offerAuto, supported, and unsupported; enum fields offerAutoand their concrete values. DSH0.1.0-rc.7does not provide gateway compat settings. DSH0.1.0-rc.8through<0.1.2-alpha.1provide the other fields, but notsupportsFinishReasonorsupportsThinkingTokenBudget; DSH0.1.2-alpha.1and later expose all 15 when supported by the schema. The optionaldsh-llm-openai-completionstransport can take over eligible custom OpenAI-compatible thinking providers when it is installed and enabled.Autounsets the current-layer override and restores the next value in the inheritance chain.DSH
0.1.2-alpha.1and later accept language-pack locale IDs throughLocaleRuntime. This plugin registersjaandkodynamically, so no DSH core fork is required. Older DSH builds that only expose built-in locale IDs supportzhandenonly.The published runtime entries are
lib/index.js(Host) andlib/client.js(Client). After changing TypeScript or locale sources, runnpm run buildbefore running DSH or packing the plugin. Current DSH does not expose a public semver metadata contract, so runtime capability detection is authoritative. An optional version is used only when explicit metadata or test input supplies it; unknown valid versions still use the detected capabilities. The plugin supports both modernremote.settingsand legacyconnection.api.settings.The Host registers its
dsh-thinking-effortSettings namespace through the host-provided SettingsinstallSectionwhen available, and falls back to the legacyregisterpath otherwise. It does not depend on@deepseek-ai/dsh-settingsat runtime, so the package installs cleanly into DSH profiles configured withautoInstallPeers: falsewithout introducing a second Cordis runtime.
DSH compatibility
| DSH range | Gateway compatibility settings |
|---|---|
0.1.0-rc.7 |
Not available |
0.1.0-rc.8 to <0.1.2-alpha.1 |
Available when exposed by the DSH schema, but without supportsFinishReason and supportsThinkingTokenBudget |
0.1.2-alpha.1 to <0.1.6-0 |
All 15 fields when exposed by the DSH schema. Releases at or beyond the newest bound are unmapped: the plugin keeps working and follows the capabilities the running host reports instead |
From DSH 0.1.0-rc.8 onward, field availability follows the runtime schema. The table shows the maximum field set for each DSH version; the route protocol can further reduce it.
A gateway compat field can be configured only when the DSH version, runtime schema, and route's api protocol all support it. Unsupported fields stay hidden and are not written to Settings. Among these 15 fields, openai-completions supports all 15, while openai-responses, azure-openai-responses, and openai-codex-responses support only supportsDeveloperRole, supportsStrictMode, and supportsLongCacheRetention. If api is missing or unrecognized, the runtime schema and DSH validation remain the final authority.
Why use it?
The llm-pi-ai adapter supports hand-declared third-party models, but those entries often do not declare reasoningEfforts. As a result, Composer does not show a reasoning effort selector, and gateway-specific values such as ultra cannot be mapped to DSH's standard levels.
This plugin provides the configuration layer needed to:
- Add default
off,high, andmaxoptions to models without a declaration; - Configure reasoning levels per model from the DSH settings page;
- Map a DSH level such as
highto a gateway value such asultra; - Set a default reasoning effort for subagents while preserving explicit request values;
- Keep existing user-defined model declarations unchanged.
The plugin is usually unnecessary when you only use built-in DSH models and their reasoning controls already work.
Identifiers
These identifiers have different responsibilities:
| Identifier | Purpose |
|---|---|
@hytime/dsh-thinking-effort |
npm package, browser bundle path, loader ID, and host/client runtime ID |
thinking-effort |
Cordis composition entry ID and settings Slot ID |
Features
| Feature | Description |
|---|---|
| Default levels | Adds off, high, and max without overwriting custom values |
| Per-model editor | Select levels and configure gateway values for both catalog/modelOverrides and models[] entries in Settings |
| Gateway compatibility | Configure 15 common scalar fields globally per provider or separately per model, grouped by role/reasoning, format/output, streaming/tools, and storage/cache; groups are collapsed by default |
| OpenCode session Header | Enable a dynamic x-opencode-session per exact model, using the current DSH session ID without storing a fixed Header value |
| Gateway mapping | Send ultra when the user selects DSH high |
| Composer effort slider | Registers an optional Composer seat when the Web runtime exposes modelDirectories, with host-resolved tiers for the current provider/model |
| Subagent default | Apply a default effort only when a subagent request has no explicit value |
| Multilingual settings | Includes Chinese, English, Japanese, and Korean dictionaries; Japanese/Korean switching uses DSH language-pack support |
| Version watermark | Show the installed plugin version in the bottom-right corner |
Install, upgrade, and remove
Use the official DSH CLI to manage the plugin profile. A plain npm install does not register a DSH profile bundle.
# Install the latest version
dsh plugin --profile <profile> add @hytime/dsh-thinking-effort
# Install a specific version
dsh plugin --profile <profile> add @hytime/dsh-thinking-effort@0.2.4
# Upgrade
dsh plugin --profile <profile> update @hytime/dsh-thinking-effort
# Remove
dsh plugin --profile <profile> remove @hytime/dsh-thinking-effort
rm -f "${DSH_HOME:-$HOME/.dsh}/thinking-effort-loaded.json"
See INSTALL.md for profile discovery, migration, validation, and troubleshooting.
Quick use
Open DSH Settings → Model capabilities and effort.
Use the Page language selector at the top to choose
中文,English,日本語, or한국어. DSH uses the persisted locale first, then the browser language, then English as the fallback.Choose a subagent default from the Subagent default effort card, then click Apply.
Use Quick settings to apply the official DeepSeek or generic preset to all models, or expand a provider and model for detailed configuration.
Use the search field to filter models by name or ID. Model rows show text/image input capability badges, a context-window badge when declared, and a settings button for per-model editing.
Select a reasoning level and enter the exact gateway value. For example:
DSH level Gateway value offLeave empty to omit the parameter highultramaxmaxIn the model editor, optionally enable OpenCode session Header for the exact model that needs
x-opencode-session. It is off by default, uses the current DSH session ID dynamically, does not inherit across models or providers, and saves immediately when toggled — there is no separate save button.Return to Composer, choose the configured model, then use its reasoning-effort slider.
Composer reasoning-effort slider
When the DSH Web runtime exposes modelDirectories, the client registers an optional conversation.input.model seat with a low shadow priority; it does not modify Composer itself. The slider reads the host-resolved reasoning.efforts array for the current exact provider/model, so it shows only the tiers currently effective for that model. Changing a level submits the ordinary session model selection; it does not mutate the plugin Settings document.
The model's defaultEffort is shown through the matching tier. If the host model has no defaultEffort, the panel also provides Follow model default, which submits a selection without a reasoning-effort override. The control uses the host --dsw-* semantic tokens and therefore follows the active light or dark theme without its own theme preference.
The seat is not registered when the runtime does not provide modelDirectories; the Settings page and its legacy Settings transport behavior continue to work. This plugin does not modify the DSH Composer, ui-conversation, or ui-model-selection packages.
The settings page shows the installed version as a small watermark such as v0.1.14 in the bottom-right corner.
Gateway compatibility configuration
The provider compat block is the global default for every model under that provider. The Settings page groups the 15 fields into four sections that are collapsed by default. Configure provider defaults with the official DSH YAML shape:
providers:
qwen-gateway:
compat:
supportsDeveloperRole: false
maxTokensField: max_tokens
models:
- id: qwen-plus
- id: qwen-thinking
compat:
maxTokensField: max_completion_tokens
Field-by-field, each value resolves independently in this order: model → provider → base/catalog → protocol. URL/hostname detection is not used as a compat source. A model value overrides only that field. Auto removes the current-layer value, restores provider inheritance when applicable, and lets the next value in the chain take effect. Provider defaults apply to every model on the route; a model edit changes only the current model. For a route/provider, non-empty models[] and non-empty modelOverrides are mutually exclusive; the official schema rejects this invalid configuration, and the plugin fails closed for malformed data.
The provider area in Settings edits defaults for all models. Both catalog models and custom YAML models[] entries expose a single-model compat editor: catalog models write only the target fields with field-level set/unset operations under modelOverrides.<model>.compat, while models[] models write one complete providers.<route>.models array set while preserving other entries and fields. A model edit does not change other models.
These compat values are control plane configuration. They do not implement or replace the gateway transport; an external transport remains responsible for network requests.
OpenCode session Header compatibility
The model editor has a separate OpenCode session Header switch. It is off by default and is stored in the plugin's own dsh-thinking-effort Settings namespace, not in llm-pi-ai.compat. Enable it only for the exact provider/model that requires x-opencode-session; another model on the same route, including a GPT model, does not inherit it. Flipping the switch saves immediately — there is no separate save button — and reopening the model shows the persisted value.
When enabled, the Host sends x-opencode-session: <current DSH session ID> on matching llm/stream requests. The value follows the current conversation and is not stored in Settings or replaced with a fixed value. An existing x-opencode-session supplied by the adapter or caller is preserved. The setting does not choose or change openai-completions, openai-responses, or anthropic-messages.
Sub2API, CPA, and other forwarding gateways must preserve and forward x-opencode-session to the OpenCode upstream. A static route setting such as llm-pi-ai.providers.<route>.headers.x-opencode-session is not an equivalent replacement: it uses one value for every conversation and cannot provide per-conversation routing or prompt-cache affinity. Restart DSH after Host changes and refresh the Web page after Settings or Client changes.
Settings page layout
The page header contains the language selector. Below it, the Subagent default effort card controls the default for requests without an explicit effort. The Quick settings controls apply a preset across models. Provider sections can be expanded or collapsed; each model row exposes input capabilities, context length, and gateway compatibility controls in its settings area. models[] saves use one complete array set rather than an array-index path operation.

See the complete Chinese, English, Japanese, and Korean screenshot gallery in docs/SCREENSHOTS.md.
How it works
- Host: Scans
llm-pi-aimodelsandmodelOverrideson startup and settings changes, adding defaults only wherereasoningEffortsis missing. It also observes the model-level OpenCode session setting and injects the current DSH session ID only into matchingllm/streamrequests. - Client: Registers the Settings page through the DSH Settings Remote (
ctx.remote.settings) and, when the runtime exposesmodelDirectories, registers the optional Composerseatwith a lowshadowpriority and host-resolved effort slider. The model editor stores OpenCode session Header settings in the plugin namespace, separately fromllm-pi-ai.compat. Chinese, English, Japanese, and Korean dictionaries are maintained separately insrc/locales/zh.json,src/locales/en.json,src/locales/ja.json, andsrc/locales/ko.json, then generated into the client bundle before publishing. - Subagents: Stores the default in the
llm-pi-aiuser layer assubagentEffort. Theagent/requestwaterfall only fills requests that do not already specify an effort. - No configured default: The plugin does not automatically choose
off,high, ormax; the request omitsreasoningand the gateway decides its own default behavior.
Limitations
llm-pi-aiexposes seven standard levels:off,minimal,low,medium,high,xhigh, andmax.- Non-
offlevels require a gateway value. An emptyoffvalue means that the parameter is omitted. - The selected subagent level must be supported by the target model, or the gateway may return
UNSUPPORTED_REASONING_EFFORT. offand an unset effort may both omitreasoning; whether this disables thinking depends on the gateway protocol.- The Composer slider is available only when the Web runtime provides the optional
modelDirectoriesservice. Theseatis not registered when that service is unavailable, and the plugin leaves Composer unchanged. - Host changes require a DSH restart. Settings, locale, and Client bundle changes take effect after a Web page refresh.
CI and release maintenance
- Pull requests and pushes to
mainrun the quality matrix on Node22.19.0and24.x. - The workflow uses
npm ci; maintainers must commitpackage-lock.jsonwhen dependencies change. - The ordinary CI workflow does not publish to npm. Publishing is triggered only by a
v<version>tag throughpublish.yml. - Before creating a release tag, update
package.jsonversion andCHANGELOG.mdfiles, commit those changes, and create the matchingv<version>tag. The tag must point to a commit in themainhistory. - npm Trusted Publishing must be configured for repository
hytime/dsh-thinking-effortand workflowpublish.yml. The workflow publishes provenance through GitHub OIDC and does not requireNPM_TOKEN. - Before publishing, the workflow builds and tests four official DSH capability representatives in this order:
dsh-v0.1.0-rc.7(0.1.0-rc.7),dsh-v0.1.1-rc.2(0.1.1-rc.2),dsh-v0.1.3-alpha.2(0.1.3-alpha.2), anddsh-v0.1.5-rc.2(0.1.5-rc.2), using the officialdsh plugincommand and real compatibility checks. The newest representative runs the real-browser DOM probe. - The workflow never changes the package version or any
CHANGELOGfile automatically; an existing npm version also blocks publishing.
No comments yet. Be the first to write one.