feat: streaming diff (#2107)
This commit is contained in:
@@ -3,6 +3,7 @@ local Clipboard = require("avante.clipboard")
|
||||
local P = require("avante.providers")
|
||||
local Config = require("avante.config")
|
||||
local HistoryMessage = require("avante.history_message")
|
||||
local JsonParser = require("avante.libs.jsonparser")
|
||||
|
||||
---@class AvanteProviderFunctor
|
||||
local M = {}
|
||||
@@ -199,6 +200,7 @@ function M:parse_response(ctx, data_stream, event_state, opts)
|
||||
end
|
||||
end
|
||||
if content_block.type == "tool_use" and opts.on_messages_add then
|
||||
local incomplete_json = JsonParser.parse(content_block.input_json)
|
||||
local msg = HistoryMessage:new({
|
||||
role = "assistant",
|
||||
content = {
|
||||
@@ -206,7 +208,7 @@ function M:parse_response(ctx, data_stream, event_state, opts)
|
||||
type = "tool_use",
|
||||
name = content_block.name,
|
||||
id = content_block.id,
|
||||
input = {},
|
||||
input = incomplete_json or {},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
@@ -214,6 +216,7 @@ function M:parse_response(ctx, data_stream, event_state, opts)
|
||||
})
|
||||
content_block.uuid = msg.uuid
|
||||
opts.on_messages_add({ msg })
|
||||
opts.on_stop({ reason = "tool_use", streaming_tool_use = true })
|
||||
end
|
||||
elseif event_state == "content_block_delta" then
|
||||
local ok, jsn = pcall(vim.json.decode, data_stream)
|
||||
|
||||
@@ -4,6 +4,7 @@ local Clipboard = require("avante.clipboard")
|
||||
local Providers = require("avante.providers")
|
||||
local HistoryMessage = require("avante.history_message")
|
||||
local XMLParser = require("avante.libs.xmlparser")
|
||||
local JsonParser = require("avante.libs.jsonparser")
|
||||
local Prompts = require("avante.utils.prompts")
|
||||
local LlmTools = require("avante.llm_tools")
|
||||
|
||||
@@ -236,6 +237,7 @@ function M:add_text_message(ctx, text, state, opts)
|
||||
local msgs = { msg }
|
||||
local stream_parser = XMLParser.createStreamParser()
|
||||
stream_parser:addData(ctx.content)
|
||||
local has_tool_use = false
|
||||
local xml = stream_parser:getAllElements()
|
||||
if xml then
|
||||
local new_content_list = {}
|
||||
@@ -262,8 +264,8 @@ function M:add_text_message(ctx, text, state, opts)
|
||||
end
|
||||
if not vim.tbl_contains(llm_tool_names, item._name) then goto continue end
|
||||
local ok, input = pcall(vim.json.decode, item._text)
|
||||
if not ok then input = {} end
|
||||
if not ok and item.children and #item.children > 0 then
|
||||
input = {}
|
||||
for _, item_ in ipairs(item.children) do
|
||||
local ok_, input_ = pcall(vim.json.decode, item_._text)
|
||||
if ok_ and input_ then
|
||||
@@ -273,7 +275,7 @@ function M:add_text_message(ctx, text, state, opts)
|
||||
end
|
||||
end
|
||||
end
|
||||
if input then
|
||||
if next(input) ~= nil then
|
||||
local tool_use_id = Utils.uuid()
|
||||
local msg_ = HistoryMessage:new({
|
||||
role = "assistant",
|
||||
@@ -296,12 +298,14 @@ function M:add_text_message(ctx, text, state, opts)
|
||||
name = item._name,
|
||||
input_json = input,
|
||||
}
|
||||
has_tool_use = true
|
||||
end
|
||||
if #new_content_list > 0 then msg.message.content = table.concat(new_content_list, "\n") end
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
if opts.on_messages_add then opts.on_messages_add(msgs) end
|
||||
if has_tool_use and state == "generating" then opts.on_stop({ reason = "tool_use", streaming_tool_use = true }) end
|
||||
end
|
||||
|
||||
function M:add_thinking_message(ctx, text, state, opts)
|
||||
@@ -325,8 +329,7 @@ function M:add_thinking_message(ctx, text, state, opts)
|
||||
end
|
||||
|
||||
function M:add_tool_use_message(tool_use, state, opts)
|
||||
local jsn = nil
|
||||
if state == "generated" then jsn = vim.json.decode(tool_use.input_json) end
|
||||
local jsn = JsonParser.parse(tool_use.input_json)
|
||||
local msg = HistoryMessage:new({
|
||||
role = "assistant",
|
||||
content = {
|
||||
@@ -344,6 +347,7 @@ function M:add_tool_use_message(tool_use, state, opts)
|
||||
tool_use.uuid = msg.uuid
|
||||
tool_use.state = state
|
||||
if opts.on_messages_add then opts.on_messages_add({ msg }) end
|
||||
if state == "generating" then opts.on_stop({ reason = "tool_use", streaming_tool_use = true }) end
|
||||
end
|
||||
|
||||
function M:parse_response(ctx, data_stream, _, opts)
|
||||
|
||||
Reference in New Issue
Block a user