🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

zzzyaar/dsh--API-message_stop-

DeepSeek 客户端兼容 / 相关生态spec-screened扫描:低风险在 GitHub 查看 ↗
⚠ 装前注意

deepseek harness 使用第三方提供者的api时的缺失messagestop导致的重复重试

基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/7 · 已提供中文文档

deepseek harness 使用第三方提供者的api时的缺失message_stop导致的重复重试

综合分
29.4
GitHub 分
29.4
用户评分
—
★ Stars
1
周下载量
—
兼容 / 相关生态插件(非 dsh 原生,请按其对应运行时安装)
git clone https://github.com/zzzyaar/dsh--API-message_stop-.git
信任档位:已验证本站已于 1 天前真实安装成功
是什么
生态插件(可安装,未声明 dsh 能力)
装得上吗
本站已真实安装成功(非静态推断)
安全吗
本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
还在维护吗
活跃:最近一次提交在 18 天前

档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →

🟢实装验证通过· 2026/9/25
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/20(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-missing-stop-heal(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=18 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

未发布到 npm registry,仅可从源码安装

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/22 19:18:43

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

由 DeepSeek 最新模型翻译生成
dsh 第三方 API 缺失 message_stop 重试修复

DeepSeek Harness (dsh) 插件:当第三方提供方网关翻译漏发了终止事件 message_stop/done 时,dsh 把内容已完整到达的回复误判为 TRANSPORT 传输错误,并对同一步最多做 5 次指数退避重试。本插件把“内容已到、缺终止信号”的流干净地结束,让回复正常提交、重试不再发生。

English: A dsh plugin that heals third-party Anthropic-compatible gateways which close the stream without a terminal message_stop/done event, so the agent loop commits a complete reply instead of burning up to 5 backoff retries.

目录
1. 这是什么 / 现象
2. 根因(源码依据)
3. 修复方案
4. 安装
5. 配置
6. 设置页(GUI)
7. 使用说明
8. 注意事项与边界
9. 常见问题
10. 如何验证 / 诊断
11. 许可

一、现象

- 在 dsh 里把某个网关配成 anthropic-messages 协议。
- 每次对话都报 Anthropic stream ended before message_stop,然后 llm-retry 重试 5 次(延迟约 467 → 1090 → 2031 → 3982 → 7282 ms,指数退避)。
- 但最终输出是正确的、完整的——内容早在重试触发前就到了,缺的只是终止信号。

从 session.jsonl 可见:

{"type":"assistant/chunk","...":"chunk":{"type":"finish","reason":{"kind":"error","failure":{"message":"Anthropic stream ended before message_stop","code":"TRANSPORT"}}}}
{"type":"llm/retry","...":"data":{"provider":"xjhc","mode":"normal","retry":1,"maxRetries":5,...}}

二、根因(源码依据)

1. 缺失终止事件由 pi-ai 适配器抛出:@deepseek-ai/dsh-llm-pi-ai/lib/index.js 的 toStreamChunks() 只在收到 done/error 事件时产出 usage+finish 并正常返回;若事件流自然跑完却无终止事件,则在末尾抛

throw new LlmError("pi-ai event stream ended without done/error", "STREAM_CLOSED")

2. 错误码分类:classifyPiAiError() 把含 stream ended (before|without) 的消息归为 TRANSPORT。
3. 触发重试:agent-loop 的 step() 在流式收尾时,若 finish 为 error/aborted,就走 agent/request-error 瀑布;@deepseek-ai/dsh-llm-retry 的 recover() 见到 TRANSPORT 在 retryableCodes 内、且未达 maxRetries,就按 initialDelayMs * 2n 退避并返回 {kind:'retry'}——于是同一步被重新完整请求一次。
4. 为何“最终内容仍正确”:每次重试都重新拿到同样完整的内容;重试耗尽后该步抛错,界面展示的其实是最后那批流式渲染的 assistant/chunk。
5. 为何“干净结束”就够:BlockAssembler 的 finish 取值是

get finish() { return this._finish ?? { kind: 'stop' } }

即流没有 finish chunk 也算正常 stop。所以只要把“缺终止信号”这个错误吞掉、让流干净结束,回复就会被正常提交,request-error/llm-retry 根本不会发生。

三、修复方案

监听 dsh host 端公开的 llm/stream waterfall(“around every streaming model call”),把下游流包一层:

- 内容 chunk(block-start / text、reasoning、tool-call 的 delta & end / usage)原样透传;
- 只有当错误为“缺终止信号”特征(code === 'STREAM_CLOSED',或失败信息含 stream ended (before|without) / message_stop / done/error),且已收到内容、且所有未闭合的 tool-call 块参数已是合法 JSON 时,才丢弃该错误、干净结束;
- 其余一切情况(真断网、限流、超时、鉴权、abort、空响应、参数残缺的 tool call)原样放行/照常抛错,重试行为不变。

语义上等价于“把这个网关变得宽容:内容完整即算完”。代码见 heal.mjs(ESM,导出标准 Cordis 插件 { name, apply })。

四、安装

方式 A(推荐):作为 web profile bundle,用设置页配置

装进 web profile 后,插件在进程级生效,规则可在 GUI 设置页里调。

dsh plugin --profile web add dsh-missing-stop-heal

- 从 dshmarket(插件市场) 里搜 missing-stop-heal 一键安装也行。
- 装完重启 dsh(bundles 在启动时读取)。
- 用仓库源码本地开发:dsh plugin --profile web add link:(link 方式 = 改仓库即生效,不用重装)。
- 想先只给某个会话用,见方式 B 的 preset 挂载(此时配置走行内 config,没有设置页)。

方式 B:作为 agent preset 的一行(旧式,会话级)

在某个 agent preset 的 agent.cordis.yml 末尾加一行(name 以 . 开头,loader 按 preset 目录相对路径解析):

- id: missing-stop-heal
name: './heal.mjs'
config:
providers:
- xjhc

把 heal.mjs(或经目录联接指向本仓库)放到该 preset 目录下即可。

注意:tool-cordis / 动态 Cordis 插件是进程内临时的,重启即失效;本插件作为 preset / profile 组成行是持久的。

五、配置

配置可通过行内 config(方式 B / 补丁层)或设置页(方式 A,写 user 层)提供。两种写法,rules 为主:

config:
rules:
- provider: xjhc            # 必填:provider 标识(llm/stream options.provider)
models: ['']             # 选填:缺省/空 = 全部模型;支持  通配,如 deepseek-v4*
enabled: true             # 选填:缺省 true

- 旧写法 config.providers: ['a','b'] 仍兼容=这些 provider 的全部模型;providers 与 rules 可混用,逐条累加。
- models 语义:留空或填  = 该 provider 的全部模型;写多个用逗号/数组分隔;可用  通配前缀(如 deepseek-v4 匹配 deepseek-v4 开头)。
- 什么都不配 = 不修复任何流(插件对每个请求只提示一次,其余原样放行)。
- 规则按 llm/stream 事件的 options.provider + options.model 逐条匹配;命中才包裹该流。

六、设置页(GUI)

装成 bundle(方式 A)后,dsh web 的设置侧栏会多一个「流重试修复」独立入口(settings.section,类似「插件市场」的独立项):

- provider:下拉候选来自 host 读取的真实已配置 provider 列表(ctx.llm.listProviders),可点选/手填;
- models:选定 provider 后下拉列出该 provider 的真实模型候选(host ctx.llm.listModels),也可手填 +  通配;
- 每行可勾选启用、可增删;点「保存规则」立即写入并对下一条请求生效(当前正在进行的请求不受影响);「恢复部署默认」清空 user 层、回到 patch/行配置里的默认。

provider/模型目录(catalog)由 host 端写入设置文档,随 llm/adapters-updated 自动刷新;客户端直接从同一 settingsScope 快照读取,无需手动同步。

七、使用说明

1. 安装(方式 A 或 B)、必要时重启 dsh;
2. 配置生效范围:小任务常用网关(如 xjhc)用 rules 列出;官方 API 不必列,未被规则命中的请求一律放行;
3. 想随时改:用设置页勾选(方式 A),或编辑 patch/行配置后刷新即可;
4. 改宿主代码(heal.mjs)需重启 dsh;改客户端(client/client.js)浏览器 Ctrl+F5 即可。

八、注意事项与边界

- 只对命中规则的 provider/模型生效;其余(含官方 API)完全不受影响。
- 只修复"内容已到 + 缺终止信号"这一种特征:参数残缺的未闭合 tool-call、空响应、abort、真断网/限流/超时/鉴权失败一律不修,保持原报错/重试语义,不会掩盖真正的错误。
- 对下一条请求生效:规则改动不追溯当前在途请求。
- 被修复的流没有 finish chunk、也没有 replayState;usage 是否保留取决于错误是 in-band(有 usage)还是抛错(无 usage),通常 token 计量走估算。
- 需要 dsh web ≥ 0.1.0-rc.6(engines.dsh 已声明);@deepseek-ai/schemastery 以 peerDependencies 声明,用于设置命名空间(缺失时自动退化为纯行配置,修复功能不受影响)。
- 该插件不接触凭据、不发网络请求,只包一层流;无安全面扩展。
- 若某次更新 dsh 后事件名/结构变化导致不再生效,检查 llm/stream 的 options.provider/options.model 字段(本仓库根因分析里有完整签名)。

九、常见问题

- 装完在设置里看不到「流重试修复」? 确认用方式 A 装进了 web profile 并重启;设置页是独立 settings.section,不是藏进「插件」列表。
- 页面显示"设置服务不可用"? 多为页面连上时命名空间尚未就绪/mirror 快照过期——Ctrl+F5 或重开标签;插件内置自动重试,稍等即可。
- provider 下拉是空的? 目录由 host 在 llm/adapters-updated 时写入;首次装完重启后即有,之后可手填。
- 为什么官方 API 也会被修? 不会——未在 rules 里列出的 provider 一律放行。
- 会不会把真错误吞掉? 不会——只匹配"内容已到 + 缺终止信号"特征,且要求未闭合 tool-call 参数为合法 JSON;其它错误照常抛。

十、如何验证 / 诊断

dsh 会话日志是 JSONL(默认在 $DSH_HOME/sessions/.../session.jsonl)。判断该会话是否发生过此问题:

Select-String -Path  -Pattern 'llm/retry|TRANSPORT|message_stop|STREAM_CLOSED|stream ended|request-error'

- 修复前:能看到 llm/retry、TRANSPORT、Anthropic stream ended before message_stop;
- 修复后:assistant/message 的 sourceEventSeqs 是单次连续区间(每步一次尝试即落库),没有 llm/retry 事件。

十一、许可

MIT,作者 zzzyaar。欢迎在此基础上扩展、提交 PR。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群