DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

Finish Reason Patch — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
F

dsh-finish-reason-patch

Finish Reason Patch

Tolerate OpenAI-compatible model streams that end without a terminal finish_reason so DSH turns complete instead of aborting.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:Canson666/dsh-finish-reason-patch#c544c90c64b969e5ebdcad2e23d0e792e6542578
READMECompatibilityVersions

Compatibility and provenance

Finish Reason Patch is published as dsh-finish-reason-patch and currently resolves to version 1.1.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
8/20/2026

Versions

1.1.0stable
8/20/2026

Related plugins

Loading related plugins…

Latest
1.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 1
Weekly downloads
0
Last push
8/20/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in models-usage.

Usage@linxin666/dsh-usageUsage statistics plugin for the dsh web GUI: per-provider balance and coding-plan quota detection plus a live token usage ledger, with the current session provider's today usage on the sidebar entryWhale Widgetdsh-whale-widgetDeepSeek balance whale widget in the bottom-right corner of the DSH Web interface: balance/today’s usage/peak-off-peak pricing, customizable bubble click sequence (text/balance/today/peak-off-peak/image/random phrases and parallel weighted selection), per-line styles and fonts, floating quick editinUsage Stats@ychris12138/dsh-usage-statsToken usage heatmap, provider balances, and subscription quotas for the dsh web GUICodex Connectdsh-codex-connectChatGPT OAuth and Codex models for DeepSeek Harness.

README

dsh-finish-reason-patch

DSH plugin: stop agent turns from being aborted when an OpenAI-compatible provider (GPT-family models, gateways, proxies) ends a streaming response with full output but without a terminal finish_reason.

The bug it fixes

DSH routes OpenAI-compatible providers through @earendil-works/pi-ai. When the wire stream ends without ever seeing choices[].finish_reason, pi-ai raises Stream ended without finish_reason (openai-completions.js:438). By that point every content block is already closed and delivered — the response is complete, only the terminal marker is missing. pi-ai surfaces that as an error event, the dsh-llm-pi-ai adapter maps it to a terminal finish {kind:'error', code:'TRANSPORT'} chunk, and the agent loop (dsh-agent-loop) throws — aborting a perfectly good model turn. Other agents (e.g. Codex) tolerate the same wire behavior by treating end-of-stream as the end of the response.

The fix

The plugin hooks the llm/stream waterfall — every model call (agent turns, session-title requests, prepared calls, subagents) flows through it via LlmRuntime.streamWithRegistration. When the terminal finish is exactly that error, it is rewritten to a normal stop finish (or tool-calls if tool-call deltas were delivered), so the turn completes instead of aborting. This holds whether or not content was delivered: some OpenAI-compatible gateways stream only usage — or nothing — before ending without a finish_reason (reporting outputTokens: 0), and they are accepted as complete empty responses instead of retry-looping (Codex-style tolerance). All other error finishes (transport resets, rate limits, HTTP errors, ...) pass through untouched, so the existing retry policy still applies to genuinely broken responses.

When it fires you'll see: [finish-reason-patch] provider finished without finish_reason -> mapped to "stop"

Installation

The plugin is a plain Cordis host plugin (exports name / apply, no external dependencies beyond the ctx Cordis passes in).

1. As a persistent profile bundle (recommended, survives restarts)

Ship this folder as a package named dsh-finish-reason-patch:

  1. Place the package where your DSH profile can resolve it, e.g. a junction or symlink inside <profile root>/node_modules/dsh-finish-reason-patch pointing at this folder (same pattern as other local DSH plugins).
  2. In the profile root package.json, add the package to dsh.profile.bundles and to dependencies (e.g. "dsh-finish-reason-patch": "link:<absolute path to this folder>").
  3. Restart DSH — bundle patches compose at boot. The package's own cordis.patch.yml inserts the plugin row automatically.

2. As a dynamic Cordis plugin (current process only)

Define/run the plugin host body (plugin.mjs) through the Cordis dynamic plugin tools. It stays active until the process exits; re-run after a restart. Effects are identical and idempotent if both routes are active.

Verifying

  • Logic self-test (no network): node selftest.mjs — all 5 cases pass.
  • Live: run a normal conversation with a GPT-class model. Turns that used to abort now complete, and the log line above appears.

Removal

Remove the bundle entry + dependency from the profile package.json, delete the node_modules junction, restart DSH. No changes are made to any shipped DSH file.

Files

  • plugin.mjs — the plugin (llm/stream waterfall hook + rewrite logic)
  • cordis.patch.yml — bundle patch layer (the profile-tree insert row)
  • package.json — npm metadata (dsh.runtime: host, dsh.bundle.patch)
  • selftest.mjs — local logic self-test
  • LICENSE — MIT