Signed-off-by: Aaron Pham <contact@aarnphm.xyz>
This commit is contained in:
@@ -4,6 +4,7 @@ local curl = require("plenary.curl")
|
||||
|
||||
local Utils = require("avante.utils")
|
||||
local Config = require("avante.config")
|
||||
local Path = require("avante.path")
|
||||
local P = require("avante.providers")
|
||||
|
||||
---@class avante.LLM
|
||||
@@ -13,136 +14,32 @@ M.CANCEL_PATTERN = "AvanteLLMEscape"
|
||||
|
||||
------------------------------Prompt and type------------------------------
|
||||
|
||||
---@alias AvanteSystemPrompt string
|
||||
local system_prompt = [[
|
||||
You are an excellent programming expert.
|
||||
]]
|
||||
|
||||
-- Copy from: https://github.com/Doriandarko/claude-engineer/blob/15c94963cbf9d01b8ae7bbb5d42d7025aa0555d5/main.py#L276
|
||||
---@alias AvanteBasePrompt string
|
||||
local planning_mode_user_prompt_tpl = [[
|
||||
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:
|
||||
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. If an image is provided, make sure to use the image in conjunction with the code snippet.
|
||||
d. Provide the exact code snippet to be replaced using this format:
|
||||
|
||||
Replace lines: {{start_line}}-{{end_line}}
|
||||
```{{language}}
|
||||
{{suggested_code}}
|
||||
```
|
||||
|
||||
3. Crucial guidelines for suggested code snippets:
|
||||
- The content regarding line numbers MUST strictly follow the format "Replace lines: {{start_line}}-{{end_line}}". Do not be lazy!
|
||||
- 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).
|
||||
- Please keep your suggested code changes minimal, and do not include irrelevant lines in the code snippet.
|
||||
- Maintain the SAME indentation in the returned code as in the source code
|
||||
|
||||
4. Crucial guidelines for line numbers:
|
||||
- The range {{start_line}}-{{end_line}} is INCLUSIVE. Both start_line and end_line are included in the replacement.
|
||||
- Count EVERY line, including empty lines and comments lines, comments. Do not be lazy!
|
||||
- Use the same number for start and end lines for single-line changes.
|
||||
- For multi-line changes, ensure the range covers ALL affected lines, from first to 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.
|
||||
- DO NOT return the complete modified code with applied changes!
|
||||
|
||||
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 your line numbers match the original code structure without any overall shift.
|
||||
]]
|
||||
|
||||
local editing_mode_user_prompt_tpl = [[
|
||||
Your task is to modify the provided code according to the user's request. Follow these instructions precisely:
|
||||
|
||||
1. Return ONLY the complete modified code.
|
||||
|
||||
2. Do not include any explanations, comments, or line numbers in your response.
|
||||
|
||||
3. Ensure the returned code is complete and can be directly used as a replacement for the original code.
|
||||
|
||||
4. Preserve the original structure, indentation, and formatting of the code as much as possible.
|
||||
|
||||
5. Do not omit any parts of the code, even if they are unchanged.
|
||||
|
||||
6. Maintain the SAME indentation in the returned code as in the source code
|
||||
|
||||
7. Do NOT include three backticks: ```
|
||||
|
||||
8. Only return the new code snippets to be updated, DO NOT return the entire file content.
|
||||
|
||||
Remember: Your response should contain ONLY the modified code, ready to be used as a direct replacement for the original file.
|
||||
]]
|
||||
|
||||
local suggesting_mode_user_prompt_tpl = [[
|
||||
Your task is to suggest code modifications at the cursor position. Follow these instructions meticulously:
|
||||
|
||||
1. Carefully analyze the original code, paying close attention to its structure and the cursor position.
|
||||
|
||||
2. You must follow this json format when suggesting modifications:
|
||||
|
||||
[
|
||||
{
|
||||
"row": ${row},
|
||||
"col": ${column},
|
||||
"content": "Your suggested code here"
|
||||
}
|
||||
]
|
||||
|
||||
3. When suggesting suggested code:
|
||||
- Each element in the returned list is a COMPLETE and INDEPENDENT code snippet.
|
||||
- MUST be a valid json format. Don't be lazy!
|
||||
- Only return the new code to be inserted.
|
||||
- Your returned code should not overlap with the original code in any way. Don't be lazy!
|
||||
- Please strictly check the code around the position and ensure that the complete code after insertion is correct. Don't be lazy!
|
||||
- Do not return the entire file content or any surrounding code.
|
||||
- Do not include any explanations, comments, or line numbers in your response.
|
||||
- Ensure the suggested code fits seamlessly with the existing code structure and indentation.
|
||||
- If there are no recommended modifications, return an empty list.
|
||||
|
||||
Remember: Return ONLY the suggested code snippet, without any additional formatting or explanation.
|
||||
]]
|
||||
|
||||
local group = api.nvim_create_augroup("avante_llm", { clear = true })
|
||||
|
||||
---@class StreamOptions
|
||||
---@field file_content string
|
||||
---@alias LlmMode "planning" | "editing" | "suggesting"
|
||||
---
|
||||
---@class TemplateOptions
|
||||
---@field use_xml_format boolean
|
||||
---@field ask boolean
|
||||
---@field question string
|
||||
---@field code_lang string
|
||||
---@field file_content string
|
||||
---@field selected_code string | nil
|
||||
---@field instructions string
|
||||
---@field project_context string | nil
|
||||
---@field memory_context string | nil
|
||||
---@field full_file_contents_context string | nil
|
||||
---@field mode "planning" | "editing" | "suggesting"
|
||||
---
|
||||
---@class StreamOptions: TemplateOptions
|
||||
---@field bufnr integer
|
||||
---@field instructions string
|
||||
---@field mode LlmMode
|
||||
---@field on_chunk AvanteChunkParser
|
||||
---@field on_complete AvanteCompleteParser
|
||||
|
||||
---@param opts StreamOptions
|
||||
M.stream = function(opts)
|
||||
local mode = opts.mode or "planning"
|
||||
local provider = Config.provider
|
||||
|
||||
local user_prompt_tpl = planning_mode_user_prompt_tpl
|
||||
|
||||
if mode == "editing" then
|
||||
user_prompt_tpl = editing_mode_user_prompt_tpl
|
||||
elseif mode == "suggesting" then
|
||||
user_prompt_tpl = suggesting_mode_user_prompt_tpl
|
||||
end
|
||||
---@type AvanteProviderFunctor
|
||||
local Provider = P[Config.provider]
|
||||
|
||||
-- Check if the instructions contains an image path
|
||||
local image_paths = {}
|
||||
@@ -159,52 +56,30 @@ M.stream = function(opts)
|
||||
original_instructions = table.concat(lines, "\n")
|
||||
end
|
||||
|
||||
local user_prompts = {}
|
||||
Path.prompts.initialize(Path.prompts.get(opts.bufnr))
|
||||
local user_prompt = Path.prompts.render(mode, {
|
||||
use_xml_format = Provider.use_xml_format,
|
||||
ask = true, -- TODO: add mode without ask instruction
|
||||
question = original_instructions,
|
||||
code_lang = opts.code_lang,
|
||||
file_content = opts.file_content,
|
||||
selected_code = opts.selected_code,
|
||||
project_context = opts.project_context,
|
||||
memory_context = opts.memory_context,
|
||||
})
|
||||
|
||||
if opts.selected_code and opts.selected_code ~= "" then
|
||||
table.insert(
|
||||
user_prompts,
|
||||
string.format("<code_context>```%s\n%s\n```</code_context>", opts.code_lang, opts.file_content)
|
||||
)
|
||||
table.insert(user_prompts, string.format("<code>```%s\n%s\n```</code>", opts.code_lang, opts.selected_code))
|
||||
else
|
||||
table.insert(user_prompts, string.format("<code>```%s\n%s\n```</code>", opts.code_lang, opts.file_content))
|
||||
end
|
||||
|
||||
if opts.project_context then
|
||||
table.insert(user_prompts, string.format("<project_context>%s</project_context>", opts.project_context))
|
||||
end
|
||||
|
||||
if opts.memory_context then
|
||||
table.insert(user_prompts, string.format("<memory_context>%s</memory_context>", opts.memory_context))
|
||||
end
|
||||
|
||||
if opts.full_file_contents_context then
|
||||
table.insert(
|
||||
user_prompts,
|
||||
string.format("<full_file_contents_context>%s</full_file_contents_context>", opts.full_file_contents_context)
|
||||
)
|
||||
end
|
||||
|
||||
table.insert(user_prompts, "<question>" .. original_instructions .. "</question>")
|
||||
|
||||
local user_prompt = user_prompt_tpl:gsub("%${(.-)}", opts)
|
||||
|
||||
table.insert(user_prompts, user_prompt)
|
||||
Utils.debug(user_prompt)
|
||||
|
||||
---@type AvantePromptOptions
|
||||
local code_opts = {
|
||||
system_prompt = system_prompt,
|
||||
user_prompts = user_prompts,
|
||||
system_prompt = Config.system_prompt,
|
||||
user_prompt = user_prompt,
|
||||
image_paths = image_paths,
|
||||
}
|
||||
|
||||
---@type string
|
||||
local current_event_state = nil
|
||||
|
||||
---@type AvanteProviderFunctor
|
||||
local Provider = P[provider]
|
||||
|
||||
---@type AvanteHandlerOptions
|
||||
local handler_opts = { on_chunk = opts.on_chunk, on_complete = opts.on_complete }
|
||||
---@type AvanteCurlOutput
|
||||
@@ -244,7 +119,7 @@ M.stream = function(opts)
|
||||
return
|
||||
end
|
||||
vim.schedule(function()
|
||||
if Config.options[provider] == nil and Provider.parse_stream_data ~= nil then
|
||||
if Config.options[Config.provider] == nil and Provider.parse_stream_data ~= nil then
|
||||
if Provider.parse_response ~= nil then
|
||||
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.",
|
||||
|
||||
Reference in New Issue
Block a user