From 5e4eb8652b4776f139282a343f04a3a8c7f23cb0 Mon Sep 17 00:00:00 2001 From: NekoNekoNiko120 <151913497+NekoNekoNiko120@users.noreply.github.com> Date: Mon, 28 Jul 2025 13:21:49 +0800 Subject: [PATCH] feat: remember the last selected model (#2518) Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: yetone --- lua/avante/config.lua | 56 ++++++++++++++++++++++++++++++++++- lua/avante/history/init.lua | 4 +-- lua/avante/llm.lua | 18 +++++++---- lua/avante/model_selector.lua | 2 ++ 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/lua/avante/config.lua b/lua/avante/config.lua index 7f6f3fd..500c443 100644 --- a/lua/avante/config.lua +++ b/lua/avante/config.lua @@ -684,8 +684,50 @@ M._defaults = { ---@diagnostic disable-next-line: missing-fields M._options = {} ----@param opts? avante.Config +--- Function to save the last used model +---@param model_name string +function M.save_last_model(model_name, provider_name) + local config_dir = Utils.join_paths(vim.fn.expand("~"), ".config", "avante.nvim") + local storage_path = Utils.join_paths(config_dir, "config.json") + + -- 确保目录存在 + if not Utils.path_exists(config_dir) then vim.fn.mkdir(config_dir, "p") end + + local file = io.open(storage_path, "w") + if file then + file:write(vim.json.encode({ last_model = model_name, last_provider = provider_name })) + file:close() + end +end + +--- Function to load the last used model +---@return string|nil, string|nil +function M.load_last_model() + local config_dir = Utils.join_paths(vim.fn.expand("~"), ".config", "avante.nvim") + local storage_path = Utils.join_paths(config_dir, "config.json") + local file = io.open(storage_path, "r") + if file then + local content = file:read("*a") + file:close() + if content and content ~= "" then + local success, data = pcall(vim.json.decode, content) + if success and data and data.last_model and data.last_provider then + return data.last_model, data.last_provider + elseif success and data and data.last_model then + return data.last_model, nil + else + Utils.warn("Invalid or corrupt JSON in last model file: " .. storage_path, { title = "Avante" }) + end + else + Utils.warn("Last model file is empty: " .. storage_path, { title = "Avante" }) + end + end + return nil +end + +---@param opts table|nil -- Optional table parameter for configuration settings function M.setup(opts) + opts = opts or {} -- Ensure `opts` is defined with a default table if vim.fn.has("nvim-0.11") == 1 then vim.validate("opts", opts, "table", true) else @@ -819,6 +861,18 @@ function M.setup(opts) } ) + local last_model, last_provider = M.load_last_model() + if last_model then + if last_provider then merged.provider = last_provider end + if merged.providers and merged.provider and merged.providers[merged.provider] then + merged.providers[merged.provider].model = last_model + Utils.info( + "Using last model: " .. merged.provider .. "/" .. merged.providers[merged.provider].model, + { title = "Avante" } + ) + end + end + M._options = merged ---@diagnostic disable-next-line: undefined-field diff --git a/lua/avante/history/init.lua b/lua/avante/history/init.lua index 2089934..9844710 100644 --- a/lua/avante/history/init.lua +++ b/lua/avante/history/init.lua @@ -64,10 +64,10 @@ local function collect_tool_info(messages) if use.name == "view" or Utils.is_edit_tool_use(use) then if use.input.path then local path = Utils.uniform_path(use.input.path) - tools[use.id] = { kind = use.name == "view" and "view" or "edit", use = use, path = path } + if use.id then tools[use.id] = { kind = use.name == "view" and "view" or "edit", use = use, path = path } end end else - tools[use.id] = { kind = "other", use = use } + if use.id then tools[use.id] = { kind = "other", use = use } end end goto continue end diff --git a/lua/avante/llm.lua b/lua/avante/llm.lua index 8aa1e0c..c50379c 100644 --- a/lua/avante/llm.lua +++ b/lua/avante/llm.lua @@ -707,11 +707,19 @@ function M.curl(opts) -- Mark as completed first to prevent error handler from running completed = true - -- Attempt to shutdown the active job, but ignore any errors - xpcall(function() active_job:shutdown() end, function(err) - Utils.debug("Ignored error during job shutdown: " .. vim.inspect(err)) - return err - end) + -- 检查 active_job 的状态 + local job_is_alive = pcall(function() return active_job:is_closing() == false end) + + -- 只有当 job 仍然活跃时才尝试关闭它 + if job_is_alive then + -- Attempt to shutdown the active job, but ignore any errors + xpcall(function() active_job:shutdown() end, function(err) + Utils.debug("Ignored error during job shutdown: " .. vim.inspect(err)) + return err + end) + else + Utils.debug("Job already closed, skipping shutdown") + end Utils.debug("LLM request cancelled") active_job = nil diff --git a/lua/avante/model_selector.lua b/lua/avante/model_selector.lua index f80d0c5..85ac10a 100644 --- a/lua/avante/model_selector.lua +++ b/lua/avante/model_selector.lua @@ -119,6 +119,8 @@ function M.open() if provider_cfg then provider_cfg.model = choice.model end Utils.info("Switched to model: " .. choice.name) + -- Persist last used provider and model + Config.save_last_model(choice.model, choice.provider_name) end local selector = Selector:new({