Introduction

DeepSeek Harness (dsh) natively supports request headers by provider, but this field can only be edited in settings.yaml, with no entry on the model settings page. This plugin uses dsh’s plugin mechanism to add a request header editor to the model settings page and additionally implements per-session expansion of ${sessionId}.

What It Is

This is a plugin that adds a “custom request headers” editor to the model settings page of DeepSeek Harness (dsh). It is maintained by user duanyunlun and uses the plugin mechanism to add or remove request headers for each pi-ai provider card without modifying source code. It also replaces ${sessionId} with the current session ID.

Installation

Before installing, ensure that your system has Node.js ^22.19.0 || >=24.0.0 and pnpm installed.

# 从 npm 安装(已发布)
dsh plugin --profile desktop add dsh-provider-headers

# 从本地目录安装
dsh plugin --profile desktop add /path/to/dsh-provider-headers

# 从本地打包文件安装
dsh plugin --profile desktop add ./dsh-provider-headers-0.1.0.tgz

After installation, restart the corresponding profile to load the browser-side code. To uninstall, run:

dsh plugin --profile desktop remove dsh-provider-headers

Usage

  1. Open Settings → Models.
  2. Expand any pi-ai provider card (official DeepSeek, built-in third-party, or a custom provider).
  3. The card will show “Custom Request Headers (N)”. Expand it and fill in each row by Name / Value.
  4. Click Save, and the configuration will be written to Harness’s native settings.yaml.

Typical Example

Taking OpenCode Go as an example, this service requires all inference requests to carry x-opencode-session. Add one row in the corresponding card:

Name Value
x-opencode-session ${sessionId}

After saving, every streaming request will include the ID associated with that session. If session expansion is not needed, simply fill in a fixed value.

How It Works

Native Harness configuration cannot implement per-session expansion of ${sessionId} because all sessions under the same route share one value. The plugin implements this through the following mechanism:

  1. Listens to the llm/stream waterfall and places a streaming call inside an AsyncLocalStorage scope that carries the session ID.
  2. Wraps globalThis.fetch during the plugin lifecycle; only requests inside that scope have the expanded request headers attached.

Fixed-value request headers still go through Harness’s native logic and are unaffected.

Configuration

The plugin supports the following configuration in settings.yaml:

- id: model-headers
  config:
    dynamic: true      # 默认 true,设为 false 则不安装 fetch 包装与监听器
    hosts: []          # 默认空,填写则按主机后缀收窄生效范围

Notes

  1. Only pi-ai routes are covered: The Config for the llm-deepseek route has no headers field, so that card will not show this editor.
  2. user-agent cannot be overridden: It is an attribution identifier for Harness, and the plugin cannot modify it.
  3. ${sessionId} only works for streaming: The “get available models” request does not go through llm/stream, so the literal value is still sent there.
  4. Plaintext storage: Request header values are stored in plaintext in settings.yaml. Do not put API keys in request headers; use Harness credential fields instead.
  5. Editor location: It is rendered inside the card rather than a separate “Edit” form because this is the only extension slot on the model settings page.

Conclusion

This plugin fills the gap of the missing request header UI entry on the DSH model settings page and solves the problem that native configuration cannot change dynamically across sessions. It is implemented through the standard plugin mechanism and can be fully restored after uninstallation. For more details, refer to the plugin directory or source repository.