refactor(history): reduce computational complexity when handling history

When updating chat history to be used in LLM request there are several
instances where we do O(n^2) operations: scanning all messages to locate
a tool "use" and for each use scan messages again to locate
corresponding "result".

Refactor the code to scan messages once collecting tool uses and results
together, and then do 2nd scan to drop incomplete tool invocations and
refresh "view" and "edit" results with the latest content.

Also reduce number of pre-scan loops (where we discard partially
generated messages or messages that are not interesting or too-old) by
combining them when possible.

This reduces time to scan initial 417 messages on my system (which
result in 576 final messages) from 0.32 to 0.12 seconds.
This commit is contained in:
Dmitry Torokhov
2025-07-08 17:22:39 -07:00
parent c2e4ae5ef6
commit 2335ea3d15
5 changed files with 312 additions and 264 deletions

View File

@@ -1496,30 +1496,10 @@ function M.tool_use_to_xml(tool_use)
end
---@param tool_use AvanteLLMToolUse
function M.is_edit_func_call_tool_use(tool_use)
local is_replace_func_call = false
local is_str_replace_editor_func_call = false
local is_str_replace_based_edit_tool_func_call = false
local path = nil
if tool_use.name == "replace_in_file" then
is_replace_func_call = true
path = tool_use.input.path
end
if tool_use.name == "str_replace_editor" then
if tool_use.input.command == "str_replace" then
is_replace_func_call = true
is_str_replace_editor_func_call = true
path = tool_use.input.path
end
end
if tool_use.name == "str_replace_based_edit_tool" then
if tool_use.input.command == "str_replace" then
is_replace_func_call = true
is_str_replace_based_edit_tool_func_call = true
path = tool_use.input.path
end
end
return is_replace_func_call, is_str_replace_editor_func_call, is_str_replace_based_edit_tool_func_call, path
function M.is_edit_tool_use(tool_use)
return tool_use.name == "replace_in_file"
or (tool_use.name == "str_replace_editor" and tool_use.input.command == "str_replace")
or (tool_use.name == "str_replace_based_edit_tool" and tool_use.input.command == "str_replace")
end
---Counts number of strings in text, accounting for possibility of a trailing newline