fix: refine tools (#2229)
This commit is contained in:
@@ -95,21 +95,20 @@ function M.write_global_file(opts, on_log, on_complete)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
function M.rename_file(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
---@type AvanteLLMToolFunc<{ source_path: string, destination_path: string }>
|
||||
function M.move_path(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.source_path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end
|
||||
if not Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end
|
||||
if not Path:new(abs_path):is_file() then return false, "Path is not a file: " .. abs_path end
|
||||
local new_abs_path = Helpers.get_abs_path(opts.new_path)
|
||||
if not Path:new(abs_path):exists() then return false, "The source path not found: " .. abs_path end
|
||||
local new_abs_path = Helpers.get_abs_path(opts.destination_path)
|
||||
if on_log then on_log(abs_path .. " -> " .. new_abs_path) end
|
||||
if not Helpers.has_permission_to_access(new_abs_path) then
|
||||
return false, "No permission to access path: " .. new_abs_path
|
||||
end
|
||||
if Path:new(new_abs_path):exists() then return false, "File already exists: " .. new_abs_path end
|
||||
if Path:new(new_abs_path):exists() then return false, "The destination path already exists: " .. new_abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
Helpers.confirm(
|
||||
"Are you sure you want to rename the file: " .. abs_path .. " to: " .. new_abs_path,
|
||||
"Are you sure you want to move the path: " .. abs_path .. " to: " .. new_abs_path,
|
||||
function(ok, reason)
|
||||
if not ok then
|
||||
on_complete(false, "User declined, reason: " .. (reason or "unknown"))
|
||||
@@ -121,35 +120,61 @@ function M.rename_file(opts, on_log, on_complete)
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
function M.copy_file(opts, on_log)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
---@type AvanteLLMToolFunc<{ source_path: string, destination_path: string }>
|
||||
function M.copy_path(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.source_path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return false, "No permission to access path: " .. abs_path end
|
||||
if not Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end
|
||||
if not Path:new(abs_path):is_file() then return false, "Path is not a file: " .. abs_path end
|
||||
local new_abs_path = Helpers.get_abs_path(opts.new_path)
|
||||
if not Path:new(abs_path):exists() then return false, "The source path not found: " .. abs_path end
|
||||
local new_abs_path = Helpers.get_abs_path(opts.destination_path)
|
||||
if not Helpers.has_permission_to_access(new_abs_path) then
|
||||
return false, "No permission to access path: " .. new_abs_path
|
||||
end
|
||||
if Path:new(new_abs_path):exists() then return false, "File already exists: " .. new_abs_path end
|
||||
if on_log then on_log("Copying file: " .. abs_path .. " to " .. new_abs_path) end
|
||||
Path:new(new_abs_path):write(Path:new(abs_path):read())
|
||||
return true, nil
|
||||
if Path:new(new_abs_path):exists() then return false, "The destination path already exists: " .. new_abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
Helpers.confirm(
|
||||
"Are you sure you want to copy the path: " .. abs_path .. " to: " .. new_abs_path,
|
||||
function(ok, reason)
|
||||
if not ok then
|
||||
on_complete(false, "User declined, reason: " .. (reason or "unknown"))
|
||||
return
|
||||
end
|
||||
if on_log then on_log("Copying path: " .. abs_path .. " to " .. new_abs_path) end
|
||||
if Path:new(abs_path):is_dir() then
|
||||
Path:new(new_abs_path):mkdir({ parents = true })
|
||||
for _, entry in ipairs(Path:new(abs_path):list()) do
|
||||
local new_entry_path = Path:new(new_abs_path):joinpath(entry)
|
||||
if entry:match("^%.") then goto continue end
|
||||
if Path:new(new_entry_path):exists() then
|
||||
if Path:new(new_entry_path):is_dir() then
|
||||
Path:new(new_entry_path):rmdir()
|
||||
else
|
||||
Path:new(new_entry_path):unlink()
|
||||
end
|
||||
end
|
||||
vim.fn.mkdir(new_entry_path, "p")
|
||||
Path:new(new_entry_path):write(Path:new(abs_path):joinpath(entry):read())
|
||||
::continue::
|
||||
end
|
||||
else
|
||||
Path:new(new_abs_path):write(Path:new(abs_path):read())
|
||||
end
|
||||
on_complete(true, nil)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.delete_file(opts, on_log, on_complete)
|
||||
function M.delete_path(opts, on_log, on_complete)
|
||||
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 Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end
|
||||
if not Path:new(abs_path):is_file() then return false, "Path is not a file: " .. abs_path end
|
||||
if not Path:new(abs_path):exists() then return false, "Path not found: " .. abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
Helpers.confirm("Are you sure you want to delete the file: " .. abs_path, function(ok, reason)
|
||||
Helpers.confirm("Are you sure you want to delete the path: " .. abs_path, function(ok, reason)
|
||||
if not ok then
|
||||
on_complete(false, "User declined, reason: " .. (reason or "unknown"))
|
||||
return
|
||||
end
|
||||
if on_log then on_log("Deleting file: " .. abs_path) end
|
||||
if on_log then on_log("Deleting path: " .. abs_path) end
|
||||
os.remove(abs_path)
|
||||
on_complete(true, nil)
|
||||
end)
|
||||
@@ -172,50 +197,6 @@ function M.create_dir(opts, on_log, on_complete)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
function M.rename_dir(opts, on_log, on_complete)
|
||||
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 Path:new(abs_path):exists() then return false, "Directory not found: " .. abs_path end
|
||||
if not Path:new(abs_path):is_dir() then return false, "Path is not a directory: " .. abs_path end
|
||||
local new_abs_path = Helpers.get_abs_path(opts.new_path)
|
||||
if not Helpers.has_permission_to_access(new_abs_path) then
|
||||
return false, "No permission to access path: " .. new_abs_path
|
||||
end
|
||||
if Path:new(new_abs_path):exists() then return false, "Directory already exists: " .. new_abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
Helpers.confirm(
|
||||
"Are you sure you want to rename directory " .. abs_path .. " to " .. new_abs_path .. "?",
|
||||
function(ok, reason)
|
||||
if not ok then
|
||||
on_complete(false, "User declined, reason: " .. (reason or "unknown"))
|
||||
return
|
||||
end
|
||||
if on_log then on_log("Renaming directory: " .. abs_path .. " to " .. new_abs_path) end
|
||||
os.rename(abs_path, new_abs_path)
|
||||
on_complete(true, nil)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.delete_dir(opts, on_log, on_complete)
|
||||
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 Path:new(abs_path):exists() then return false, "Directory not found: " .. abs_path end
|
||||
if not Path:new(abs_path):is_dir() then return false, "Path is not a directory: " .. abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
Helpers.confirm("Are you sure you want to delete the directory: " .. abs_path, function(ok, reason)
|
||||
if not ok then
|
||||
on_complete(false, "User declined, reason: " .. (reason or "unknown"))
|
||||
return
|
||||
end
|
||||
if on_log then on_log("Deleting directory: " .. abs_path) end
|
||||
os.remove(abs_path)
|
||||
on_complete(true, nil)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ query: string }>
|
||||
function M.web_search(opts, on_log)
|
||||
local provider_type = Config.web_search_engine.provider
|
||||
@@ -896,25 +877,42 @@ M._tools = {
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "rename_file",
|
||||
description = "Rename a file in current project scope",
|
||||
name = "move_path",
|
||||
description = [[Moves or rename a file or directory in the project, and returns confirmation that the move succeeded.
|
||||
If the source and destination directories are the same, but the filename is different, this performs a rename. Otherwise, it performs a move.
|
||||
|
||||
This tool should be used when it's desirable to move or rename a file or directory without changing its contents at all.]],
|
||||
param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "path",
|
||||
description = "Relative path to the file in current project scope",
|
||||
name = "source_path",
|
||||
description = [[The source path of the file or directory to move/rename.
|
||||
|
||||
<example>
|
||||
If the project has the following files:
|
||||
|
||||
- directory1/a/something.txt
|
||||
- directory2/a/things.txt
|
||||
- directory3/a/other.txt
|
||||
|
||||
You can move the first file by providing a source_path of "directory1/a/something.txt"
|
||||
</example>]],
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "new_path",
|
||||
description = "New relative path for the file",
|
||||
name = "destination_path",
|
||||
description = [[The destination path where the file or directory should be moved/renamed to. If the paths are the same except for the filename, then this will be a rename.
|
||||
|
||||
<example>
|
||||
To move "directory1/a/something.txt" to "directory2/b/renamed.txt", provide a destination_path of "directory2/b/renamed.txt"
|
||||
</example>]],
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the file in current project scope",
|
||||
new_path = "New relative path for the file",
|
||||
source_path = "The source path of the file or directory to move/rename",
|
||||
destination_path = "The destination path where the file or directory should be moved/renamed to",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
@@ -932,19 +930,81 @@ M._tools = {
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "delete_file",
|
||||
description = "Delete a file in current project scope",
|
||||
name = "copy_path",
|
||||
description = [[Copies a file or directory from the project to a new location, and returns confirmation that the copy succeeded.
|
||||
|
||||
This tool should be used when it's desirable to copy a file or directory without changing its contents at all.]],
|
||||
param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "source_path",
|
||||
description = [[The source path of the file or directory to copy.
|
||||
|
||||
<example>
|
||||
If the project has the following files:
|
||||
|
||||
- directory1/a/something.txt
|
||||
- directory2/a/things.txt
|
||||
- directory3/a/other.txt
|
||||
|
||||
You can copy the first file by providing a source_path of "directory1/a/something.txt"
|
||||
</example>]],
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "destination_path",
|
||||
description = [[The destination path where the file or directory should be copied to.
|
||||
|
||||
<example>
|
||||
To copy "directory1/a/something.txt" to "directory2/b/copied.txt", provide a destination_path of "directory2/b/copied.txt"
|
||||
</example>]],
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
source_path = "The source path of the file or directory to copy",
|
||||
destination_path = "The destination path where the file or directory should be copied to",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "success",
|
||||
description = "True if the file was copied successfully, false otherwise",
|
||||
type = "boolean",
|
||||
},
|
||||
{
|
||||
name = "error",
|
||||
description = "Error message if the file was not copied successfully",
|
||||
type = "string",
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "delete_path",
|
||||
description = "Deletes the file or directory (and the directory's contents, recursively) at the specified path in the project, and returns confirmation of the deletion.",
|
||||
param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "path",
|
||||
description = "Relative path to the file in current project scope",
|
||||
description = [[The path of the file or directory to delete.
|
||||
<example>
|
||||
If the project has the following files:
|
||||
|
||||
- directory1/a/something.txt
|
||||
- directory2/a/things.txt
|
||||
- directory3/a/other.txt
|
||||
|
||||
You can delete the first file by providing a path of "directory1/a/something.txt"
|
||||
</example>
|
||||
]],
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the file in current project scope",
|
||||
path = "Relative path to the file or directory in the current project scope",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
@@ -991,72 +1051,7 @@ M._tools = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "rename_dir",
|
||||
description = "Rename a directory in current project scope",
|
||||
param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "new_path",
|
||||
description = "New relative path for the directory",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
new_path = "New relative path for the directory",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "success",
|
||||
description = "True if the directory was renamed successfully, false otherwise",
|
||||
type = "boolean",
|
||||
},
|
||||
{
|
||||
name = "error",
|
||||
description = "Error message if the directory was not renamed successfully",
|
||||
type = "string",
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "delete_dir",
|
||||
description = "Delete a directory in current project scope",
|
||||
param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
name = "success",
|
||||
description = "True if the directory was deleted successfully, false otherwise",
|
||||
type = "boolean",
|
||||
},
|
||||
{
|
||||
name = "error",
|
||||
description = "Error message if the directory was not deleted successfully",
|
||||
type = "string",
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
require("avante.llm_tools.thinking"),
|
||||
require("avante.llm_tools.get_diagnostics"),
|
||||
require("avante.llm_tools.bash"),
|
||||
require("avante.llm_tools.attempt_completion"),
|
||||
@@ -1188,8 +1183,6 @@ M.run_python = M.python
|
||||
---@return string | nil result
|
||||
---@return string | nil error
|
||||
function M.process_tool_use(tools, tool_use, on_log, on_complete, session_ctx)
|
||||
-- Utils.debug("use tool", tool_use.name, tool_use.input_json)
|
||||
|
||||
-- Check if execution is already cancelled
|
||||
if Helpers.is_cancelled then
|
||||
Utils.debug("Tool execution cancelled before starting: " .. tool_use.name)
|
||||
|
||||
Reference in New Issue
Block a user