fix: refine tools (#1706)
* fix: refine tools * fix: missing break line * fix: view a in-context file * fix: remove create_file tests
This commit is contained in:
@@ -61,4 +61,15 @@ function M.has_permission_to_access(abs_path)
|
|||||||
return not M.is_ignored(abs_path)
|
return not M.is_ignored(abs_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param path string
|
||||||
|
---@return boolean
|
||||||
|
function M.already_in_context(path)
|
||||||
|
local sidebar = require("avante").get()
|
||||||
|
if sidebar and sidebar.file_selector then
|
||||||
|
local rel_path = Utils.uniform_path(path)
|
||||||
|
return vim.tbl_contains(sidebar.file_selector.selected_filepaths, rel_path)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@@ -276,24 +276,6 @@ function M.write_global_file(opts, on_log, on_complete)
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@type AvanteLLMToolFunc<{ rel_path: string }>
|
|
||||||
function M.create_file(opts, on_log)
|
|
||||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
|
||||||
if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end
|
|
||||||
if on_log then on_log("path: " .. abs_path) end
|
|
||||||
---create directory if it doesn't exist
|
|
||||||
local dir = Path:new(abs_path):parent()
|
|
||||||
if not dir:exists() then dir:mkdir({ parents = true }) end
|
|
||||||
---create file if it doesn't exist
|
|
||||||
if not dir:joinpath(opts.rel_path):exists() then
|
|
||||||
local file = io.open(abs_path, "w")
|
|
||||||
if not file then return false, "file not found: " .. abs_path end
|
|
||||||
file:close()
|
|
||||||
end
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }>
|
---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }>
|
||||||
function M.rename_file(opts, on_log, on_complete)
|
function M.rename_file(opts, on_log, on_complete)
|
||||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||||
@@ -1008,33 +990,6 @@ M._tools = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name = "create_file",
|
|
||||||
description = "Create a new file in current project scope",
|
|
||||||
param = {
|
|
||||||
type = "table",
|
|
||||||
fields = {
|
|
||||||
{
|
|
||||||
name = "rel_path",
|
|
||||||
description = "Relative path to the file in current project scope",
|
|
||||||
type = "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
returns = {
|
|
||||||
{
|
|
||||||
name = "success",
|
|
||||||
description = "True if the file was created successfully, false otherwise",
|
|
||||||
type = "boolean",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name = "error",
|
|
||||||
description = "Error message if the file was not created successfully",
|
|
||||||
type = "string",
|
|
||||||
optional = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name = "rename_file",
|
name = "rename_file",
|
||||||
description = "Rename a file in current project scope",
|
description = "Rename a file in current project scope",
|
||||||
|
|||||||
@@ -75,6 +75,10 @@ M.returns = {
|
|||||||
---@type AvanteLLMToolFunc<{ path: string, view_range?: { start_line: integer, end_line: integer } }>
|
---@type AvanteLLMToolFunc<{ path: string, view_range?: { start_line: integer, end_line: integer } }>
|
||||||
function M.func(opts, on_log, on_complete)
|
function M.func(opts, on_log, on_complete)
|
||||||
if not on_complete then return false, "on_complete not provided" end
|
if not on_complete then return false, "on_complete not provided" end
|
||||||
|
if Helpers.already_in_context(opts.path) then
|
||||||
|
on_complete(nil, "Ooooops! This file is already in the context! Why you are trying to read it again?")
|
||||||
|
return
|
||||||
|
end
|
||||||
local abs_path = Helpers.get_abs_path(opts.path)
|
local abs_path = Helpers.get_abs_path(opts.path)
|
||||||
if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end
|
if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end
|
||||||
if on_log then on_log("path: " .. abs_path) end
|
if on_log then on_log("path: " .. abs_path) end
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ end
|
|||||||
---@field is_searching boolean
|
---@field is_searching boolean
|
||||||
---@field is_replacing boolean
|
---@field is_replacing boolean
|
||||||
---@field is_thinking boolean
|
---@field is_thinking boolean
|
||||||
|
---@field waiting_for_breakline boolean
|
||||||
---@field last_search_tag_start_line integer
|
---@field last_search_tag_start_line integer
|
||||||
---@field last_replace_tag_start_line integer
|
---@field last_replace_tag_start_line integer
|
||||||
---@field last_think_tag_start_line integer
|
---@field last_think_tag_start_line integer
|
||||||
@@ -278,6 +279,7 @@ local function transform_result_content(selected_files, result_content, prev_fil
|
|||||||
|
|
||||||
local current_filepath
|
local current_filepath
|
||||||
|
|
||||||
|
local waiting_for_breakline = false
|
||||||
local i = 1
|
local i = 1
|
||||||
while true do
|
while true do
|
||||||
if i > #result_lines then break end
|
if i > #result_lines then break end
|
||||||
@@ -414,6 +416,7 @@ local function transform_result_content(selected_files, result_content, prev_fil
|
|||||||
if search_start_tag_idx_in_transformed_lines > 0 then
|
if search_start_tag_idx_in_transformed_lines > 0 then
|
||||||
transformed_lines = vim.list_slice(transformed_lines, 1, search_start_tag_idx_in_transformed_lines - 1)
|
transformed_lines = vim.list_slice(transformed_lines, 1, search_start_tag_idx_in_transformed_lines - 1)
|
||||||
end
|
end
|
||||||
|
waiting_for_breakline = true
|
||||||
vim.list_extend(transformed_lines, {
|
vim.list_extend(transformed_lines, {
|
||||||
string.format("Replace lines: %d-%d", start_line, end_line),
|
string.format("Replace lines: %d-%d", start_line, end_line),
|
||||||
string.format("```%s", match_filetype),
|
string.format("```%s", match_filetype),
|
||||||
@@ -456,6 +459,7 @@ local function transform_result_content(selected_files, result_content, prev_fil
|
|||||||
is_thinking = false
|
is_thinking = false
|
||||||
last_think_tag_end_line = i
|
last_think_tag_end_line = i
|
||||||
end
|
end
|
||||||
|
waiting_for_breakline = false
|
||||||
table.insert(transformed_lines, line_content)
|
table.insert(transformed_lines, line_content)
|
||||||
::continue::
|
::continue::
|
||||||
i = i + 1
|
i = i + 1
|
||||||
@@ -465,6 +469,7 @@ local function transform_result_content(selected_files, result_content, prev_fil
|
|||||||
return {
|
return {
|
||||||
current_filepath = current_filepath,
|
current_filepath = current_filepath,
|
||||||
content = table.concat(transformed_lines, "\n"),
|
content = table.concat(transformed_lines, "\n"),
|
||||||
|
waiting_for_breakline = waiting_for_breakline,
|
||||||
is_searching = is_searching,
|
is_searching = is_searching,
|
||||||
is_replacing = is_replacing,
|
is_replacing = is_replacing,
|
||||||
is_thinking = is_thinking,
|
is_thinking = is_thinking,
|
||||||
@@ -2645,6 +2650,7 @@ function Sidebar:create_input_container(opts)
|
|||||||
self:update_content(content_prefix .. generating_text)
|
self:update_content(content_prefix .. generating_text)
|
||||||
|
|
||||||
local original_response = ""
|
local original_response = ""
|
||||||
|
local waiting_for_breakline = false
|
||||||
local transformed_response = ""
|
local transformed_response = ""
|
||||||
local displayed_response = ""
|
local displayed_response = ""
|
||||||
local current_path = ""
|
local current_path = ""
|
||||||
@@ -2702,7 +2708,15 @@ function Sidebar:create_input_container(opts)
|
|||||||
|
|
||||||
local selected_files = self.file_selector:get_selected_files_contents()
|
local selected_files = self.file_selector:get_selected_files_contents()
|
||||||
|
|
||||||
local transformed = transform_result_content(selected_files, transformed_response .. chunk, current_path)
|
local transformed_response_
|
||||||
|
if waiting_for_breakline and chunk and chunk:sub(1, 1) ~= "\n" then
|
||||||
|
transformed_response_ = transformed_response .. "\n" .. chunk
|
||||||
|
else
|
||||||
|
transformed_response_ = transformed_response .. chunk
|
||||||
|
end
|
||||||
|
|
||||||
|
local transformed = transform_result_content(selected_files, transformed_response_, current_path)
|
||||||
|
waiting_for_breakline = transformed.waiting_for_breakline
|
||||||
transformed_response = transformed.content
|
transformed_response = transformed.content
|
||||||
if transformed.current_filepath and transformed.current_filepath ~= "" then
|
if transformed.current_filepath and transformed.current_filepath ~= "" then
|
||||||
current_path = transformed.current_filepath
|
current_path = transformed.current_filepath
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ Don't directly search for code context in historical messages. Instead, prioriti
|
|||||||
Tools Usage Guide:
|
Tools Usage Guide:
|
||||||
- You have access to tools, but only use them when necessary. If a tool is not required, respond as normal.
|
- You have access to tools, but only use them when necessary. If a tool is not required, respond as normal.
|
||||||
- Please DON'T be so aggressive in using tools, as many tasks can be better completed without tools.
|
- Please DON'T be so aggressive in using tools, as many tasks can be better completed without tools.
|
||||||
- Files will be provided to you as context through <selected_files> tag!
|
- Files will be provided to you as context through <file> tag!
|
||||||
- Before using the `view` tool each time, always repeatedly check whether the file is already in the <selected_files> tag. If it is already there, do not use the `view` tool, just read the file content directly from the <selected_files> tag.
|
- Before using the `view` tool each time, always repeatedly check whether the file is already in the <file> tag. If it is already there, do not use the `view` tool, just read the file content directly from the <file> tag.
|
||||||
- If you use the `view` tool when file content is already provided in the <selected_files> tag, you will be fired!
|
- If you use the `view` tool when file content is already provided in the <file> tag, you will be fired!
|
||||||
- If the `rag_search` tool exists, prioritize using it to do the search!
|
- If the `rag_search` tool exists, prioritize using it to do the search!
|
||||||
- If the `rag_search` tool exists, only use tools like `search_keyword` `search_files` `view` `list_files` etc when absolutely necessary!
|
- If the `rag_search` tool exists, only use tools like `search_keyword` `search_files` `view` `list_files` etc when absolutely necessary!
|
||||||
- Keep the `query` parameter of `rag_search` tool as concise as possible! Try to keep it within five English words!
|
- Keep the `query` parameter of `rag_search` tool as concise as possible! Try to keep it within five English words!
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ local view = require("avante.llm_tools.view")
|
|||||||
local bash = require("avante.llm_tools.bash")
|
local bash = require("avante.llm_tools.bash")
|
||||||
|
|
||||||
LlmToolHelpers.confirm = function(msg, cb) return cb(true) end
|
LlmToolHelpers.confirm = function(msg, cb) return cb(true) end
|
||||||
|
LlmToolHelpers.already_in_context = function(path) return false end
|
||||||
|
|
||||||
describe("llm_tools", function()
|
describe("llm_tools", function()
|
||||||
local test_dir = "/tmp/test_llm_tools"
|
local test_dir = "/tmp/test_llm_tools"
|
||||||
@@ -99,18 +100,6 @@ describe("llm_tools", function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("create_file", function()
|
|
||||||
it("should create new file", function()
|
|
||||||
LlmTools.create_file({ rel_path = "new_file.txt" }, nil, function(success, err)
|
|
||||||
assert.is_nil(err)
|
|
||||||
assert.is_true(success)
|
|
||||||
|
|
||||||
local file_exists = io.open(test_dir .. "/new_file.txt", "r") ~= nil
|
|
||||||
assert.is_true(file_exists)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
describe("create_dir", function()
|
describe("create_dir", function()
|
||||||
it("should create new directory", function()
|
it("should create new directory", function()
|
||||||
LlmTools.create_dir({ rel_path = "new_dir" }, nil, function(success, err)
|
LlmTools.create_dir({ rel_path = "new_dir" }, nil, function(success, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user