From d44db1053550acdf56f0995144dc41368573f508 Mon Sep 17 00:00:00 2001 From: yetone Date: Thu, 29 May 2025 03:55:32 +0800 Subject: [PATCH] fix: tool result message must be adjacent to the tool use message (#2096) --- lua/avante/llm.lua | 61 +++------------------ lua/avante/llm_tools/attempt_completion.lua | 2 +- lua/avante/utils/init.lua | 33 ++++------- 3 files changed, 21 insertions(+), 75 deletions(-) diff --git a/lua/avante/llm.lua b/lua/avante/llm.lua index dcc9356..cd7218e 100644 --- a/lua/avante/llm.lua +++ b/lua/avante/llm.lua @@ -401,59 +401,16 @@ function M.generate_prompts(opts) local final_history_messages = {} if cleaned_history_messages then - if opts.disable_compact_history_messages then - for i, msg in ipairs(cleaned_history_messages) do - if Utils.is_tool_use_message(msg) then - local next_msg = cleaned_history_messages[i + 1] - if not next_msg or not Utils.is_tool_result_message(next_msg) then goto continue end - if next_msg.message.content[1].tool_use_id ~= msg.message.content[1].id then goto continue end - end - if Utils.is_tool_result_message(msg) and not Utils.get_tool_use_message(msg, cleaned_history_messages) then - goto continue - end - table.insert(final_history_messages, msg) - ::continue:: + for _, msg in ipairs(cleaned_history_messages) do + local tool_result_message + if Utils.is_tool_use_message(msg) then + tool_result_message = Utils.get_tool_result_message(msg, cleaned_history_messages) + if not tool_result_message then goto continue end end - else - if Config.history.max_tokens > 0 then - remaining_tokens = math.min(Config.history.max_tokens, remaining_tokens) - end - - -- Traverse the history in reverse, keeping only the latest history until the remaining tokens are exhausted and the first message role is "user" - local retained_history_messages = {} - for i = #cleaned_history_messages, 1, -1 do - local message = cleaned_history_messages[i] - local tokens = Utils.tokens.calculate_tokens(message.message.content) - remaining_tokens = remaining_tokens - tokens - if remaining_tokens > 0 then - table.insert(retained_history_messages, 1, message) - else - break - end - end - - if #retained_history_messages == 0 then - retained_history_messages = - vim.list_slice(cleaned_history_messages, #cleaned_history_messages - 1, #cleaned_history_messages) - end - - pending_compaction_history_messages = - vim.list_slice(cleaned_history_messages, 1, #cleaned_history_messages - #retained_history_messages) - - pending_compaction_history_messages = vim - .iter(pending_compaction_history_messages) - :filter(function(msg) return msg.is_dummy ~= true end) - :totable() - - vim.iter(retained_history_messages):each(function(msg) - if Utils.is_tool_use_message(msg) and not Utils.get_tool_result_message(msg, retained_history_messages) then - return - end - if Utils.is_tool_result_message(msg) and not Utils.get_tool_use_message(msg, retained_history_messages) then - return - end - table.insert(final_history_messages, msg) - end) + if Utils.is_tool_result_message(msg) then goto continue end + table.insert(final_history_messages, msg) + if tool_result_message then table.insert(final_history_messages, tool_result_message) end + ::continue:: end end diff --git a/lua/avante/llm_tools/attempt_completion.lua b/lua/avante/llm_tools/attempt_completion.lua index ca875a6..dcab0cc 100644 --- a/lua/avante/llm_tools/attempt_completion.lua +++ b/lua/avante/llm_tools/attempt_completion.lua @@ -65,7 +65,7 @@ function M.func(opts, on_log, on_complete, session_ctx) just_for_display = true, }) sidebar:add_history_messages({ message }) - if opts.command then + if opts.command and opts.command ~= "" and opts.command ~= vim.NIL then require("avante.llm_tools.bash").func({ command = opts.command }, on_log, on_complete, session_ctx) else on_complete(true, nil) diff --git a/lua/avante/utils/init.lua b/lua/avante/utils/init.lua index 93b2bbd..f209440 100644 --- a/lua/avante/utils/init.lua +++ b/lua/avante/utils/init.lua @@ -1411,19 +1411,13 @@ function M.get_tool_use_message(message, messages) end end if not tool_id then return nil end - local idx = nil - for idx_, message_ in ipairs(messages) do - if message_.uuid == message.uuid then - idx = idx_ - break - end - end - if not idx then return nil end - for idx_ = idx - 1, 1, -1 do + for idx_ = #messages, 1, -1 do local message_ = messages[idx_] local content_ = message_.message.content - if type(content_) == "table" and content_[1].type == "tool_use" and content_[1].id == tool_id then - return message_ + if type(content_) == "table" then + for _, item in ipairs(content_) do + if item.type == "tool_use" and item.id == tool_id then return message_ end + end end end end @@ -1445,18 +1439,13 @@ function M.get_tool_result_message(message, messages) end end if not tool_id then return nil end - local idx = nil - for idx_, message_ in ipairs(messages) do - if message_.uuid == message.uuid then - idx = idx_ - break - end - end - if not idx then return nil end - for _, message_ in ipairs(vim.list_slice(messages, idx + 1, #messages)) do + for idx_ = #messages, 1, -1 do + local message_ = messages[idx_] local content_ = message_.message.content - if type(content_) == "table" and content_[1].type == "tool_result" and content_[1].tool_use_id == tool_id then - return message_ + if type(content_) == "table" then + for _, item in ipairs(content_) do + if item.type == "tool_result" and item.tool_use_id == tool_id then return message_ end + end end end end