针对 NInfer 托管的 qwen3.8-27b 网关的压缩修复:在 dsh 上下文压缩与会话标题调用中关闭思考,避免 xhigh 推理耗尽全部输出预算;同一思路适用于其他启动方式,本包仅面向 NInfer。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-qwen38-ninfer-compaction-fix
# Release 预构建包
dsh plugin --profile web add "https://github.com/zhubaohi/dsh-qwen38-compaction-fix/releases/download/v1.1.0/dsh-qwen38-ninfer-compaction-fix-1.1.0.tgz"
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:zhubaohi/dsh-qwen38-compaction-fix
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
该插件的 README 只有英文版本。
Fix for a local qwen3.8-27b gateway running on the NInfer engine that fails to compact. The model thinks at xhigh, spends the entire output token budget on reasoning before reaching a conclusion, and the compaction checkpoint comes back truncated. This DeepSeek Harness (dsh) plugin disables thinking for compaction calls only and applies, to those calls, the sampling parameters the model recommends when thinking is off.
Scope: NInfer only. This package is written for gateways served by the NInfer engine (
ninfer-serve, OpenAI-compatible API): the wire fields it rewrites (reasoning_effort,presence_penalty,repetition_penalty,min_p) are the ones the NInfer gateway interprets. If your qwen3.8 is launched by something else (llama.cpp, vLLM, FastMTP, ...), the same idea — turn thinking off for dsh's compaction and session-title calls soxhighreasoning cannot burn the entire output budget — still applies, but each engine speaks different wire parameters, so this package does not claim to fix those launch methods.
Install
dsh plugin --profile web add dsh-qwen38-ninfer-compaction-fix
Then restart dsh web (or refresh the GUI page). The plugin is also listed in the DSH
plugin market (Settings → Plugin Market → search "qwen38").
The symptom
When context pressure builds, dsh compacts the conversation into a checkpoint. With a local qwen3.8-27b running at its default reasoning level, compaction sometimes fails, and the session is left with exactly this line:
summarization truncated at the token cap (incomplete checkpoint)
That is dsh-compaction-basic's verdict that the summarizer hit its output token cap without finishing. The conversation is condensed only into the truncated text: everything the summary never reached is effectively lost from context.
Why it happens
Local qwen3.8-27b deployments think at their default effort: xhigh in a typical route config, on every call that does not explicitly set a reasoning effort. Compaction is one such call. The model is asked to write a long summary of the whole conversation. At xhigh, it spends the entire max_tokens output budget on reasoning tokens before ever writing a word of the summary. The response hits the cap with no conclusion, and you get the truncated checkpoint above.
The fix
- Disable thinking for compaction only. Stamps
reasoning_effort: "off"onto the compaction call (waterfall layer, resolved through the model'sreasoningEffortsdeclaration to the wire valuereasoning_effort: "none"): zero reasoning tokens, and the whole output budget is available for the summary. Every other call, whether a normal turn, a subagent, or a request for any other model, keeps the route'sxhigh. Thinking is never disabled globally. - Apply the sampling parameters recommended when thinking is off. qwen3.8-27b publishes different recommended sampling parameters for thinking mode and for the mode with thinking disabled. The plugin writes the second set (
temperature: 0.7, top_p: 0.8, top_k: 20, min_p: 0.0, presence_penalty: 1.5, repetition_penalty: 1.0) into the compaction request body, so the request actually matches the mode it is in. - Restore the output budget. Raises the wire
max_tokensof compaction bodies up to a configurable floor (default16384; the value is never lowered), undoing the context clamp in pi-ai that can collapsemax_tokenson large conversations. - Fix session titles (secondary). Session title generation runs on the same route with a tiny output budget (
maxTokens: 64), soxhighthinking truncates titles too. The plugin writes the configuredreasoning_effortwire value into title request bodies. The title provider locks its LLM options in place before the waterfall, so only the wire body is reachable.
Everything else is untouched. Every gate checks the purpose and the model (waterfall), or the signature and the model (HTTP), so conversation turns, subagents, and any other model pass through unchanged, byte for byte, with the route defaults. Every guard fails open.
The model name must match: read this first
The plugin only acts when the model field of the outgoing request matches an id in the models allowlist: default exactly qwen3.8-27b, case sensitive. It is an exact id match, not a family or substring match, because the sampling parameters written into the body are specific to this model and would be wrong for any other model.
What id is being compared: the model id your route serves, the one declared under llm-pi-ai.providers.<provider>.models[].id in $DSH_HOME/settings.yaml. That is the value dsh puts in the model field of every outgoing request to your gateway. It is not whatever name your gateway internally calls the model.
Make it match: either of two places works:
The
qwen38-compaction-fix:section of$DSH_HOME/settings.yaml(applies live, no restart):qwen38-compaction-fix: models: [your-model-id]The
config:block of the plugin row in your profile'scordis.patch.yml(applies on the next GUI load):- id: qwen38-compaction-fix config: models: [your-model-id]
If your gateway serves the model under a different id (a custom model name, a suffixed variant, different casing), add that id to models. The sampling values stay the same; only the id has to match.
If nothing matches, the plugin silently does nothing: every request passes through unchanged, byte for byte, and there is no warning on a miss. If you installed this plugin and you still see the truncated checkpoint, check the model id first.
Configuration
All keys are optional; defaults are applied by the schema. Precedence (highest first):
qwen38-compaction-fix:section of$DSH_HOME/settings.yaml(applies live, no restart)- the
config:block of the plugin row in your profile'scordis.patch.yml - the defaults shipped with the plugin
Example settings.yaml:
qwen38-compaction-fix:
effort: off # "" disables the effort policy
models: [qwen3.8-27b] # exact ids; [] disables the whole policy
sampling: # wire field names, written verbatim into the body
temperature: 0.7
top_p: 0.8
top_k: 20
min_p: 0.0
presence_penalty: 1.5
repetition_penalty: 1.0
maxTokensFloor: 16384 # 0 disables the floor
titleReasoning: none # "" disables the title gate
| Key | Default | Meaning |
|---|---|---|
effort |
"off" |
Reasoning effort stamped onto matched calls. Preference order: configured, then off, then low; a model offering none of them keeps its own default (a single warning). "" disables the effort policy. |
purposes |
["compaction"] |
purpose tags of LLM calls the waterfall layer applies to. |
models |
["qwen3.8-27b"] |
Exact model ids (case sensitive) the policy applies to, checked at every layer. Empty list disables the whole policy. See the model name section above. |
sampling.* |
{} |
Sampling settings written verbatim into compaction request bodies. Absent keys stay absent. |
maxTokensFloor |
16384 |
The wire max_tokens/max_completion_tokens of compaction bodies is raised to at least this value; never lowered. 0 disables. |
titleReasoning |
"none" |
Wire reasoning_effort value written into session title request bodies. "" disables the gate. |
An explicit reasoningEffort on the call itself always wins over the plugin default.
How it works
Four cooperating layers:
llm/streamwaterfall: for calls whosepurposeis inpurposesand whoseoptions.modelis inmodels, resolves the model's offered reasoning efforts and stamps the chosen effort in place before dispatch.- HTTP sampling: wraps the process
fetch; when a chat completion body carries the compaction engine's final instruction (a stable signature) and itsmodelfield is allowed, applies the configured sampling entries — wire fields as spelled for the NInfer gateway. - HTTP max_tokens floor: same gate; raises the output cap to the floor; never lowers it.
- HTTP session title reasoning: when a body carries the title provider's system prompt (stable signature) and its
modelis allowed, writes the configuredreasoning_effortwire value.
Identity at the HTTP layer relies on the instruction text shipped by dsh-compaction-basic and dsh-session-title-llm. If a future dsh release changes those instructions, the matching HTTP gate silently stops matching and the body keeps its wire defaults. The other gates are unaffected, and nothing ever breaks LLM traffic, because every guard fails open.
Limitations
- Engine scope: NInfer. The wire fields this plugin rewrites are the ones the NInfer gateway interprets. Gateways served by other engines (llama.cpp, vLLM, FastMTP, ...) may ignore or spell these fields differently; the same thinking-off idea can be ported to them, but that port is a different package.
- Model matching is an exact id match against the id declared under
llm-pi-ai.providers.<provider>.models[].idinsettings.yaml. See the model name section above. - The HTTP layer signatures track specific dsh releases; see "How it works" for what happens when a signature stops matching.
- This plugin shapes requests for the local gateway you run. It does not change the harness's own routing or the server's real capacity limits (the server still enforces them).
Testing
The gating logic is covered by a smoke test (see CHANGELOG.md): allowed model bodies are rewritten with the expected sampling, floor, and reasoning values; disallowed model, missing model, and empty allowlist bodies pass through unchanged, byte for byte.
License
MIT. See LICENSE.
链接
同类插件
corrinehu/dsh-workbuddy-connect★ 456
将 WorkBuddy 桌面 App 包含的模型自动接入 DeepSeek Harness,在 DSH 对话窗口里零配置使用。
V1ki/dsh-plugin-subscriptions★ 447
把 ChatGPT(Codex)、Claude、Grok 订阅当作 DeepSeek Harness 的 LLM 提供方:设置页登录、模型目录、用量展示,以及 image_generate、video_generate 与 x_search 工具。
Mars-Sea/dsh-commandcode-provider★ 379
非官方 Command Code 模型接入插件:注册 `commandcode` 路由,带实时模型目录与推理强度支持。
cv-superding/dsh-deepseek-web-login★ 256
新增 deepseek-web provider,把 chat.deepseek.com 网页端模型接入 DSH:浏览器登录抓取、PoW 请求签名、SSE 流式传输与基于提示词的工具调用。
FishBottle7/opencode2dsh★ 175
将 OpenCode Zen 免费模型接入 DeepSeek Harness,无需 API Key。
WSL043/dsh-codex-subscription★ 161
通过 ChatGPT OAuth 在 DSH 中使用 Codex 模型,提供订阅联网搜索、额度与安全重置、图片工具、高速模式和模型感知上下文;无需 API Key 或 Codex CLI。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。