# DSH Custom Provider Settings Plugin [中文](README.md) | English A plugin for the web and desktop editions of [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) that adds global model request headers and extends user-defined custom providers with per-provider headers, image-input declarations, reasoning-level settings, and native system-role compatibility controls. It loads through the DSH plugin system and does not modify Harness source files. The current version is **0.10.0**, updated for the settings API, UI components, and desktop transport in Harness **0.2.2-rc.1**. Install it into the `web` profile for the browser UI or the `desktop` profile for the desktop application. [v0.10.0 release notes](https://github.com/supersealwqas/dsh-custom-provider-settings/releases/tag/v0.10.0) · [Download the 0.10.0 TGZ package](https://github.com/supersealwqas/dsh-custom-provider-settings/releases/download/v0.10.0/dsh-custom-provider-settings-0.10.0.tgz) > Global request headers apply to every channel and model, including official DeepSeek, built-in third-party, and custom providers. Per-provider headers, model capabilities, and compatibility controls remain limited to providers carrying the Custom tag. ## Features - Configure `User-Agent` and additional HTTP request headers for each custom provider. - Configure global `User-Agent` and additional headers in the web or desktop UI for every model request. - Fill either global or per-provider `User-Agent` fields from common presets while retaining free-form input. - Apply the same custom headers to normal model requests and Fetch available models. - Declare each custom model as text-only or text-and-image capable. - Configure the reasoning levels exposed for each model and map every level to the value sent to its API. - Set a provider-level default reasoning level. - Configure the reasoning parameter format for `openai-completions` providers. - Manage DSH's native `compat.supportsDeveloperRole` switch for each compatible custom OpenAI provider whose endpoint rejects `developer` messages. - Restore the original Harness request-header behavior by clearing the global headers. ## Demo ### Custom provider settings The plugin inserts request-header and model-capability fields into the existing custom-provider form. These screenshots illustrate an earlier version; newer Harness versions use updated buttons and layouts. The highlighted areas show `User-Agent`, additional headers, image input, the default reasoning level, and per-model reasoning mappings. ![Custom provider request headers, image input, and reasoning settings](assets/img01.png) ### Reasoning selector Enabled reasoning levels appear in the conversation composer. The example exposes Default, Off, Low, Medium, High, Xhigh, and Max, with Xhigh selected. ![Reasoning-level selector in the DeepSeek Harness conversation composer](assets/img02.png) ## Installation ### Prerequisites - DeepSeek Harness `0.2.2-rc.1`. Use the official CLI for the web edition and the CLI shipped with the matching desktop application for desktop. - Packaging from source or using the standalone CLI requires Node.js `^22.19.0` or `>=24.0.0`; Node.js 24 LTS is recommended. - The standalone `dsh plugin` command uses pnpm to manage profile plugins. For desktop, use the bundled CLI described below. Check the environment in PowerShell: ```powershell node --version npx --version corepack enable pnpm --version ``` If `corepack enable` fails because of insufficient permissions, run it once from an administrator PowerShell or follow the [pnpm installation guide](https://pnpm.io/installation). Stop the corresponding web service or desktop application before installing, upgrading, or removing the plugin, then restart it when the command completes. ### Download the 0.10.0 package (recommended) Download `dsh-custom-provider-settings-0.10.0.tgz` from the [v0.10.0 release](https://github.com/supersealwqas/dsh-custom-provider-settings/releases/tag/v0.10.0), or save it into a `dist` folder under the current directory with PowerShell: ```powershell New-Item -ItemType Directory -Force .\dist | Out-Null Invoke-WebRequest -Uri 'https://github.com/supersealwqas/dsh-custom-provider-settings/releases/download/v0.10.0/dsh-custom-provider-settings-0.10.0.tgz' -OutFile .\dist\dsh-custom-provider-settings-0.10.0.tgz ``` Both installation commands below use this file. For a manual download, place the package in `dist` or replace the command's path with its actual location. ### Build from source (optional) Alternatively, run these commands in the repository to package the current source: ```powershell npm install npm test New-Item -ItemType Directory -Force .\dist | Out-Null npm pack --pack-destination .\dist ``` Skip this step if you downloaded the release package. ### Install into the web edition ```powershell npx --yes -p @deepseek-ai/dsh@0.2.2-rc.1 dsh plugin --profile web add .\dist\dsh-custom-provider-settings-0.10.0.tgz npx --yes -p @deepseek-ai/dsh@0.2.2-rc.1 dsh web ``` The WebUI listens on `127.0.0.1:3080` by default; open the URL printed at startup. If your global `dsh --version` already reports `0.2.2-rc.1`, the shorter `dsh plugin ...` and `dsh web` forms are equivalent. ### Install into Windows desktop Use `resources\runtime\cli\bin\dsh.cmd` under the desktop installation directory. This example uses `D:\App\DeepSeek Harness`; replace it with your actual installation directory: ```powershell $desktopCli = 'D:\App\DeepSeek Harness\resources\runtime\cli\bin\dsh.cmd' & $desktopCli --version & $desktopCli plugin --profile desktop add (Resolve-Path .\dist\dsh-custom-provider-settings-0.10.0.tgz).Path ``` Reopen DeepSeek Harness from its desktop shortcut afterward. The ordinary npm CLI does not manage the `desktop` profile; use the bundled CLI for these commands. The two profiles manage plugins and configuration independently. Installing into the web profile does not install into desktop, or vice versa. If you use a custom `DSH_HOME`, the CLI command and its corresponding application must use the same directory. The `dist` directory and TGZ files are ignored by `.gitignore` and are not committed with the source. ### Upgrade Stop the corresponding application and run that profile's `add` command again with the updated TGZ. DSH updates the installed plugin without requiring a separate removal. After rebuilding the source, reinstall the new package before restarting the application. When repacking the same version for testing, give the TGZ a new filename (for example, append its content hash) before running `add`; otherwise pnpm may reuse its cached package from the same path. ### Uninstall ```powershell # Web npx --yes -p @deepseek-ai/dsh@0.2.2-rc.1 dsh plugin --profile web remove dsh-custom-provider-settings # Desktop, using $desktopCli from above & $desktopCli plugin --profile desktop remove dsh-custom-provider-settings ``` Restart the corresponding application to remove the plugin controls and global request-header overrides. Image input, reasoning levels, and `compat` fields are native Harness provider settings and can still be managed in the Models settings. ## Usage 1. Open Settings > Models. 2. In the Global model request headers area at the top of the model list, enter a `User-Agent` or other headers. Leave it empty to keep Harness defaults. 3. If needed, edit a provider carrying the Custom tag that already contains a model, or choose Add model provider > Custom model API and enter its models. 4. In the inserted per-provider Request headers area, configure headers for that custom provider; matching local values take precedence over global values. 5. For a compatible custom OpenAI provider, enable `Send system prompts with the system role` when its endpoint rejects the `developer` role. An existing native `supportsDeveloperRole: false` setting appears as an already-checked box. 6. Under Model capabilities, choose each model's input and reasoning capabilities. Select Text and images only when both the API and model support image input. 7. Use the original Apply or Create provider button. The plugin saves its fields after the Harness form succeeds. 8. Start a new conversation and select the model; global headers are applied automatically. Fetch available models uses the request-header values currently entered in the same form, including values that have not been saved yet. This allows model discovery to work with endpoints that require a particular `User-Agent` or another custom header. Clearing unsaved per-provider headers before fetching models removes the previously saved extra headers while preserving Harness defaults and credentials. Desktop discovery uses the application's native transport and does not require an additional web service. Global headers are also applied to model discovery. The merge order is Harness defaults, global headers, then custom-provider headers, so matching local values have the highest priority. Both global and per-provider `User-Agent` fields include these presets: - `claude-cli/2.1.161 (external, cli)` - `claude-cli/2.1.161` - `claude-code/1.0.0` - `claude-code/0.1.0` - `Kilo-Code/1.0` Selecting a preset replaces the current text field value. The field remains editable, so any other `User-Agent` can be entered manually. ## Verify image input 1. Set the model's input capability to Text and images and save the provider. 2. Start a new conversation with that model. 3. Upload a PNG or JPEG containing a unique string such as `VISION-7392`. 4. Ask the model to return only the string visible in the image. A correct response confirms that Harness accepted the attachment and the endpoint processed it. This setting declares model capability to Harness; it cannot add vision support to an API or model that does not already provide it. ## System-role compatibility The checkbox is a WebUI layer over DSH's native pi-ai compatibility setting. The plugin does not intercept or rewrite the JSON request body. - Checked: writes `compat.supportsDeveloperRole: false` for the current custom provider. - Unchecked: removes only `supportsDeveloperRole`, restoring DSH/pi-ai automatic detection. - Scope: applies to every model under that provider, without changing other providers. - Preservation: leaves neighboring fields such as `thinkingFormat` and `supportsReasoningEffort` unchanged. The control appears only for custom OpenAI protocols whose native pi-ai compatibility type supports this field. ## Stored settings Newer Harness versions store editable configuration in each profile's `cordis.patch.yml`. The default Windows locations are: - Web: `%USERPROFILE%\.dsh\profiles\web\cordis.patch.yml` - Desktop: `%USERPROFILE%\.dsh\profiles\desktop\cordis.patch.yml` With a custom `DSH_HOME`, use `profiles\\cordis.patch.yml` below that directory. Open configuration file in Settings opens the file used by the current application. The configuration structure is: ```yaml - id: dsh-custom-provider-settings name: dsh-custom-provider-settings config: globalHeaders: User-Agent: my-global-client/1.0 X-Client-Name: all-models - id: llm-pi-ai name: '@deepseek-ai/dsh-llm-pi-ai' config: providers: relay: headers: User-Agent: my-client/1.0 X-Client-Name: my-client reasoning: high compat: thinkingFormat: deepseek supportsDeveloperRole: false models: - id: example-model input: [text, image] reasoningEfforts: low: low medium: medium high: high ``` Header values are stored as ordinary text in the profile configuration. Keep API keys and other secrets in the Harness credential field instead of custom headers. Harness handles migration from the old `settings.yaml`; that file is no longer the active configuration store in current versions. Clearing the global headers removes the global override and restores the original Harness request-header behavior. Clearing a provider's headers only removes that provider's extra override. ## Troubleshooting ### Startup fails with `Cannot read properties of undefined (reading 'llm')` Upgrade Harness to the tested `0.2.2-rc.1`, install plugin `0.10.0` using the steps above, and restart the corresponding application. This error was reported with plugin `0.5.0` on a newer Harness version. Version `0.10.0` prefers the current Remote interface and handles a missing legacy `connection.api`; changing model JSON or deleting configuration is unnecessary. The complete older environment described in the report has not been reproduced. See [Related issue #1](https://github.com/supersealwqas/dsh-custom-provider-settings/issues/1). ### The plugin settings do not appear Confirm that the web edition uses the `web` profile and the desktop edition uses `desktop`, then restart the corresponding application. The global header area appears at the top of the Models list; a custom provider without models has no editable model-capability settings. Plugin 0.9.0 has component and settings API incompatibilities with newer Harness versions; install 0.10.0. ### Fetch available models still fails Confirm the Base URL, API key, and API protocol first, then check every `User-Agent` or additional header required by the endpoint. The plugin includes unsaved header values from the active form in the discovery request. ### Reasoning levels or image upload are missing in a conversation Save the provider, start a new conversation, and select the model again. Reasoning levels must be enabled for that model, and image upload requires the model to be declared as Text and images. ### A third-party DeepSeek endpoint rejects the developer role Edit the compatible custom OpenAI provider, enable `Send system prompts with the system role`, save it, and start a new conversation. The setting is scoped to that provider; the official DeepSeek provider and other custom providers keep their existing request roles. ### The endpoint works, but the checkbox looks unchecked Open the provider editor after restarting the application. The checkbox reads the effective native `llm-pi-ai.providers..compat.supportsDeveloperRole` value. If the profile configuration already contains `false` but the UI remains unchecked, force-refresh the browser page or fully exit and reopen the desktop application to load the current plugin version. ## Verification results Version 0.10.0 completed the following checks on 2026-11-04. Harness `0.2.2-rc.1` was used except for the older-version regression checks. Each group covers a different scope: | Test group | Result | Scope | | --- | --- | --- | | Automated tests | 30 passed | Client saves, settings API, model discovery, request headers, and package configuration | | Real Harness request pipeline + local mock API | 20 passed | Headers across provider channels, system role, image bytes, 7 reasoning levels, and 8 wire formats | | Real web UI + local mock API | 19 passed | Chinese/English UI, save/clear, draft model discovery, native field preservation, model reorder/delete, and reload persistence | | Windows desktop core UI | 10 passed | Form rendering, model discovery, header/system settings save/reopen/clear, original configuration preservation, and test-provider removal | | Harness `0.2.1-rc.5` backend regression | 9 passed in each of 2 configurations | Original Schemastery 3.18.5 and plugin-local 3.19.0; loading, native Config, RPC without HTTP, and request headers | | Live API through the web UI | 15 passed | Live model discovery, text and image conversations, the High request parameter, header save/clear, and configuration/conversation reload | | Direct live API checks | Model listing + 3 inference calls passed | Streaming text, High reasoning content, and synthetic-image recognition | The live web and direct API checks used `gemini-3.5-flash-lite`. The web image request recorded `reasoningEffort=high` and identified the shapes correctly, but that response contained no reasoning block; the separate direct API reasoning test returned `reasoning_content`. Desktop verification covers the core settings flows listed above, without live model inference or a complete feature review. ## Compatibility and limitations - The adaptation and live-testing baseline for 0.10.0 is DeepSeek Harness `0.2.2-rc.1` on the web and Windows desktop editions. - Older-version regression checks cover backend compatibility, not the full UI of the older desktop application. - Mock API checks verify transmitted parameters and data. Live API checks cover the tested endpoint and model capabilities, without establishing support in every third-party model. - Global headers are injected into every model channel; custom-provider image, reasoning, compatibility, and per-provider header controls mount only on providers reported by Harness with `declared: true`. - The plugin does not modify official or built-in provider model configuration, although global headers still apply to their API requests. - Model names, context windows, maximum output values, and other fields owned by the original form are preserved when plugin settings are saved. - This plugin locates the original accessible labels and mounts its React controls at runtime, so a future Harness form change may require a plugin update. - The plugin does not patch DeepSeek Harness source files. ## Development and verification ```powershell npm test node --check client.js npm pack --dry-run ``` ## Attribution The reasoning-settings client logic is adapted from [JuneLearn/dsh-reasoning-settings](https://github.com/JuneLearn/dsh-reasoning-settings) under the MIT License. ## License MIT. See [LICENSE](LICENSE). The license retains the copyright notices for this repository and its adapted upstream source.