feat: ReAct tool calling (#2104)
This commit is contained in:
@@ -32,6 +32,10 @@ M.param = {
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
result = "The result of the task. Formulate this result in a way that is final and does not require further input from the user. Don't end your result with questions or offers for further assistance.",
|
||||
command = "A CLI command to execute to show a live demo of the result to the user. For example, use `open index.html` to display a created html website, or `open localhost:3000` to display a locally running development server. But DO NOT use commands like `echo` or `cat` that merely print text. This command should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -183,7 +183,7 @@ M.param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory, as cwd",
|
||||
type = "string",
|
||||
},
|
||||
@@ -193,6 +193,10 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory, as cwd",
|
||||
command = "Command to run",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
@@ -210,9 +214,9 @@ M.returns = {
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, command: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, command: string }>
|
||||
function M.func(opts, on_log, on_complete, session_ctx)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 Path:new(abs_path):exists() then return false, "Path not found: " .. abs_path end
|
||||
if on_log then on_log("command: " .. opts.command) end
|
||||
|
||||
@@ -49,6 +49,9 @@ M.param = {
|
||||
},
|
||||
},
|
||||
required = { "prompt" },
|
||||
usage = {
|
||||
prompt = "The task for the agent to perform",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -19,6 +19,9 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "The path to the file in the current project scope",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -18,11 +18,15 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory, as cwd",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
pattern = "Glob pattern",
|
||||
path = "Relative path to the project directory, as cwd",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
@@ -40,9 +44,9 @@ M.returns = {
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, pattern: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, pattern: string }>
|
||||
function M.func(opts, on_log, on_complete, session_ctx)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return "", "No permission to access path: " .. abs_path end
|
||||
if on_log then on_log("path: " .. abs_path) end
|
||||
if on_log then on_log("pattern: " .. opts.pattern) end
|
||||
|
||||
@@ -15,7 +15,7 @@ M.param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
@@ -44,6 +44,13 @@ M.param = {
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
query = "Query to search for",
|
||||
case_sensitive = "Whether to search case sensitively",
|
||||
include_pattern = "Glob pattern to include files",
|
||||
exclude_pattern = "Glob pattern to exclude files",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
@@ -61,9 +68,9 @@ M.returns = {
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, query: string, case_sensitive?: boolean, include_pattern?: string, exclude_pattern?: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, query: string, case_sensitive?: boolean, include_pattern?: string, exclude_pattern?: string }>
|
||||
function M.func(opts, on_log)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return "", "No permission to access path: " .. abs_path end
|
||||
if not Path:new(abs_path):exists() then return "", "No such file or directory: " .. abs_path end
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ local Helpers = require("avante.llm_tools.helpers")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.read_file_toplevel_symbols(opts, on_log)
|
||||
local RepoMap = require("avante.repo_map")
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return "", "No permission to access path: " .. abs_path end
|
||||
if on_log then on_log("path: " .. abs_path) end
|
||||
if not Path:new(abs_path):exists() then return "", "File does not exists: " .. abs_path end
|
||||
@@ -121,13 +121,13 @@ function M.write_global_file(opts, on_log, on_complete)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
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.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_rel_path)
|
||||
local new_abs_path = Helpers.get_abs_path(opts.new_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
|
||||
@@ -147,13 +147,13 @@ function M.rename_file(opts, on_log, on_complete)
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
function M.copy_file(opts, on_log)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 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_rel_path)
|
||||
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
|
||||
@@ -163,9 +163,9 @@ function M.copy_file(opts, on_log)
|
||||
return true, nil
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.delete_file(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 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
|
||||
@@ -181,9 +181,9 @@ function M.delete_file(opts, on_log, on_complete)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.create_dir(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 Path:new(abs_path):exists() then return false, "Directory already exists: " .. abs_path end
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
@@ -198,13 +198,13 @@ function M.create_dir(opts, on_log, on_complete)
|
||||
end)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, new_rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, new_path: string }>
|
||||
function M.rename_dir(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 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_rel_path)
|
||||
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
|
||||
@@ -224,9 +224,9 @@ function M.rename_dir(opts, on_log, on_complete)
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string }>
|
||||
---@type AvanteLLMToolFunc<{ path: string }>
|
||||
function M.delete_dir(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_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 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
|
||||
@@ -552,9 +552,9 @@ function M.rag_search(opts, on_log, on_complete)
|
||||
)
|
||||
end
|
||||
|
||||
---@type AvanteLLMToolFunc<{ code: string, rel_path: string, container_image?: string }>
|
||||
---@type AvanteLLMToolFunc<{ code: string, path: string, container_image?: string }>
|
||||
function M.python(opts, on_log, on_complete)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return nil, "No permission to access path: " .. abs_path end
|
||||
if not Path:new(abs_path):exists() then return nil, "Path not found: " .. abs_path end
|
||||
if on_log then on_log("cwd: " .. abs_path) end
|
||||
@@ -634,6 +634,18 @@ function M.get_tools(user_input, history_messages)
|
||||
:totable()
|
||||
end
|
||||
|
||||
function M.get_tool_names()
|
||||
local custom_tools = Config.custom_tools
|
||||
if type(custom_tools) == "function" then custom_tools = custom_tools() end
|
||||
---@type AvanteLLMTool[]
|
||||
local unfiltered_tools = vim.list_extend(vim.list_extend({}, M._tools), custom_tools)
|
||||
local tool_names = {}
|
||||
for _, tool in ipairs(unfiltered_tools) do
|
||||
table.insert(tool_names, tool.name)
|
||||
end
|
||||
return tool_names
|
||||
end
|
||||
|
||||
---@type AvanteLLMTool[]
|
||||
M._tools = {
|
||||
require("avante.llm_tools.replace_in_file"),
|
||||
@@ -652,6 +664,9 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
query = "Query to search",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -679,11 +694,15 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory, as cwd",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
code = "Python code to run",
|
||||
path = "Relative path to the project directory, as cwd",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -711,6 +730,9 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
scope = "Scope for the git diff (e.g. specific files or directories)",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -744,6 +766,10 @@ M._tools = {
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
message = "Commit message to use",
|
||||
scope = "Scope for staging files (e.g. specific files or directories)",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -768,11 +794,14 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the file in current project scope",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the file in current project scope",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -790,7 +819,7 @@ M._tools = {
|
||||
},
|
||||
require("avante.llm_tools.str_replace"),
|
||||
require("avante.llm_tools.view"),
|
||||
require("avante.llm_tools.create"),
|
||||
require("avante.llm_tools.write_to_file"),
|
||||
require("avante.llm_tools.insert"),
|
||||
require("avante.llm_tools.undo_edit"),
|
||||
{
|
||||
@@ -820,6 +849,9 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
abs_path = "Absolute path to the file in global scope",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -867,6 +899,10 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
abs_path = "The path to the file in the current project scope",
|
||||
content = "The content to write to the file",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -889,16 +925,20 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the file in current project scope",
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "new_rel_path",
|
||||
name = "new_path",
|
||||
description = "New relative path for the file",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the file in current project scope",
|
||||
new_path = "New relative path for the file",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -921,11 +961,14 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the file in current project scope",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the file in current project scope",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -948,11 +991,14 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -975,16 +1021,20 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "new_rel_path",
|
||||
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 = {
|
||||
{
|
||||
@@ -1007,11 +1057,14 @@ M._tools = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -1042,6 +1095,9 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
query = "Query to search",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
@@ -1069,6 +1125,9 @@ M._tools = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
url = "Url to fetch markdown from",
|
||||
},
|
||||
},
|
||||
returns = {
|
||||
{
|
||||
|
||||
@@ -32,6 +32,11 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "The path to the file to modify",
|
||||
insert_line = "The line number after which to insert the text (0 for beginning of file)",
|
||||
new_str = "The text to insert",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -14,7 +14,7 @@ M.param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "rel_path",
|
||||
name = "path",
|
||||
description = "Relative path to the project directory",
|
||||
type = "string",
|
||||
},
|
||||
@@ -24,6 +24,10 @@ M.param = {
|
||||
type = "integer",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "Relative path to the project directory",
|
||||
max_depth = "Maximum depth of the directory",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
@@ -41,9 +45,9 @@ M.returns = {
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ rel_path: string, max_depth?: integer }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, max_depth?: integer }>
|
||||
function M.func(opts, on_log)
|
||||
local abs_path = Helpers.get_abs_path(opts.rel_path)
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
if not Helpers.has_permission_to_access(abs_path) then return "", "No permission to access path: " .. abs_path end
|
||||
if on_log then on_log("path: " .. abs_path) end
|
||||
if on_log then on_log("max depth: " .. tostring(opts.max_depth)) end
|
||||
|
||||
@@ -16,6 +16,8 @@ M.name = "replace_in_file"
|
||||
M.description =
|
||||
"Request to replace sections of content in an existing file using SEARCH/REPLACE blocks that define exact changes to specific parts of the file. This tool should be used when you need to make targeted changes to specific parts of a file."
|
||||
|
||||
-- function M.enabled() return Config.provider:match("ollama") == nil end
|
||||
|
||||
---@type AvanteLLMToolParam
|
||||
M.param = {
|
||||
type = "table",
|
||||
@@ -57,6 +59,10 @@ One or more SEARCH/REPLACE blocks following this exact format:
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "File path here",
|
||||
diff = "Search and replace blocks here",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
local Path = require("plenary.path")
|
||||
local Utils = require("avante.utils")
|
||||
local Base = require("avante.llm_tools.base")
|
||||
local Helpers = require("avante.llm_tools.helpers")
|
||||
local Diff = require("avante.diff")
|
||||
local Config = require("avante.config")
|
||||
|
||||
---@class AvanteLLMTool
|
||||
@@ -13,6 +9,7 @@ M.name = "str_replace"
|
||||
M.description =
|
||||
"The str_replace tool allows you to replace a specific string in a file with a new string. This is used for making precise edits."
|
||||
|
||||
-- function M.enabled() return Config.provider:match("ollama") ~= nil end
|
||||
function M.enabled() return false end
|
||||
|
||||
---@type AvanteLLMToolParam
|
||||
@@ -35,6 +32,11 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "File path here",
|
||||
old_str = "old str here",
|
||||
new_str = "new str here",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -22,6 +22,9 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "The path to the file whose last edit should be undone",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
|
||||
@@ -39,23 +39,22 @@ M.param = {
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "view_range",
|
||||
description = "The range of the file to view. This parameter only applies when viewing files, not directories.",
|
||||
type = "object",
|
||||
name = "start_line",
|
||||
description = "The start line of the view range, 1-indexed",
|
||||
type = "integer",
|
||||
optional = true,
|
||||
fields = {
|
||||
{
|
||||
name = "start_line",
|
||||
description = "The start line of the range, 1-indexed",
|
||||
type = "integer",
|
||||
},
|
||||
{
|
||||
name = "end_line",
|
||||
description = "The end line of the range, 1-indexed, and -1 for the end line means read to the end of the file",
|
||||
type = "integer",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "end_line",
|
||||
description = "The end line of the view range, 1-indexed, and -1 for the end line means read to the end of the file",
|
||||
type = "integer",
|
||||
optional = true,
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "The path to the file in the current project scope",
|
||||
start_line = "The start line of the view range, 1-indexed",
|
||||
end_line = "The end line of the view range, 1-indexed, and -1 for the end line means read to the end of the file",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -74,7 +73,7 @@ M.returns = {
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string, view_range?: { start_line: integer, end_line: integer } }>
|
||||
---@type AvanteLLMToolFunc<{ path: string, start_line?: integer, end_line?: integer }>
|
||||
function M.func(opts, on_log, on_complete, session_ctx)
|
||||
if on_log then on_log("path: " .. opts.path) end
|
||||
local abs_path = Helpers.get_abs_path(opts.path)
|
||||
@@ -84,11 +83,9 @@ function M.func(opts, on_log, on_complete, session_ctx)
|
||||
local file = io.open(abs_path, "r")
|
||||
if not file then return false, "file not found: " .. abs_path end
|
||||
local lines = Utils.read_file_from_buf_or_disk(abs_path)
|
||||
if opts.view_range then
|
||||
local start_line = opts.view_range.start_line
|
||||
local end_line = opts.view_range.end_line
|
||||
if start_line and end_line and lines then lines = vim.list_slice(lines, start_line, end_line) end
|
||||
end
|
||||
local start_line = opts.start_line
|
||||
local end_line = opts.end_line
|
||||
if start_line and end_line and lines then lines = vim.list_slice(lines, start_line, end_line) end
|
||||
local truncated_lines = {}
|
||||
local is_truncated = false
|
||||
local size = 0
|
||||
|
||||
74
lua/avante/llm_tools/write_to_file.lua
Normal file
74
lua/avante/llm_tools/write_to_file.lua
Normal file
@@ -0,0 +1,74 @@
|
||||
local Utils = require("avante.utils")
|
||||
local Base = require("avante.llm_tools.base")
|
||||
local Helpers = require("avante.llm_tools.helpers")
|
||||
|
||||
---@class AvanteLLMTool
|
||||
local M = setmetatable({}, Base)
|
||||
|
||||
M.name = "write_to_file"
|
||||
|
||||
M.description =
|
||||
"Request to write content to a file at the specified path. If the file exists, it will be overwritten with the provided content. If the file doesn't exist, it will be created. This tool will automatically create any directories needed to write the file."
|
||||
|
||||
function M.enabled() return require("avante.config").mode == "agentic" end
|
||||
|
||||
---@type AvanteLLMToolParam
|
||||
M.param = {
|
||||
type = "table",
|
||||
fields = {
|
||||
{
|
||||
name = "path",
|
||||
get_description = function()
|
||||
local res = ("The path of the file to write to (relative to the current working directory {{cwd}})"):gsub(
|
||||
"{{cwd}}",
|
||||
Utils.get_project_root()
|
||||
)
|
||||
return res
|
||||
end,
|
||||
type = "string",
|
||||
},
|
||||
{
|
||||
name = "content",
|
||||
description = "The content to write to the file. ALWAYS provide the COMPLETE intended content of the file, without any truncation or omissions. You MUST include ALL parts of the file, even if they haven't been modified.",
|
||||
type = "string",
|
||||
},
|
||||
},
|
||||
usage = {
|
||||
path = "File path here",
|
||||
content = "File content here",
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolReturn[]
|
||||
M.returns = {
|
||||
{
|
||||
name = "success",
|
||||
description = "Whether the file was created successfully",
|
||||
type = "boolean",
|
||||
},
|
||||
{
|
||||
name = "error",
|
||||
description = "Error message if the file was not created successfully",
|
||||
type = "string",
|
||||
optional = true,
|
||||
},
|
||||
}
|
||||
|
||||
---@type AvanteLLMToolFunc<{ path: string, content: string }>
|
||||
function M.func(opts, on_log, on_complete, session_ctx)
|
||||
if not on_complete then return false, "on_complete not provided" end
|
||||
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 opts.content == nil then return false, "content not provided" end
|
||||
local old_lines = Utils.read_file_from_buf_or_disk(abs_path)
|
||||
local old_content = table.concat(old_lines or {}, "\n")
|
||||
local replace_in_file = require("avante.llm_tools.replace_in_file")
|
||||
local diff = "<<<<<<< SEARCH\n" .. old_content .. "\n=======\n" .. opts.content .. "\n>>>>>>> REPLACE"
|
||||
local new_opts = {
|
||||
path = opts.path,
|
||||
diff = diff,
|
||||
}
|
||||
return replace_in_file.func(new_opts, on_log, on_complete, session_ctx)
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user