fix(core): 修复工具调用重复触发导致前端显示两次的问题

问题原因:
- onToolStart 同时传给了 toVercelTools 和 streamChat 两处
- 导致工具开始事件在 onChunk 和 executeTool 中各触发一次
- 两处生成的 toolCallId 不同,前端去重逻辑无法生效

修复方案:
- 移除传给 toVercelTools 的 onToolStart,只保留 streamChat 中的触发
- 在 handleToolCallChunk 中增加 toolCallId 去重检查(防止 AI SDK 发送重复 chunk)
This commit is contained in:
2025-12-16 23:50:18 +08:00
parent 3b170738ee
commit a4e8037108
2 changed files with 8 additions and 2 deletions
@@ -225,6 +225,11 @@ export class AgentMessageHandler {
): void {
const toolCallId = chunk.toolCallId || `tool-${Date.now()}`;
// 去重:如果该工具调用已经被处理过,跳过
if (toolStartTimes.has(toolCallId)) {
return;
}
// Doom Loop 检测
this.doomLoopDetector.record(chunk.toolName, chunk.input);
@@ -236,7 +241,7 @@ export class AgentMessageHandler {
onStream?.(DOOM_LOOP_WARNING);
}
// 记录开始时间
// 记录开始时间(同时作为去重标记)
toolStartTimes.set(toolCallId, Date.now());
// 调用回调
+2 -1
View File
@@ -193,10 +193,11 @@ export class Agent {
this.toolExecutor.setAgentMode(this.modeManager.getCurrentMode());
// 获取工具
// 注意:不传 onToolStart 给 toVercelTools,因为 streamChat 的 onChunk 已经会触发
// 如果同时传给两处,会导致前端收到两次 tool_start 事件
const vercelTools = this.toolExecutor.toVercelTools({
sessionId: this.sessionManager?.getSession()?.id || 'default',
agentMode: this.modeManager.getCurrentMode(),
onToolStart,
onToolEnd,
});