DeepSeek Harness plugin

dsh-plugin-thinking-api

One-click OpenAI-compatible API (CodeBuddy/vLLM/proxies) with thinking mode, avoiding developer-role content_filter rejection.

Jump to install

Source facts

Repository
qjf44/dsh-plugin-thinking-api
Latest update
Aug 19, 2026
Category
Models & Providers
GitHub stars
0

Install

Start with a prompt that asks an agent to read the source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to read the page and repository first.

Do not install anything yet. Read this DeepSeek Harness plugin and explain what it does, which files, networks, or credentials it can access, and how to install and remove it.

Plugin page: https://deepseekplugins.org/plugins/qjf44/dsh-plugin-thinking-api
GitHub: https://github.com/qjf44/dsh-plugin-thinking-api
Plugin: dsh-plugin-thinking-api
Author: qjf44
Install command: dsh plugin --profile web add github:qjf44/dsh-plugin-thinking-api

Do not run the install command until I confirm.

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

dsh-plugin-thinking-api

<div align="center">

[简体中文](./README.zh-CN.md) · English

</div>

<p align="center"> DeepSeek Harness plugin: configure any OpenAI-compatible API in one block and get thinking mode for free — while dodging the <code>developer</code>-role rejection that breaks such APIs. </p>

<p align="center"> <img src="https://badgen.net/badge/license/MIT/blue" alt="license"> <img src="https://badgen.net/badge/node/%3E%3D20/green" alt="node"> <img src="https://badgen.net/badge/dsh/0.1.0--rc.6/purple" alt="dsh"> <img src="https://github.com/qjf44/dsh-plugin-thinking-api/actions/workflows/check.yml/badge.svg" alt="ci"> </p>

---

What it solves

Three problems in one plugin:

1. Configure any OpenAI-compatible API in one block — Tencent CodeBuddy, self-hosted vLLM, or any relay — no hand-writing reasoningEfforts, thinkingFormat, or pi-ai provider internals. 2. Thinking mode out of the box — set thinking: true on a model and it gains reasoning levels automatically. 3. Fixes the content_filter / developer-role bug — this is the subtle one.

The bug this fixes

When a model declares reasoning, pi-ai rewrites the system prompt into the OpenAI developer role unless it recognizes the endpoint as a non-standard vendor. Third-party APIs that are not on pi-ai's built-in allowlist (Tencent CodeBuddy is a prime example) therefore receive a developer message, which many endpoints hard-reject with content_filter — while the exact same request using system succeeds.

The official dsh-llm-pi-ai adapter drops the compat.supportsDeveloperRole field when it builds models, so you cannot fix this from settings.yaml alone. This plugin builds the pi-ai models itself and injects compat.supportsDeveloperRole: false directly, forcing the system role.

How it stays maintainable

The plugin reuses the official PiAiAdapter class (exported by @deepseek-ai/dsh-llm-pi-ai): its streaming, chunk translation, credential resolution, idle-timeout watchdog, and image handling all keep evolving with DSH. This plugin only owns the small "model/provider assembly" layer where the correct compat is written in.

Install

Add to your profile's package.json dependencies and bundle list:

// ~/.dsh/profiles/<profile>/package.json
{
  "dependencies": {
    "dsh-plugin-thinking-api": "github:qjf44/dsh-plugin-thinking-api"
  },
  "dsh": {
    "profile": {
      "bundles": [
        // ... your existing bundles ...
        "dsh-plugin-thinking-api"
      ]
    }
  }
}

Then reinstall and restart the Harness. The plugin's cordis.patch.yml registers itself (insert: [{ id: thinking-api }]), so no manual cordis.patch.yml edit is needed.

Configure

Add a thinking-api section to ~/.dsh/settings.yaml:

thinking-api:
  providers:
    codebuddy:                                   # route id (any unique name)
      displayName: CodeBuddy                     # optional, shown in pickers
      baseURL: https://copilot.tencent.com/v2
      apiKeyEnv: CODEBUDDY_API_KEY               # env-var reference; store via the Web Models page or export it
      thinkingFormat: deepseek                   # optional, default deepseek
      models:
        deepseek-v4-pro:
          name: DeepSeek V4 Pro
          thinking: true                         # ← enables thinking mode
        deepseek-v4-flash:
          name: DeepSeek V4 Flash
          thinking: false

Store the key (never paste raw keys into the config):

# either export it in the launching environment
export CODEBUDDY_API_KEY=ck_xxxxxxxx

# or write it through the Web UI → Models page (credentials service)

Restart, then pick your API's models from the model picker.

> 📄 Ready-to-copy configs (CodeBuddy / self-hosted vLLM / any OpenAI-compatible relay): see [examples/settings.yaml](./examples/settings.yaml).

One-click setup in the Web GUI

The plugin also registers a Settings → Thinking API panel with a single setup wizard. Open it to connect an API without touching YAML:

1. Source — pick a template (CodeBuddy / DeepSeek / OpenRouter / …) or Custom. 2. API key — paste it once. Templates ship sensible default models, so you can save immediately and start chatting. 3. Models (optional) — click Fetch models to list the endpoint's models; the wizard pre-flags reasoning models by name (and you can adjust each one with a checkbox). Or add model ids manually. 4. Save — done. The provider appears in the model picker and uses the fixed adapter (supportsDeveloperRole: false).

Existing providers can be edited (the Edit button reloads them into the wizard) or removed.

> The client half ships as a browser bundle discovered through exports["./client"]; after changing plugin source, rebuild the Web artifacts so this URL picks up the new bundle.

Configuration reference

Provider (per providers.<id>)

| Field | Type | Required | Default | Meaning | |---|---|---|---|---| | baseURL | string | ✅ | — | API endpoint base URL | | apiKeyEnv | string | — | — | Env-var name holding the API key | | displayName | string | — | route id | Name shown in pickers | | thinkingFormat | enum | — | deepseek | deepseek \| openai \| openrouter \| together \| zai \| qwen \| string-thinking | | models | dict | ✅ | — | Model id → model entry |

Model (per models.<id>)

FieldTypeRequiredDefaultMeaning
namestringmodel idDisplay name
thinkingbooleanfalseEnable reasoning levels
thinkingEffortsdictautoCustom level → wire-value mapping, e.g. { off: null, high: high, max: xhigh }
contextWindownumber262144Context window size
maxTokensnumber32768Max output tokens

When thinking: true and no thinkingEfforts is given, the plugin fills a verified DeepSeek-compatible level map (off / high / max, mapping to disabled / reasoning_effort: high / reasoning_effort: xhigh). Provide thinkingEfforts to add levels (low/medium) or override per API.

Why not llm-pi-ai?

The built-in llm-pi-ai adapter already supports custom APIs. It just cannot express supportsDeveloperRole (its compat schema omits the field and its resolver drops it), so thinking-mode models on allowlist-less APIs hit the developer-role rejection. This plugin exists purely to inject that one missing bit, while reusing everything else.

Supported DSH

Built against DSH 0.1.0-rc.6+ (@deepseek-ai/dsh-llm-pi-ai), pi-ai 0.82.1. The plugin defensively reuses PiAiAdapter's constructor shape; if a future DSH changes that internal contract, the plugin fails with a clear error rather than silently misbehaving — check the release notes before upgrading DSH.

After upgrading DSH, CodeBuddy / third-party APIs stop working? Run the compat check

The plugin depends on several internal contracts of pi-ai and DSH (provider auth shape, PiAiAdapter constructor, llm service registration methods). These are not covered by semver. So after every DSH (or pi-ai) upgrade, if models suddenly fail with Provider is not configured, content_filter, or MISSING_CREDENTIAL, run the compat check first:

# from the plugin repo (DSH workspace is auto-detected upward; pass --workspace when needed)
node scripts/check-compat.mjs --workspace ~/.workbuddy/binaries/node/workspace

It verifies, item by item: the plugin imports under the real dependencies, the PiAiAdapter constructor shape, the pi-ai provider auth shape, the llm service registration methods, and the settings/credentials helpers. All ✓ means you can keep using it; any ✗ means the plugin needs an update (each failure names the changed contract and where to fix it).

Incident log (2026-08-18, DSH rc.6 → rc.7)

After the upgrade, codebuddy requests failed 100% with PI_AI_ERROR: Provider is not configured: codebuddy. Root cause: pi-ai 0.82.1 changed the provider auth contract:

  • Before 0.82.1: auth: { name, resolve } (top-level resolve).
  • From 0.82.1: resolveProviderAuth only recognizes auth.apiKey.resolve; a top-level resolve is treated as "no auth method" → getAuth returns nothing → the error above.

Fix: buildProvider now assembles auth as { apiKey: { name, resolve } }, matching the official dsh-llm-pi-ai routeAuth/harnessApiKeyAuth shape. The plugin also self-checks this contract at startup, so a version mismatch now fails loudly at boot instead of on your first message.

Second pitfall: editing a provider in the GUI wizard with the key field left blank wiped the existing apiKeyEnv, losing the credential reference after an upgrade/reconfigure (reported as MISSING_CREDENTIAL or auth failures). Fixed: in edit mode, a blank key means "keep unchanged" and the previous apiKeyEnv is preserved.

Contributing

Bugs and reports welcome — please open an issue via the bug report template (it asks for the DSH version, plugin version, and the compat-check output, which covers 90% of failures).

Before opening a PR, run the local checks:

npm run check                 # syntax (lib/index.mjs, lib/client.js, scripts/check-compat.mjs)
node scripts/check-compat.mjs --workspace ~/.workbuddy/binaries/node/workspace   # contract check against your real DSH

CI runs npm run check plus an npm-package sanity job (tarball file list and version-bump) on every push/PR — see [.github/workflows/check.yml](.github/workflows/check.yml).

License

[MIT](./LICENSE)