工具调用 id 复用导致历史加载失败:兼容端点 callId 会话内不唯一,建议 UI 层加 turn/step 命名空间 #3644
oevon364-ship-it
started this conversation in
General
Replies: 0 comments
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.
问题现象 Symptom
加载某些历史会话时整段历史不可用,Web 端报:
多个会话同时受影响(同批会话),其余会话正常。数据本身完整:seq 连续、JSON 全部可解析、无并发写损坏迹象(不是 #1433/#1452/#1497 那种 seq 回绕)。
根因分析 Root Cause
受影响会话由 OpenAI-completions 兼容端点(非官方 API,走自定义网关/中转)生成。这类端点的 tool call id 是每轮响应内编号的局部 id:
会话事件日志里
call_0出现几十次,每次都是不同的工具调用(不同 step / 不同参数)。而客户端 Conversation 引擎的
toolDefinition(packages/client/ui-conversation/src/client/conversation-nodes/tool.ts)用裸 callId 作为 Context 身份(conversationContextKey('tool-call', callId))。同一会话内 callId 复用 → 同一个 Context 收到第二个startMatch → assembler 按设计 fail-loud 抛more than one start Match→ 整段历史拒绝加载。官方 OpenAI API 的 tool call id 全局唯一(
call_abc123...),所以官方端点从不触发;兼容端点不保证这一点,UI 层却假设了会话内唯一。佐证
(turn, step, callId)三元组零冲突(全部 64 个受影响会话验证过)tool/result与前置tool/call的 turn/step 100% 一致(1488/1488 对)修复方案 Fix
让 tool-call 的 Context 身份带上 turn/step 命名空间:裸
callId→${turn}:${step}:${callId}。这样每轮的call_0变成1:1:call_0、1:2:call_0、1:3:call_0…… 会话内天然唯一,且对已有历史数据零改动(key 是运行时派生的,不落盘)。改动点:
packages/client/ui-conversation/src/client/conversation-nodes/tool.ts—toolDefinition.match的 id 生成加turn:step:前缀(tool/call、tool/result两个分支;tool/code-dispatch-*分支在事件带坐标时同样加前缀,旧日志无坐标时回退裸 id 保持兼容)packages/client/ui-trajectory/src/client/trajectory-tool-definition.ts— trajectory 视图的trajectory-tool-call同样处理(同类问题,不修的话 trajectory 面板会命中同一个重复 start)packages/core/tools/src/code-mode.ts+types.ts— 数据侧:tool/code-dispatch-start/tool/code-dispatch事件现在携带 root 调用的turn/step(从会话日志里 roottool/call事件拷贝),保证嵌套 dispatch 记录能与前缀化后的 root Context 配对。旧日志(无坐标)仍回退裸 rootCallId,不会崩packages/client/ui-conversation/src/client/chat/tool-node-reader.ts—rootToolCall由「按 key 精确查」改为「遍历匹配 root callId」,避免 key 格式变化后查询失配为什么不改数据 / 不加锁
call_0编号)无法从 DSH 侧改变,UI 层命名空间是唯一稳妥的根治点验证 Verification
ConversationNodeAssembler+ 修复后的toolDefinition加载:零失败(修复前 64 个抛 duplicate start)packages/client、packages/core/tools、packages/core/session全量 3979/3979 通过(含 conversation-node-definitions、trajectory definitions、code-mode、assembler 测试)/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js确认含前缀逻辑关联
作者:胡桃(胡桃的神秘小屋)
All reactions