fix: better sidebar (#1603)

* fix: better sidebar

* feat: better msg history

* fix: tests
This commit is contained in:
yetone
2025-03-17 01:40:05 +08:00
committed by GitHub
parent f60f150a21
commit 6e77da83c1
17 changed files with 870 additions and 319 deletions

View File

@@ -59,6 +59,8 @@ function M:parse_messages(opts)
---@type AvanteClaudeMessage[]
local messages = {}
local provider_conf, _ = P.parse_config(self)
---@type {idx: integer, length: integer}[]
local messages_with_length = {}
for idx, message in ipairs(opts.messages) do
@@ -76,15 +78,46 @@ function M:parse_messages(opts)
end
for idx, message in ipairs(opts.messages) do
local content_items = message.content
local message_content = {}
if type(content_items) == "string" then
table.insert(message_content, {
type = "text",
text = message.content,
cache_control = top_two[idx] and { type = "ephemeral" } or nil,
})
elseif type(content_items) == "table" then
---@cast content_items AvanteLLMMessageContentItem[]
for _, item in ipairs(content_items) do
if type(item) == "string" then
table.insert(
message_content,
{ type = "text", text = item, cache_control = top_two[idx] and { type = "ephemeral" } or nil }
)
elseif type(item) == "table" and item.type == "text" then
table.insert(
message_content,
{ type = "text", text = item.text, cache_control = top_two[idx] and { type = "ephemeral" } or nil }
)
elseif type(item) == "table" and item.type == "image" then
table.insert(message_content, { type = "image", source = item.source })
elseif not provider_conf.disable_tools and type(item) == "table" and item.type == "tool_use" then
table.insert(message_content, { type = "tool_use", name = item.name, id = item.id, input = item.input })
elseif not provider_conf.disable_tools and type(item) == "table" and item.type == "tool_result" then
table.insert(
message_content,
{ type = "tool_result", tool_use_id = item.tool_use_id, content = item.content, is_error = item.is_error }
)
elseif type(item) == "table" and item.type == "thinking" then
table.insert(message_content, { type = "thinking", thinking = item.thinking, signature = item.signature })
elseif type(item) == "table" and item.type == "redacted_thinking" then
table.insert(message_content, { type = "redacted_thinking", data = item.data })
end
end
end
table.insert(messages, {
role = self.role_map[message.role],
content = {
{
type = "text",
text = message.content,
cache_control = top_two[idx] and { type = "ephemeral" } or nil,
},
},
content = message_content,
})
end

View File

@@ -35,9 +35,36 @@ function M:parse_messages(opts)
end
end
prev_role = role
table.insert(contents, { role = M.role_map[role] or role, parts = {
{ text = message.content },
} })
local parts = {}
local content_items = message.content
if type(content_items) == "string" then
table.insert(parts, { text = content_items })
elseif type(content_items) == "table" then
---@cast content_items AvanteLLMMessageContentItem[]
for _, item in ipairs(content_items) do
if type(item) == "string" then
table.insert(parts, { text = item })
elseif type(item) == "table" and item.type == "text" then
table.insert(parts, { text = item.text })
elseif type(item) == "table" and item.type == "image" then
table.insert(parts, {
inline_data = {
mime_type = "image/png",
data = item.source.data,
},
})
elseif type(item) == "table" and item.type == "tool_use" then
table.insert(parts, { text = item.name })
elseif type(item) == "table" and item.type == "tool_result" then
table.insert(parts, { text = item.content })
elseif type(item) == "table" and item.type == "thinking" then
table.insert(parts, { text = item.thinking })
elseif type(item) == "table" and item.type == "redacted_thinking" then
table.insert(parts, { text = item.data })
end
end
end
table.insert(contents, { role = M.role_map[role] or role, parts = parts })
end)
if Clipboard.support_paste_image() and opts.image_paths then

View File

@@ -81,9 +81,54 @@ function M:parse_messages(opts)
table.insert(messages, { role = "system", content = opts.system_prompt })
end
vim
.iter(opts.messages)
:each(function(msg) table.insert(messages, { role = M.role_map[msg.role], content = msg.content }) end)
vim.iter(opts.messages):each(function(msg)
if type(msg.content) == "string" then
table.insert(messages, { role = self.role_map[msg.role], content = msg.content })
else
local content = {}
local tool_calls = {}
local tool_results = {}
for _, item in ipairs(msg.content) do
if type(item) == "string" then
table.insert(content, { type = "text", text = item })
elseif item.type == "text" then
table.insert(content, { type = "text", text = item.text })
elseif item.type == "image" then
table.insert(content, {
type = "image_url",
image_url = {
url = "data:" .. item.source.media_type .. ";" .. item.source.type .. "," .. item.source.data,
},
})
elseif item.type == "tool_use" then
table.insert(tool_calls, {
id = item.id,
type = "function",
["function"] = { name = item.name, arguments = vim.json.encode(item.input) },
})
elseif item.type == "tool_result" then
table.insert(
tool_results,
{ tool_call_id = item.tool_use_id, content = item.is_error and "Error: " .. item.content or item.content }
)
end
end
table.insert(messages, { role = self.role_map[msg.role], content = content })
if not provider_conf.disable_tools then
if #tool_calls > 0 then
table.insert(messages, { role = self.role_map["assistant"], tool_calls = tool_calls })
end
if #tool_results > 0 then
for _, tool_result in ipairs(tool_results) do
table.insert(
messages,
{ role = "tool", tool_call_id = tool_result.tool_call_id, content = tool_result.content or "" }
)
end
end
end
end
end)
if Config.behaviour.support_paste_from_clipboard and opts.image_paths and #opts.image_paths > 0 then
local message_content = messages[#messages].content