Replies: 1 comment 1 reply
|
你的结论我对着 master( 核对结果:
你的修复实操没有需要修正的地方;唯一想强调的风险:改日志时必须保持 seq 连续( |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
messages 协议:历史里一条 tool input 不是合法 JSON,会让整条会话永久无法恢复
Summary
b0641b83fc("feat(llm): default DeepSeek to Messages with Files parity")把默认协议从chat-completions切到messages之后,历史中只要存在一条arguments不是合法 JSON 的 tool call,该会话就永久无法再打开。原因是
messages适配器在序列化历史时会校验每条工具输入(protocols/messages/serialize.ts:16-22),一条不合法即拒绝整个请求;而恢复会话必须重放整份历史,于是每次都失败、无法自救。同一份历史在
chat-completions下可正常使用(该路径不做此校验),这也是升级前该会话一直可用的原因。模型偶发生成非法 JSON 是生成侧问题,但让它升级为"整条会话报废"的是适配器缺少容错。一个容易踩偏的实现细节(本贴的核心)
同一份工具参数在会话日志里存了两份,两处都可以独立损坏,而只有其中一份会被校验:
serialize.ts读取tool/call事件的data.argumentsassistant/message的tool-call内容块argumentsmessage.content)serialize.ts:24-36的assistant()遍历的是message.content,:33对每个tool-call块调用toolInput(block.arguments)。这是结构性的,不是巧合:消息派生只接受"表面事件",而
tool/call不在其中——packages/core/session/src/index.ts:315-318:tool/call(写入点packages/core/agent-loop/src/tool-calls.ts:264)永远不进入序列化器接收的Message[],因此被校验的只有assistant/message内容块里那一份。实测后果:把
tool/call事件那份修好后,会话仍然打不开——必须连内容块那份一起修。诊断时若只检查事件副本(或只看会话日志里的type=tool/call行),会得出"已修复"的错误结论。建议诊断工具同时检查两处。Reproduction
在
messages协议(即当前默认)下运行会话,期间某次工具调用的arguments由模型生成为非法 JSON。本例是模型在中文正文里使用了未转义的英文双引号:正确写法应为
\"某个说法\",或按中文排版改用全角引号。该轮不会立即报错:工具照常执行、后续步骤照常进行,坏记录被原样写入会话日志。
之后任意一次恢复该会话 → 序列化整份历史 → 失败:
此后该会话每次恢复都失败,无法继续,也无法压缩自救。
Current behavior
protocols/messages/serialize.ts:16-22直接抛错,整个请求被拒:用户侧只得到这一行,不含 callId / 工具名 / 位置,无法定位是哪一条坏在哪里;该会话只能放弃。
本机实测(DSH
0.1.6-alpha.1,Windows 11,deepseek-official/deepseek-flash):tool/callask_user_question,seq=167,内容块索引 2,arguments全长 911 字符assistant/message(含该tool-call块);第 2 行是同一参数的tool/call事件副本Expected ',' or '}' after property value in JSON at position 389arguments内 82 个双引号全部未转义(含结构引号),解析器直到正文引号处才迷路;断点389正是紧跟…最快,但之后的那个裸引号修复验证:将正文引号成对替换为全角引号、结构引号保持裸引号后,
JSON.parse通过,语义完整保留("某个说法"→“某个说法”),会话恢复可用。注意两处副本都要改:只改tool/call事件那份时,会话依旧打不开(本机实测)。Expected behavior
建议至少实现第 1 条:
protocols/messages/replay.ts:39-46的readReplay()—— 捕获INVALID_REPLAY_STATE后调用onDegrade并返回undefined,即"丢弃不可用元数据 + 记警告 + 保留内容";arguments是否可解析,不可解析则就地归一化,避免坏记录进入 durable log;callId/seq/ 工具名,便于用户定位。Environment
0.1.6-alpha.1(0d1f50007f),Windows 11deepseek-official/deepseek-flash(DeepSeek-V41-Flash),协议messages(默认)b0641b83fc;相关代码:protocols/messages/serialize.ts:16-22、:33、protocols/messages/replay.ts:39-46、packages/core/session/src/index.ts:315-318All reactions