优化: dag拓扑O(V+E)+前端findToolCall反向遍历
- FR-D1 dag.rs topological_layers + executor.rs run 建 adjacency 索引, O(V·E)→O(V+E)(14测试全绿, 含executor3测)
- FR-R5 useAiEvents findToolCall 正向 O(n²) 改反向遍历(命中最近, 放弃Map索引防陈旧引用)
- AR-6 核查确认已于 f82dd8b 落地(Low失败emit AiToolCallCompleted), 零改动
This commit is contained in:
@@ -59,12 +59,26 @@ export function flushCurrentText() {
|
||||
if (last && last.role === 'assistant') last.content = state.currentText
|
||||
}
|
||||
|
||||
/** 在全部消息中查找指定 id 的工具调用卡片(用于状态流转) */
|
||||
/**
|
||||
* 在全部消息中查找指定 id 的工具调用卡片(用于状态流转)
|
||||
*
|
||||
* 扫描策略:从尾部反向遍历并提前退出。tool_result/approval/completed
|
||||
* 通常对应最近触发的 tool_use(agent 顺序执行工具并尽快回填结果),
|
||||
* 反向扫描使其命中落在尾部 → 平均 O(1)、最坏 O(n)。(原正向全量扫描为 O(n²),
|
||||
* 每条 tool_result 都从头扫整条历史。)
|
||||
*
|
||||
* 注:未引入 Map<id, tc> 索引。state.messages 在 newConversation /
|
||||
* switchConversation / deleteConversation 等处被整体替换(且这些操作散落在
|
||||
* useAiEvents 之外),独立索引极易与响应式数组失配形成"陈旧引用"——状态卡
|
||||
* 片读到已不存在的对象。反向扫描零额外状态、改动最小且行为完全一致。
|
||||
*/
|
||||
export function findToolCall(id: string): AiToolCallInfo | undefined {
|
||||
for (const msg of state.messages) {
|
||||
if (msg.toolCalls) {
|
||||
const tc = msg.toolCalls.find(t => t.id === id)
|
||||
if (tc) return tc
|
||||
for (let i = state.messages.length - 1; i >= 0; i--) {
|
||||
const toolCalls = state.messages[i].toolCalls
|
||||
if (!toolCalls) continue
|
||||
// 同一消息内工具调用通常很少,沿用正向扫描;命中即返回
|
||||
for (let j = 0; j < toolCalls.length; j++) {
|
||||
if (toolCalls[j].id === id) return toolCalls[j]
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
||||
Reference in New Issue
Block a user