From 9791bdc71e2634f6ea2e03e6633051561bc6fd7a Mon Sep 17 00:00:00 2001 From: Lucas Pereira Date: Mon, 26 May 2025 11:44:54 +0200 Subject: [PATCH] feat: add claude 4 text_editor tool (#2079) --- lua/avante/llm_tools/init.lua | 32 ++++++++++++++++++++++++++++++++ lua/avante/providers/claude.lua | 7 ++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lua/avante/llm_tools/init.lua b/lua/avante/llm_tools/init.lua index a748c11..733826e 100644 --- a/lua/avante/llm_tools/init.lua +++ b/lua/avante/llm_tools/init.lua @@ -56,6 +56,36 @@ function M.str_replace_editor(opts, on_log, on_complete, session_ctx) return false, "Unknown command: " .. opts.command end +---@type AvanteLLMToolFunc<{ command: "view" | "str_replace" | "create" | "insert", path: string, old_str?: string, new_str?: string, file_text?: string, insert_line?: integer, new_str?: string, view_range?: integer[] }> +function M.str_replace_based_edit_tool(opts, on_log, on_complete, session_ctx) + if on_log then on_log("command: " .. opts.command) end + 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.command == "view" then + local view = require("avante.llm_tools.view") + local opts_ = { path = opts.path } + if opts.view_range then + local start_line, end_line = unpack(opts.view_range) + opts_.view_range = { + start_line = start_line, + end_line = end_line, + } + end + return view(opts_, on_log, on_complete, session_ctx) + end + if opts.command == "str_replace" then + return require("avante.llm_tools.str_replace").func(opts, on_log, on_complete, session_ctx) + end + if opts.command == "create" then + return require("avante.llm_tools.create").func(opts, on_log, on_complete, session_ctx) + end + if opts.command == "insert" then + return require("avante.llm_tools.insert").func(opts, on_log, on_complete, session_ctx) + end + return false, "Unknown command: " .. opts.command +end + ---@type AvanteLLMToolFunc<{ abs_path: string }> function M.read_global_file(opts, on_log) local abs_path = Helpers.get_abs_path(opts.abs_path) @@ -1132,6 +1162,8 @@ function M.process_tool_use(tools, tool_use, on_log, on_complete, session_ctx) local func if tool_use.name == "str_replace_editor" then func = M.str_replace_editor + elseif tool_use.name == "str_replace_based_edit_tool" then + func = M.str_replace_based_edit_tool else ---@type AvanteLLMTool? local tool = vim.iter(tools):find(function(tool) return tool.name == tool_use.name end) ---@param tool AvanteLLMTool diff --git a/lua/avante/providers/claude.lua b/lua/avante/providers/claude.lua index 1e8da96..af00b32 100644 --- a/lua/avante/providers/claude.lua +++ b/lua/avante/providers/claude.lua @@ -361,7 +361,12 @@ function M:parse_curl_args(prompt_opts) end if prompt_opts.tools and #prompt_opts.tools > 0 and Config.mode == "agentic" then - if provider_conf.model:match("claude%-3%-7%-sonnet") then + if provider_conf.model:match("claude%-sonnet%-4") then + table.insert(tools, { + type = "text_editor_20250429", + name = "str_replace_based_edit_tool", + }) + elseif provider_conf.model:match("claude%-3%-7%-sonnet") then table.insert(tools, { type = "text_editor_20250124", name = "str_replace_editor",