2024-08-17 16:04:40 -04:00
local api = vim.api
2024-08-15 19:04:15 +08:00
local curl = require ( " plenary.curl " )
2024-08-17 15:14:30 +08:00
local Utils = require ( " avante.utils " )
local Config = require ( " avante.config " )
2024-08-22 01:48:40 -04:00
local P = require ( " avante.providers " )
2024-08-18 15:03:25 -04:00
2024-08-18 22:20:29 -04:00
---@class avante.LLM
2024-08-17 15:14:30 +08:00
local M = { }
2024-08-15 19:04:15 +08:00
2024-08-18 22:20:29 -04:00
M.CANCEL_PATTERN = " AvanteLLMEscape "
2024-08-18 15:03:25 -04:00
------------------------------Prompt and type------------------------------
2024-08-22 01:48:40 -04:00
---@alias AvanteSystemPrompt string
2024-08-15 19:04:15 +08:00
local system_prompt = [ [
You are an excellent programming expert .
] ]
2024-08-22 01:48:40 -04:00
---@alias AvanteBasePrompt string
2024-08-15 19:04:15 +08:00
local base_user_prompt = [ [
Your primary task is to suggest code modifications with precise line number ranges . Follow these instructions meticulously :
1. Carefully analyze the original code , paying close attention to its structure and line numbers . Line numbers start from 1 and include ALL lines , even empty ones .
2. When suggesting modifications :
2024-08-17 22:29:05 +08:00
a . Use the language in the question to reply . If there are non - English parts in the question , use the language of those parts .
b . Explain why the change is necessary or beneficial .
c . Provide the exact code snippet to be replaced using this format :
2024-08-15 19:04:15 +08:00
Replace lines : { { start_line } } - { { end_line } }
` ` ` { { language } }
{ { suggested_code } }
` ` `
2024-08-18 02:46:19 +08:00
3. Crucial guidelines for suggested code snippets :
- Only apply the change ( s ) suggested by the most recent assistant message ( before your generation ) .
- Do not make any unrelated changes to the code .
- Produce a valid full rewrite of the entire original file without skipping any lines . Do not be lazy !
- Do not arbitrarily delete pre - existing comments / empty Lines .
- Do not omit large parts of the original file for no reason .
- Do not omit any needed changes from the requisite messages / code blocks .
- If there is a clicked code block , bias towards just applying that ( and applying other changes implied ) .
2024-08-18 02:52:27 +08:00
- Please keep your suggested code changes minimal , and do not include irrelevant lines in the code snippet .
2024-08-18 02:46:19 +08:00
4. Crucial guidelines for line numbers :
2024-08-19 00:05:13 +08:00
- The content regarding line numbers MUST strictly follow the format " Replace lines: {{start_line}}-{{end_line}} " . Do not be lazy !
2024-08-15 19:04:15 +08:00
- The range { { start_line } } - { { end_line } } is INCLUSIVE . Both start_line and end_line are included in the replacement .
2024-08-18 04:47:47 +08:00
- Count EVERY line , including empty lines and comments lines , comments . Do not be lazy !
2024-08-15 19:04:15 +08:00
- For single - line changes , use the same number for start and end lines .
- For multi - line changes , ensure the range covers ALL affected lines , from the very first to the very last .
- Double - check that your line numbers align perfectly with the original code structure .
5. Final check :
- Review all suggestions , ensuring each line number is correct , especially the start_line and end_line .
- Confirm that no unrelated code is accidentally modified or deleted .
- Verify that the start_line and end_line correctly include all intended lines for replacement .
- Perform a final alignment check to ensure your line numbers haven ' t shifted, especially the start_line.
- Double - check that your line numbers align perfectly with the original code structure .
2024-08-18 02:52:27 +08:00
- Do not show the full content after these modifications .
2024-08-15 19:04:15 +08:00
Remember : Accurate line numbers are CRITICAL . The range start_line to end_line must include ALL lines to be replaced , from the very first to the very last . Double - check every range before finalizing your response , paying special attention to the start_line to ensure it hasn ' t shifted down. Ensure that your line numbers perfectly match the original code structure without any overall shift.
] ]
2024-08-22 14:46:08 +08:00
local group = api.nvim_create_augroup ( " AvanteLLM " , { clear = true } )
2024-08-18 15:03:25 -04:00
local active_job = nil
---@param question string
---@param code_lang string
---@param code_content string
---@param selected_content_content string | nil
2024-08-19 06:11:02 -04:00
---@param on_chunk AvanteChunkParser
---@param on_complete AvanteCompleteParser
2024-08-18 22:20:29 -04:00
M.stream = function ( question , code_lang , code_content , selected_content_content , on_chunk , on_complete )
2024-08-18 15:03:25 -04:00
local provider = Config.provider
2024-08-22 01:48:40 -04:00
---@type AvantePromptOptions
2024-08-18 22:20:29 -04:00
local code_opts = {
2024-08-22 01:48:40 -04:00
base_prompt = base_user_prompt ,
system_prompt = system_prompt ,
2024-08-18 15:03:25 -04:00
question = question ,
code_lang = code_lang ,
code_content = code_content ,
selected_code_content = selected_content_content ,
2024-08-18 22:20:29 -04:00
}
2024-08-22 01:48:40 -04:00
---@type string
local current_event_state = nil
2024-08-18 22:20:29 -04:00
2024-08-22 01:48:40 -04:00
---@type AvanteProviderFunctor
local Provider = P [ provider ]
2024-08-18 22:20:29 -04:00
2024-08-22 01:48:40 -04:00
---@type AvanteHandlerOptions
local handler_opts = { on_chunk = on_chunk , on_complete = on_complete }
---@type AvanteCurlOutput
2024-08-24 17:52:38 -04:00
local spec = Provider.parse_curl_args ( Provider , code_opts )
2024-08-18 15:03:25 -04:00
---@param line string
2024-08-22 01:48:40 -04:00
local function parse_stream_data ( line )
2024-08-18 15:03:25 -04:00
local event = line : match ( " ^event: (.+)$ " )
if event then
2024-08-19 06:11:02 -04:00
current_event_state = event
2024-08-18 15:03:25 -04:00
return
end
local data_match = line : match ( " ^data: (.+)$ " )
if data_match then
2024-08-22 01:48:40 -04:00
Provider.parse_response ( data_match , current_event_state , handler_opts )
2024-08-18 15:03:25 -04:00
end
end
if active_job then
active_job : shutdown ( )
active_job = nil
2024-08-15 19:04:15 +08:00
end
2024-08-18 15:03:25 -04:00
active_job = curl.post ( spec.url , {
headers = spec.headers ,
2024-08-22 01:48:40 -04:00
proxy = spec.proxy ,
insecure = spec.insecure ,
2024-08-18 15:03:25 -04:00
body = vim.json . encode ( spec.body ) ,
stream = function ( err , data , _ )
2024-08-15 19:04:15 +08:00
if err then
on_complete ( err )
return
end
if not data then
return
end
2024-08-18 15:03:25 -04:00
vim.schedule ( function ( )
2024-08-22 01:48:40 -04:00
if Config.options [ provider ] == nil and Provider.parse_stream_data ~= nil then
if Provider.parse_response ~= nil then
2024-08-20 07:54:58 -04:00
Utils.warn (
" parse_stream_data and parse_response_data are mutually exclusive, and thus parse_response_data will be ignored. Make sure that you handle the incoming data correctly. " ,
{ once = true }
)
end
2024-08-22 01:48:40 -04:00
Provider.parse_stream_data ( data , handler_opts )
2024-08-20 07:54:58 -04:00
else
2024-08-23 09:36:40 -04:00
if Provider.parse_stream_data ~= nil then
Provider.parse_stream_data ( data , handler_opts )
else
parse_stream_data ( data )
end
2024-08-20 07:54:58 -04:00
end
2024-08-18 15:03:25 -04:00
end )
end ,
on_error = function ( err )
on_complete ( err )
end ,
2024-08-25 21:26:19 -04:00
callback = function ( result )
if result.status >= 400 then
if Provider.on_error then
Provider.on_error ( result )
else
Utils.error ( " API request failed with status " .. result.status , { once = true , title = " Avante " } )
end
end
2024-08-18 15:03:25 -04:00
active_job = nil
end ,
} )
api.nvim_create_autocmd ( " User " , {
group = group ,
pattern = M.CANCEL_PATTERN ,
callback = function ( )
if active_job then
active_job : shutdown ( )
2024-08-19 05:40:57 -04:00
Utils.debug ( " LLM request cancelled " , { title = " Avante " } )
2024-08-18 15:03:25 -04:00
active_job = nil
2024-08-15 19:04:15 +08:00
end
end ,
} )
2024-08-18 15:03:25 -04:00
return active_job
2024-08-15 19:04:15 +08:00
end
2024-08-20 07:43:53 -04:00
return M