local tools_module = require("chatgpt_nvim.tools") local M = {} local function is_destructive_command(cmd) if not cmd then return false end local destructive_list = { "rm", "sudo", "mv", "cp" } for _, keyword in ipairs(destructive_list) do if cmd:match("(^" .. keyword .. "[%s$])") or cmd:match("[%s]" .. keyword .. "[%s$]") then return true end end return false end local function prompt_user_tool_accept(tool_call, conf) local function ask_user(msg) vim.api.nvim_out_write(msg .. " [y/N]: ") local ans = vim.fn.input("") if ans:lower() == "y" then return true end return false end local auto_accept = conf.tool_auto_accept[tool_call.tool] if tool_call.tool == "executeCommand" and auto_accept then if is_destructive_command(tool_call.command) then auto_accept = false end end if not auto_accept then return ask_user(("Tool request: %s -> Accept?"):format(tool_call.tool or "unknown")) else return true end end local function handle_tool_calls(tools, conf, is_subpath_fn, read_file_fn) local messages = {} for _, call in ipairs(tools) do local accepted = prompt_user_tool_accept(call, conf) if not accepted then table.insert(messages, string.format("Tool [%s] was rejected by user.", call.tool or "nil")) else local tool_impl = tools_module.tools_by_name[call.tool] if tool_impl then local msg = tool_impl.run(call, conf, prompt_user_tool_accept, is_subpath_fn, read_file_fn) table.insert(messages, msg) else table.insert(messages, string.format("Unknown tool type: '%s'", call.tool or "nil")) end end end local combined = table.concat(messages, "\n\n") local limit = conf.prompt_char_limit or 8000 if #combined > limit then return "The combined tool output is too large ("..#combined.."). Please break down the operations into smaller steps." end return combined end M.handle_tool_calls = handle_tool_calls return M