feat(api): support native chat mode (#541)
Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
parent
a8ef7de7d8
commit
29e109e447
@ -1,4 +1,4 @@
|
|||||||
function avante#build(...) abort
|
function avante#build(...) abort
|
||||||
let l:source = get(a:, 1, v:false)
|
let l:source = get(a:, 1, v:false)
|
||||||
return join(luaeval("require('avante').build(_A)", l:source), "\n")
|
return join(luaeval("require('avante_lib').load()"),"\n",luaeval("require('avante.api').build(_A)", l:source), "\n")
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -73,9 +73,9 @@ M.build = function(opts)
|
|||||||
local output = stdout
|
local output = stdout
|
||||||
if #output == 0 then
|
if #output == 0 then
|
||||||
table.insert(output, "")
|
table.insert(output, "")
|
||||||
Utils.info("outputs: " .. output)
|
Utils.debug(output)
|
||||||
else
|
else
|
||||||
Utils.error("error: " .. stderr)
|
Utils.debug(stderr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@ -87,6 +87,7 @@ end
|
|||||||
---@class AskOptions
|
---@class AskOptions
|
||||||
---@field question? string optional questions
|
---@field question? string optional questions
|
||||||
---@field win? table<string, any> windows options similar to |nvim_open_win()|
|
---@field win? table<string, any> windows options similar to |nvim_open_win()|
|
||||||
|
---@field ask? boolean
|
||||||
|
|
||||||
---@param opts? AskOptions
|
---@param opts? AskOptions
|
||||||
M.ask = function(opts)
|
M.ask = function(opts)
|
||||||
|
@ -36,16 +36,25 @@ H.commands = function()
|
|||||||
---@type AskOptions
|
---@type AskOptions
|
||||||
local args = { question = nil, win = {} }
|
local args = { question = nil, win = {} }
|
||||||
local q_parts = {}
|
local q_parts = {}
|
||||||
|
local q_ask = nil
|
||||||
for _, arg in ipairs(opts.fargs) do
|
for _, arg in ipairs(opts.fargs) do
|
||||||
local value = arg:match("position=(%w+)")
|
local value = arg:match("position=(%w+)")
|
||||||
if value then
|
local ask = arg:match("ask=(%w+)")
|
||||||
|
if ask ~= nil then
|
||||||
|
q_ask = ask == "true"
|
||||||
|
elseif value then
|
||||||
args.win.position = value
|
args.win.position = value
|
||||||
else
|
else
|
||||||
table.insert(q_parts, arg)
|
table.insert(q_parts, arg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
args.question = #q_parts > 0 and table.concat(q_parts, " ") or nil
|
require("avante.api").ask(
|
||||||
require("avante.api").ask(args)
|
vim.tbl_deep_extend(
|
||||||
|
"force",
|
||||||
|
args,
|
||||||
|
{ ask = q_ask, question = #q_parts > 0 and table.concat(q_parts, " ") or nil }
|
||||||
|
)
|
||||||
|
)
|
||||||
end, {
|
end, {
|
||||||
desc = "avante: ask AI for code suggestions",
|
desc = "avante: ask AI for code suggestions",
|
||||||
nargs = "*",
|
nargs = "*",
|
||||||
@ -56,6 +65,7 @@ H.commands = function()
|
|||||||
---@param x string
|
---@param x string
|
||||||
vim.tbl_map(function(x) return "position=" .. x end, { "left", "right", "top", "bottom" })
|
vim.tbl_map(function(x) return "position=" .. x end, { "left", "right", "top", "bottom" })
|
||||||
)
|
)
|
||||||
|
vim.list_extend(candidates, vim.tbl_map(function(x) return "ask=" .. x end, { "true", "false" }))
|
||||||
return candidates
|
return candidates
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -283,6 +293,8 @@ M.toggle = { api = true }
|
|||||||
---@param opts? AskOptions
|
---@param opts? AskOptions
|
||||||
M.toggle_sidebar = function(opts)
|
M.toggle_sidebar = function(opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
if opts.ask == nil then opts.ask = true end
|
||||||
|
|
||||||
local sidebar = M.get()
|
local sidebar = M.get()
|
||||||
if not sidebar then
|
if not sidebar then
|
||||||
M._init(api.nvim_get_current_tabpage())
|
M._init(api.nvim_get_current_tabpage())
|
||||||
|
@ -29,6 +29,7 @@ local group = api.nvim_create_augroup("avante_llm", { clear = true })
|
|||||||
---@field memory_context string | nil
|
---@field memory_context string | nil
|
||||||
---
|
---
|
||||||
---@class StreamOptions: TemplateOptions
|
---@class StreamOptions: TemplateOptions
|
||||||
|
---@field ask boolean
|
||||||
---@field bufnr integer
|
---@field bufnr integer
|
||||||
---@field instructions string
|
---@field instructions string
|
||||||
---@field mode LlmMode
|
---@field mode LlmMode
|
||||||
@ -60,7 +61,7 @@ M.stream = function(opts)
|
|||||||
|
|
||||||
local template_opts = {
|
local template_opts = {
|
||||||
use_xml_format = Provider.use_xml_format,
|
use_xml_format = Provider.use_xml_format,
|
||||||
ask = true, -- TODO: add mode without ask instruction
|
ask = opts.ask, -- TODO: add mode without ask instruction
|
||||||
question = original_instructions,
|
question = original_instructions,
|
||||||
code_lang = opts.code_lang,
|
code_lang = opts.code_lang,
|
||||||
file_content = opts.file_content,
|
file_content = opts.file_content,
|
||||||
|
@ -395,6 +395,7 @@ function Selection:create_editing_input()
|
|||||||
|
|
||||||
Llm.stream({
|
Llm.stream({
|
||||||
bufnr = code_bufnr,
|
bufnr = code_bufnr,
|
||||||
|
ask = true,
|
||||||
file_content = code_content,
|
file_content = code_content,
|
||||||
code_lang = filetype,
|
code_lang = filetype,
|
||||||
selected_code = self.selection.content,
|
selected_code = self.selection.content,
|
||||||
|
@ -66,7 +66,7 @@ function Sidebar:reset()
|
|||||||
self.input = nil
|
self.input = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts? AskOptions
|
---@param opts AskOptions
|
||||||
function Sidebar:open(opts)
|
function Sidebar:open(opts)
|
||||||
local in_visual_mode = Utils.in_visual_mode() and self:in_code_win()
|
local in_visual_mode = Utils.in_visual_mode() and self:in_code_win()
|
||||||
if not self:is_open() then
|
if not self:is_open() then
|
||||||
@ -122,7 +122,7 @@ end
|
|||||||
|
|
||||||
function Sidebar:in_code_win() return self.code.winid == api.nvim_get_current_win() end
|
function Sidebar:in_code_win() return self.code.winid == api.nvim_get_current_win() end
|
||||||
|
|
||||||
---@param opts? table<string, any>
|
---@param opts AskOptions
|
||||||
function Sidebar:toggle(opts)
|
function Sidebar:toggle(opts)
|
||||||
local in_visual_mode = Utils.in_visual_mode() and self:in_code_win()
|
local in_visual_mode = Utils.in_visual_mode() and self:in_code_win()
|
||||||
if self:is_open() and not in_visual_mode then
|
if self:is_open() and not in_visual_mode then
|
||||||
@ -592,7 +592,9 @@ function Sidebar:render_result()
|
|||||||
self:render_header(self.result.winid, self.result.bufnr, header_text, Highlights.TITLE, Highlights.REVERSED_TITLE)
|
self:render_header(self.result.winid, self.result.bufnr, header_text, Highlights.TITLE, Highlights.REVERSED_TITLE)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Sidebar:render_input()
|
---@param ask? boolean
|
||||||
|
function Sidebar:render_input(ask)
|
||||||
|
if ask == nil then ask = true end
|
||||||
if not self.input or not self.input.bufnr or not api.nvim_buf_is_valid(self.input.bufnr) then return end
|
if not self.input or not self.input.bufnr or not api.nvim_buf_is_valid(self.input.bufnr) then return end
|
||||||
|
|
||||||
local filetype = api.nvim_get_option_value("filetype", { buf = self.code.bufnr })
|
local filetype = api.nvim_get_option_value("filetype", { buf = self.code.bufnr })
|
||||||
@ -614,11 +616,13 @@ function Sidebar:render_input()
|
|||||||
|
|
||||||
local code_file_fullpath = api.nvim_buf_get_name(self.code.bufnr)
|
local code_file_fullpath = api.nvim_buf_get_name(self.code.bufnr)
|
||||||
local code_filename = fn.fnamemodify(code_file_fullpath, ":t")
|
local code_filename = fn.fnamemodify(code_file_fullpath, ":t")
|
||||||
local header_text = string.format(" Chat with %s %s (<Tab>: switch focus)", icon, code_filename)
|
local header_text =
|
||||||
|
string.format(" %s %s %s (<Tab>: switch focus)", ask and "Ask" or "Chat with", icon, code_filename)
|
||||||
|
|
||||||
if self.code.selection ~= nil then
|
if self.code.selection ~= nil then
|
||||||
header_text = string.format(
|
header_text = string.format(
|
||||||
" Chat with %s %s(%d:%d) (<Tab>: switch focus)",
|
" %s %s %s(%d:%d) (<Tab>: switch focus)",
|
||||||
|
ask and "Ask" or "Chat with",
|
||||||
icon,
|
icon,
|
||||||
code_filename,
|
code_filename,
|
||||||
self.code.selection.range.start.line,
|
self.code.selection.range.start.line,
|
||||||
@ -664,7 +668,8 @@ function Sidebar:render_selected_code()
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Sidebar:on_mount()
|
---@param opts AskOptions
|
||||||
|
function Sidebar:on_mount(opts)
|
||||||
self:refresh_winids()
|
self:refresh_winids()
|
||||||
|
|
||||||
api.nvim_set_option_value("wrap", Config.windows.wrap, { win = self.result.winid })
|
api.nvim_set_option_value("wrap", Config.windows.wrap, { win = self.result.winid })
|
||||||
@ -795,7 +800,7 @@ function Sidebar:on_mount()
|
|||||||
})
|
})
|
||||||
|
|
||||||
self:render_result()
|
self:render_result()
|
||||||
self:render_input()
|
self:render_input(opts.ask)
|
||||||
self:render_selected_code()
|
self:render_selected_code()
|
||||||
|
|
||||||
self.augroup = api.nvim_create_augroup("avante_sidebar_" .. self.id .. self.result.winid, { clear = true })
|
self.augroup = api.nvim_create_augroup("avante_sidebar_" .. self.id .. self.result.winid, { clear = true })
|
||||||
@ -1148,7 +1153,8 @@ end
|
|||||||
|
|
||||||
local hint_window = nil
|
local hint_window = nil
|
||||||
|
|
||||||
function Sidebar:create_input()
|
---@param opts AskOptions
|
||||||
|
function Sidebar:create_input(opts)
|
||||||
if self.input then self.input:unmount() end
|
if self.input then self.input:unmount() end
|
||||||
|
|
||||||
if not self.code.bufnr or not api.nvim_buf_is_valid(self.code.bufnr) then return end
|
if not self.code.bufnr or not api.nvim_buf_is_valid(self.code.bufnr) then return end
|
||||||
@ -1266,6 +1272,7 @@ function Sidebar:create_input()
|
|||||||
|
|
||||||
Llm.stream({
|
Llm.stream({
|
||||||
bufnr = self.code.bufnr,
|
bufnr = self.code.bufnr,
|
||||||
|
ask = opts.ask,
|
||||||
file_content = content_with_line_numbers,
|
file_content = content_with_line_numbers,
|
||||||
code_lang = filetype,
|
code_lang = filetype,
|
||||||
selected_code = selected_code_content_with_line_numbers,
|
selected_code = selected_code_content_with_line_numbers,
|
||||||
@ -1396,7 +1403,7 @@ function Sidebar:create_input()
|
|||||||
local width = #hint_text
|
local width = #hint_text
|
||||||
|
|
||||||
-- Set the floating window options
|
-- Set the floating window options
|
||||||
local opts = {
|
local win_opts = {
|
||||||
relative = "win",
|
relative = "win",
|
||||||
win = self.input.winid,
|
win = self.input.winid,
|
||||||
width = width,
|
width = width,
|
||||||
@ -1410,7 +1417,7 @@ function Sidebar:create_input()
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- Create the floating window
|
-- Create the floating window
|
||||||
hint_window = api.nvim_open_win(buf, false, opts)
|
hint_window = api.nvim_open_win(buf, false, win_opts)
|
||||||
|
|
||||||
api.nvim_win_set_hl_ns(hint_window, Highlights.hint_ns)
|
api.nvim_win_set_hl_ns(hint_window, Highlights.hint_ns)
|
||||||
end
|
end
|
||||||
@ -1461,14 +1468,14 @@ function Sidebar:create_input()
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
self:refresh_winids()
|
|
||||||
|
|
||||||
api.nvim_create_autocmd("User", {
|
api.nvim_create_autocmd("User", {
|
||||||
pattern = "AvanteInputSubmitted",
|
pattern = "AvanteInputSubmitted",
|
||||||
callback = function(ev)
|
callback = function(ev)
|
||||||
if ev.data and ev.data.request then handle_submit(ev.data.request) end
|
if ev.data and ev.data.request then handle_submit(ev.data.request) end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self:refresh_winids()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Sidebar:get_selected_code_size()
|
function Sidebar:get_selected_code_size()
|
||||||
@ -1485,9 +1492,8 @@ function Sidebar:get_selected_code_size()
|
|||||||
return selected_code_size
|
return selected_code_size
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param opts? AskOptions
|
---@param opts AskOptions
|
||||||
function Sidebar:render(opts)
|
function Sidebar:render(opts)
|
||||||
opts = opts or {}
|
|
||||||
local chat_history = Path.history.load(self.code.bufnr)
|
local chat_history = Path.history.load(self.code.bufnr)
|
||||||
|
|
||||||
local get_position = function()
|
local get_position = function()
|
||||||
@ -1546,7 +1552,7 @@ function Sidebar:render(opts)
|
|||||||
self:close()
|
self:close()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
self:create_input()
|
self:create_input(opts)
|
||||||
|
|
||||||
self:update_content_with_history(chat_history)
|
self:update_content_with_history(chat_history)
|
||||||
|
|
||||||
@ -1557,7 +1563,7 @@ function Sidebar:render(opts)
|
|||||||
|
|
||||||
self:create_selected_code()
|
self:create_selected_code()
|
||||||
|
|
||||||
self:on_mount()
|
self:on_mount(opts)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
@ -107,6 +107,7 @@ function Suggestion:suggest()
|
|||||||
|
|
||||||
Llm.stream({
|
Llm.stream({
|
||||||
bufnr = bufnr,
|
bufnr = bufnr,
|
||||||
|
ask = true,
|
||||||
file_content = code_content,
|
file_content = code_content,
|
||||||
code_lang = filetype,
|
code_lang = filetype,
|
||||||
instructions = vim.json.encode(doc),
|
instructions = vim.json.encode(doc),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user