perf: 优化 Agent 流式会话处理

- 合并流式通知与持久化写入,限制浏览器会话缓存

- 增量投影轮次事件并稳定关联异步工具任务
This commit is contained in:
2026-07-27 19:41:11 +08:00
parent 5497931abd
commit b08eb009bb
10 changed files with 539 additions and 47 deletions

View File

@@ -162,14 +162,26 @@ function finishAssistantMessage(
}
}
function findToolItem(items: ChatTimelineItem[], toolCallId?: string) {
const identity = normalizeText(toolCallId).trim();
if (!identity) {
function findToolItem(
items: ChatTimelineItem[],
toolCallId?: string,
taskId?: string,
sourceToolCallId?: string,
) {
const identities = new Set(
[toolCallId, sourceToolCallId]
.map((value) => normalizeText(value).trim())
.filter(Boolean),
);
const normalizedTaskId = normalizeText(taskId).trim();
if (identities.size === 0 && !normalizedTaskId) {
return undefined;
}
return items.find(
(item): item is ChatTimelineToolItem =>
item.type === 'tool' && item.toolCallId === identity,
item.type === 'tool' &&
((Boolean(normalizedTaskId) && item.taskId === normalizedTaskId) ||
(item.toolCallId ? identities.has(item.toolCallId) : false)),
);
}
@@ -251,7 +263,9 @@ function upsertTool(
rejectReason?: string;
requestId?: string;
resumeToken?: string;
sourceToolCallId?: string;
status?: ChatTimelineToolStatus;
taskId?: string;
toolCallId?: string;
toolName?: string;
},
@@ -259,7 +273,13 @@ function upsertTool(
const toolCallId = normalizeText(
payload.toolCallId ?? payload.approval?.toolCallId,
).trim();
const found = findToolItem(items, toolCallId);
const taskId = normalizeText(payload.taskId).trim();
const found = findToolItem(
items,
toolCallId,
taskId,
payload.sourceToolCallId,
);
const approval = payload.approval ?? found?.approval;
const mode =
payload.mode === 'approval'
@@ -287,6 +307,7 @@ function upsertTool(
found.output = normalizePayloadValue(payload.output) ?? found.output;
found.rejectReason = payload.rejectReason ?? found.rejectReason;
found.status = payload.status || found.status;
found.taskId = taskId || found.taskId;
found.toolCallId = toolCallId || found.toolCallId;
found.toolName = toolName || found.toolName;
return found;
@@ -304,6 +325,7 @@ function upsertTool(
rejectReason: payload.rejectReason,
status:
payload.status || (mode === 'approval' ? 'pending_approval' : 'running'),
taskId: taskId || undefined,
toolCallId,
toolName: toolName || '工具调用',
type: 'tool',
@@ -417,8 +439,10 @@ export const ChatTimelineBuilder = {
payload: {
input?: unknown;
output?: unknown;
sourceToolCallId?: string;
status?: ChatTimelineToolStatus;
statusKey?: string;
taskId?: string;
toolCallId?: string;
toolName?: string;
},