fix: tool use id sometimes will be the same (#1982)
This commit is contained in:
@@ -182,7 +182,8 @@ function M.generate_prompts(opts)
|
||||
local latest_tool_id = viewed_files[path]
|
||||
if not latest_tool_id then goto continue end
|
||||
if latest_tool_id ~= item.tool_use_id then
|
||||
item.content = string.format("The file %s has been updated. Please use the latest view tool result!", path)
|
||||
item.content =
|
||||
string.format("The file %s has been updated. Please use the latest `view` tool result!", path)
|
||||
else
|
||||
local lines, error = Utils.read_file_from_buf_or_disk(path)
|
||||
if error ~= nil then Utils.error("error reading file: " .. error) end
|
||||
@@ -288,18 +289,20 @@ function M.generate_prompts(opts)
|
||||
dropped_history_messages = vim.list_extend(dropped_history_messages, opts.prompt_opts.dropped_history_messages)
|
||||
end
|
||||
|
||||
local cleaned_history_messages = opts.history_messages
|
||||
|
||||
local final_history_messages = {}
|
||||
if opts.history_messages then
|
||||
if cleaned_history_messages then
|
||||
if opts.disable_compact_history_messages then
|
||||
final_history_messages = vim.list_extend(final_history_messages, opts.history_messages)
|
||||
final_history_messages = vim.list_extend(final_history_messages, cleaned_history_messages)
|
||||
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 history_messages = {}
|
||||
for i = #opts.history_messages, 1, -1 do
|
||||
local message = opts.history_messages[i]
|
||||
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
|
||||
@@ -310,10 +313,12 @@ function M.generate_prompts(opts)
|
||||
end
|
||||
|
||||
if #history_messages == 0 then
|
||||
history_messages = vim.list_slice(opts.history_messages, #opts.history_messages - 1, #opts.history_messages)
|
||||
history_messages =
|
||||
vim.list_slice(cleaned_history_messages, #cleaned_history_messages - 1, #cleaned_history_messages)
|
||||
end
|
||||
|
||||
dropped_history_messages = vim.list_slice(opts.history_messages, 1, #opts.history_messages - #history_messages)
|
||||
dropped_history_messages =
|
||||
vim.list_slice(cleaned_history_messages, 1, #cleaned_history_messages - #history_messages)
|
||||
|
||||
-- prepend the history messages to the messages table
|
||||
vim.iter(history_messages):each(function(msg) table.insert(final_history_messages, msg) end)
|
||||
|
||||
@@ -38,6 +38,7 @@ One or more SEARCH/REPLACE blocks following this exact format:
|
||||
\`\`\`
|
||||
Critical rules:
|
||||
1. SEARCH content must match the associated file section to find EXACTLY:
|
||||
* Do not refer to the `diff` argument of the previous `replace_in_file` function call for SEARCH content matching, as it may have been modified. Always match from the latest file content in <selected_files> or from the `view` function call result.
|
||||
* Match character-for-character including whitespace, indentation, line endings
|
||||
* Include all comments, docstrings, etc.
|
||||
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
||||
|
||||
@@ -2311,22 +2311,23 @@ function Sidebar:create_input_container()
|
||||
---@param state AvanteLLMToolUseState
|
||||
local function on_tool_log(tool_id, tool_name, log, state)
|
||||
if state == "generating" then on_state_change("tool calling") end
|
||||
local tool_message = vim.iter(self.chat_history.messages):find(function(message)
|
||||
if message.message.role ~= "assistant" then return false end
|
||||
local tool_use_message = nil
|
||||
for idx = #self.chat_history.messages, 1, -1 do
|
||||
local message = self.chat_history.messages[idx]
|
||||
local content = message.message.content
|
||||
if type(content) ~= "table" then return false end
|
||||
if content[1].type ~= "tool_use" then return false end
|
||||
if content[1].id ~= tool_id then return false end
|
||||
return true
|
||||
end)
|
||||
if not tool_message then
|
||||
Utils.debug("tool_message not found", tool_id, tool_name)
|
||||
if type(content) == "table" and content[1].type == "tool_use" and content[1].id == tool_id then
|
||||
tool_use_message = message
|
||||
break
|
||||
end
|
||||
end
|
||||
if not tool_use_message then
|
||||
Utils.debug("tool_use message not found", tool_id, tool_name)
|
||||
return
|
||||
end
|
||||
local tool_use_logs = tool_message.tool_use_logs or {}
|
||||
local tool_use_logs = tool_use_message.tool_use_logs or {}
|
||||
local content = string.format("[%s]: %s", tool_name, log)
|
||||
table.insert(tool_use_logs, content)
|
||||
tool_message.tool_use_logs = tool_use_logs
|
||||
tool_use_message.tool_use_logs = tool_use_logs
|
||||
save_history()
|
||||
self:update_content("")
|
||||
end
|
||||
|
||||
@@ -1413,6 +1413,66 @@ function M.uuid()
|
||||
end)
|
||||
end
|
||||
|
||||
---@param message avante.HistoryMessage
|
||||
---@return boolean
|
||||
function M.is_tool_use_message(message)
|
||||
local content = message.message.content
|
||||
if type(content) == "string" then return false end
|
||||
if vim.islist(content) then
|
||||
for _, item in ipairs(content) do
|
||||
if item.type == "tool_use" then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param message avante.HistoryMessage
|
||||
---@return boolean
|
||||
function M.is_tool_result_message(message)
|
||||
local content = message.message.content
|
||||
if type(content) == "string" then return false end
|
||||
if vim.islist(content) then
|
||||
for _, item in ipairs(content) do
|
||||
if item.type == "tool_result" then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param message avante.HistoryMessage
|
||||
---@param messages avante.HistoryMessage[]
|
||||
---@return avante.HistoryMessage | nil
|
||||
function M.get_tool_use_message(message, messages)
|
||||
local content = message.message.content
|
||||
if type(content) == "string" then return nil end
|
||||
if vim.islist(content) then
|
||||
local tool_id = nil
|
||||
for _, item in ipairs(content) do
|
||||
if item.type == "tool_result" then
|
||||
tool_id = item.tool_use_id
|
||||
break
|
||||
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
|
||||
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_
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param message avante.HistoryMessage
|
||||
---@param messages avante.HistoryMessage[]
|
||||
---@return avante.HistoryMessage | nil
|
||||
@@ -1428,7 +1488,15 @@ function M.get_tool_result_message(message, messages)
|
||||
end
|
||||
end
|
||||
if not tool_id then return nil end
|
||||
for _, message_ in ipairs(messages) do
|
||||
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
|
||||
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_
|
||||
@@ -1469,36 +1537,48 @@ function M.message_content_item_to_lines(item, message, messages)
|
||||
local lines = {}
|
||||
local state = "generating"
|
||||
local hl = "AvanteStateSpinnerToolCalling"
|
||||
if message.state == "generated" then
|
||||
local tool_result_message = M.get_tool_result_message(message, messages)
|
||||
if tool_result_message then
|
||||
local tool_result = tool_result_message.message.content[1]
|
||||
if tool_result.is_error then
|
||||
state = "failed"
|
||||
hl = "AvanteStateSpinnerFailed"
|
||||
else
|
||||
state = "succeeded"
|
||||
hl = "AvanteStateSpinnerSucceeded"
|
||||
end
|
||||
local tool_result_message = M.get_tool_result_message(message, messages)
|
||||
if tool_result_message then
|
||||
local tool_result = tool_result_message.message.content[1]
|
||||
if tool_result.is_error then
|
||||
state = "failed"
|
||||
hl = "AvanteStateSpinnerFailed"
|
||||
else
|
||||
state = "succeeded"
|
||||
hl = "AvanteStateSpinnerSucceeded"
|
||||
end
|
||||
end
|
||||
table.insert(
|
||||
lines,
|
||||
Line:new({ { "╭─" }, { " " }, { string.format(" %s ", item.name), hl }, { string.format(" %s", state) } })
|
||||
)
|
||||
for idx, log in ipairs(message.tool_use_logs or {}) do
|
||||
local log_ = M.trim(log, { prefix = string.format("[%s]: ", item.name) })
|
||||
local lines_ = vim.split(log_, "\n")
|
||||
if idx ~= #(message.tool_use_logs or {}) then
|
||||
for _, line_ in ipairs(lines_) do
|
||||
table.insert(lines, Line:new({ { "│" }, { string.format(" %s", line_) } }))
|
||||
end
|
||||
else
|
||||
for idx_, line_ in ipairs(lines_) do
|
||||
if idx_ ~= #lines_ then
|
||||
if message.tool_use_logs then
|
||||
for idx, log in ipairs(message.tool_use_logs) do
|
||||
local log_ = M.trim(log, { prefix = string.format("[%s]: ", item.name) })
|
||||
local lines_ = vim.split(log_, "\n")
|
||||
if idx ~= #(message.tool_use_logs or {}) then
|
||||
for _, line_ in ipairs(lines_) do
|
||||
table.insert(lines, Line:new({ { "│" }, { string.format(" %s", line_) } }))
|
||||
end
|
||||
else
|
||||
for idx_, line_ in ipairs(lines_) do
|
||||
if idx_ ~= #lines_ then
|
||||
table.insert(lines, Line:new({ { "│" }, { string.format(" %s", line_) } }))
|
||||
else
|
||||
table.insert(lines, Line:new({ { "╰─" }, { string.format(" %s", line_) } }))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif tool_result_message then
|
||||
local tool_result = tool_result_message.message.content[1]
|
||||
if tool_result.content then
|
||||
local result_lines = vim.split(tool_result.content, "\n")
|
||||
for idx, line in ipairs(result_lines) do
|
||||
if idx ~= #result_lines then
|
||||
table.insert(lines, Line:new({ { "│" }, { string.format(" %s", line) } }))
|
||||
else
|
||||
table.insert(lines, Line:new({ { "╰─" }, { string.format(" %s", line_) } }))
|
||||
table.insert(lines, Line:new({ { "╰─" }, { string.format(" %s", line) } }))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user