DeepSeek-V4-Flash 流式模式下所有工具调用报 unknown tool ""
#725
问题描述使用 工具名始终为空字符串,导致在 根本原因
// 当前写法 — 后续空字符串分块会覆盖已解析的工具名
if (call.id !== undefined) block.callId = call.id
if (call.function?.name !== undefined) block.name = call.function.name修复方案// 修复写法 — 安全累加所有分块
if (call.id !== undefined) block.callId = (block.callId ?? '') + call.id
if (call.function?.name !== undefined) block.name = (block.name ?? '') + call.function.name验证结果应用修复后, 环境: Windows 11 · DeepSeek-V4-Flash · SSE 流式传输 |
Replies: 6 comments 2 replies
|
工具名被解析成空字符串,导致任何 Skill 和工具都无法运行。 原因
解决方案修改 - if (call.id !== undefined) block.callId = call.id
- if (call.function?.name !== undefined) block.name = call.function.name
+ if (call.id !== undefined) block.callId = (block.callId ?? '') + call.id
+ if (call.function?.name !== undefined) block.name = (block.name ?? '') + call.function.name改完重新 pnpm run build 再重启 dsh 即可。 我的环境: Windows 11 · DeepSeek-V4-Flash · SSE 流式输出 |
|
这个解决方案对于hy3和longcat-2.0等模型不太适用,它们SSH流式输出时delta2的id和name会填充null,需要再补充对于null值的处理 |
|
所以我要怎么更新呢? |
|
Just a heads up: this bug also causes severe secondary damage (bricking session history). Since the tool call was persisted with an empty callId (""), when you restart and try to load the session log, it triggers a SessionPersistenceCorruptionError ("message must have tool source"). This happens because assertMessageEventShape in packages/core/session/src/index.ts strictly rejects callId === ''. So this bug not only breaks the current execution but also permanently corrupts the session file. To rescue corrupted sessions, we should relax the empty string check in packages/core/session/src/index.ts: --- packages/core/session/src/index.ts
+++ packages/core/session/src/index.ts
@@ -336,8 +336,7 @@
if (type !== 'tool/result') return
if (sourceRecord['kind'] !== 'tool'
- || typeof sourceRecord['callId'] !== 'string'
- || sourceRecord['callId'] === '') {
+ || typeof sourceRecord['callId'] !== 'string') {
throw new Error(`${subject} message must have tool source`)
}补充一个次生灾害及修复方案: 这个 Bug 会导致已经保存的历史会话完全损坏、无法加载(触发 SessionPersistenceCorruptionError)。因为带有空 callId 的异常记录被写入后,重启读取时会被 assertMessageEventShape 的严格校验拦截。要拯救已经坏档的会话,只需按上面的 Diff 移除对空字符串的限制,放宽校验即可正常载入历史脏数据。 |
|
这个根因我们也确认过(手册 FAQ 已收录): 官方修复前的规避:
排查思路和同族 bug 汇总见:https://github.com/Electricitysheep/dsh-handbook/blob/main/docs/faq.md |
|
修复如下: https://github.com/enjlife/deepseek-harness/pull/new/fix/llm-deepseek-empty-tool-name |
工具名被解析成空字符串,导致任何 Skill 和工具都无法运行。
原因
packages/llm/llm-deepseek/src/translate.ts在解析 SSE 流时,每个新分块都会覆盖已有的工具名,而不是累加。
当后续分块的
function.name为空时,就把之前解析好的名字抹掉了。解决方案
修改
packages/llm/llm-deepseek/src/translate.ts第 159–160 行:改完重新 pnpm run build 再重启 dsh 即可。
我的环境: Windows 11 · DeepSeek-V4-Flash · SSE 流式输出