fix: prohibit repeated reading of the file (#1708)

This commit is contained in:
yetone
2025-03-25 15:54:47 +08:00
committed by GitHub
parent 976fb4177c
commit f84cb2896d
6 changed files with 26 additions and 9 deletions

View File

@@ -536,7 +536,8 @@ function M._stream(opts)
return handle_next_tool_use(tool_use_list, tool_use_index + 1, tool_histories) return handle_next_tool_use(tool_use_list, tool_use_index + 1, tool_histories)
end end
-- Either on_complete handles the tool result asynchronously or we receive the result and error synchronously when either is not nil -- Either on_complete handles the tool result asynchronously or we receive the result and error synchronously when either is not nil
local result, error = LLMTools.process_tool_use(opts.tools, tool_use, opts.on_tool_log, handle_tool_result) local result, error =
LLMTools.process_tool_use(opts.tools, tool_use, opts.on_tool_log, handle_tool_result, opts.session_ctx)
if result ~= nil or error ~= nil then return handle_tool_result(result, error) end if result ~= nil or error ~= nil then return handle_tool_result(result, error) end
end end
if stop_opts.reason == "cancelled" then if stop_opts.reason == "cancelled" then

View File

@@ -13,11 +13,13 @@ M.name = "bash"
M.get_description = function() M.get_description = function()
local provider = Providers[Config.provider] local provider = Providers[Config.provider]
if Config.provider:match("copilot") and provider.model and provider.model:match("gpt") then if Config.provider:match("copilot") and provider.model and provider.model:match("gpt") then
return [[Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.]] return [[Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures. Do not use bash command to read or modify files, or you will be fired!]]
end end
return [[Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures. return [[Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.
Do not use bash command to read or modify files, or you will be fired!
Before executing the command, please follow these steps: Before executing the command, please follow these steps:
1. Directory Verification: 1. Directory Verification:

View File

@@ -26,7 +26,7 @@ function M.read_file_toplevel_symbols(opts, on_log)
end end
---@type AvanteLLMToolFunc<{ command: "view" | "str_replace" | "create" | "insert" | "undo_edit", path: string, old_str?: string, new_str?: string, file_text?: string, insert_line?: integer, new_str?: string, view_range?: integer[] }> ---@type AvanteLLMToolFunc<{ command: "view" | "str_replace" | "create" | "insert" | "undo_edit", path: string, old_str?: string, new_str?: string, file_text?: string, insert_line?: integer, new_str?: string, view_range?: integer[] }>
function M.str_replace_editor(opts, on_log, on_complete) function M.str_replace_editor(opts, on_log, on_complete, session_ctx)
if on_log then on_log("command: " .. opts.command) end if on_log then on_log("command: " .. opts.command) end
if on_log then on_log("path: " .. vim.inspect(opts.path)) end if on_log then on_log("path: " .. vim.inspect(opts.path)) end
if not on_complete then return false, "on_complete not provided" end if not on_complete then return false, "on_complete not provided" end
@@ -51,7 +51,7 @@ function M.str_replace_editor(opts, on_log, on_complete)
end_line = end_line, end_line = end_line,
} }
end end
return view(opts_, on_log, on_complete) return view(opts_, on_log, on_complete, session_ctx)
end end
if opts.command == "str_replace" then if opts.command == "str_replace" then
if not Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end if not Path:new(abs_path):exists() then return false, "File not found: " .. abs_path end
@@ -1247,9 +1247,10 @@ M._tools = {
---@param tool_use AvanteLLMToolUse ---@param tool_use AvanteLLMToolUse
---@param on_log? fun(tool_name: string, log: string): nil ---@param on_log? fun(tool_name: string, log: string): nil
---@param on_complete? fun(result: string | nil, error: string | nil): nil ---@param on_complete? fun(result: string | nil, error: string | nil): nil
---@param session_ctx? table
---@return string | nil result ---@return string | nil result
---@return string | nil error ---@return string | nil error
function M.process_tool_use(tools, tool_use, on_log, on_complete) 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) Utils.debug("use tool", tool_use.name, tool_use.input_json)
-- Check if execution is already cancelled -- Check if execution is already cancelled
@@ -1344,7 +1345,7 @@ function M.process_tool_use(tools, tool_use, on_log, on_complete)
return return
end end
on_complete(result, err) on_complete(result, err)
end) end, session_ctx)
-- Result and error being nil means that the tool was executed asynchronously -- Result and error being nil means that the tool was executed asynchronously
if result == nil and err == nil and on_complete then return end if result == nil and err == nil and on_complete then return end

View File

@@ -73,12 +73,22 @@ 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, session_ctx)
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 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?") on_complete(nil, "Ooooops! This file is already in the context! Why you are trying to read it again?")
return return
end end
if session_ctx then
local view_history = session_ctx.view_history or {}
local uniform_path = Utils.uniform_path(opts.path)
if view_history[uniform_path] then
on_complete(nil, "Ooooops! You have already viewed this file! Why you are trying to read it again?")
return
end
view_history[uniform_path] = true
session_ctx.view_history = view_history
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

View File

@@ -2817,6 +2817,7 @@ function Sidebar:create_input_container(opts)
on_chunk = on_chunk, on_chunk = on_chunk,
on_stop = on_stop, on_stop = on_stop,
on_tool_log = on_tool_log, on_tool_log = on_tool_log,
session_ctx = {},
}) })
Llm.stream(stream_options) Llm.stream(stream_options)

View File

@@ -332,6 +332,7 @@ vim.g.avante_login = vim.g.avante_login
---@field tool_use? AvanteLLMToolUse ---@field tool_use? AvanteLLMToolUse
--- ---
---@class AvanteLLMStreamOptions: AvanteGeneratePromptsOptions ---@class AvanteLLMStreamOptions: AvanteGeneratePromptsOptions
---@field session_ctx? table
---@field on_start AvanteLLMStartCallback ---@field on_start AvanteLLMStartCallback
---@field on_chunk AvanteLLMChunkCallback ---@field on_chunk AvanteLLMChunkCallback
---@field on_stop AvanteLLMStopCallback ---@field on_stop AvanteLLMStopCallback
@@ -339,8 +340,9 @@ vim.g.avante_login = vim.g.avante_login
--- ---
---@alias AvanteLLMToolFunc<T> fun( ---@alias AvanteLLMToolFunc<T> fun(
--- input: T, --- input: T,
--- on_log?: (fun(log: string): nil) | nil, --- on_log?: (fun(log: string): nil),
--- on_complete?: (fun(result: boolean | string | nil, error: string | nil): nil) | nil) --- on_complete?: (fun(result: boolean | string | nil, error: string | nil): nil),
--- session_ctx?: table)
--- : (boolean | string | nil, string | nil) --- : (boolean | string | nil, string | nil)
--- ---
---@class AvanteLLMTool ---@class AvanteLLMTool