From 8ca6d9e67d84fcb6c88353954b9c1823baa470dc Mon Sep 17 00:00:00 2001 From: Zhe Yu Date: Tue, 1 Jul 2025 17:15:21 +0800 Subject: [PATCH 1/4] refactor(nvim): Enable wildcard tool opts for CodeCompanion --- .../_extensions/vectorcode/init.lua | 34 ++-- .../integrations/codecompanion/common.lua | 146 ------------------ .../codecompanion/files_ls_tool.lua | 8 + .../codecompanion/files_rm_tool.lua | 9 ++ .../integrations/codecompanion/ls_tool.lua | 24 ++- .../integrations/codecompanion/query_tool.lua | 118 +++++++++++++- .../codecompanion/vectorise_tool.lua | 24 ++- 7 files changed, 194 insertions(+), 169 deletions(-) diff --git a/lua/codecompanion/_extensions/vectorcode/init.lua b/lua/codecompanion/_extensions/vectorcode/init.lua index 497e2ee7..7843847d 100644 --- a/lua/codecompanion/_extensions/vectorcode/init.lua +++ b/lua/codecompanion/_extensions/vectorcode/init.lua @@ -12,28 +12,15 @@ local vc_config = require("vectorcode.config") local logger = vc_config.logger -local use_lsp = vc_config.get_user_config().async_backend == "lsp" - ---@type VectorCode.CodeCompanion.ExtensionOpts|{} local default_extension_opts = { tool_opts = { - ls = { use_lsp = use_lsp, requires_approval = false, include_in_toolbox = true }, - query = { use_lsp = use_lsp, requires_approval = false, include_in_toolbox = true }, - vectorise = { - use_lsp = use_lsp, - requires_approval = true, - include_in_toolbox = true, - }, - files_ls = { - use_lsp = use_lsp, - requires_approval = false, - include_in_toolbox = false, - }, - files_rm = { - use_lsp = use_lsp, - requires_approval = true, - include_in_toolbox = false, - }, + -- NOTE: the default opts are defined in the source code files of the tools. + ls = {}, + query = {}, + vectorise = {}, + files_ls = {}, + files_rm = {}, }, tool_group = { enabled = true, collapse = true, extras = {} }, } @@ -69,7 +56,14 @@ local M = { else cc_config.strategies.chat.tools[tool_name] = { description = string.format("Run VectorCode %s tool", sub_cmd), - callback = cc_integration.make_tool(sub_cmd, opts.tool_opts[sub_cmd]), + callback = cc_integration.make_tool( + sub_cmd, + vim.tbl_deep_extend( + "force", + opts.tool_opts["*"] or {}, + opts.tool_opts[sub_cmd] + ) + ), opts = { requires_approval = opts.tool_opts[sub_cmd].requires_approval }, } logger.info(string.format("%s tool has been created.", tool_name)) diff --git a/lua/vectorcode/integrations/codecompanion/common.lua b/lua/vectorcode/integrations/codecompanion/common.lua index 64f265cd..2b855aab 100644 --- a/lua/vectorcode/integrations/codecompanion/common.lua +++ b/lua/vectorcode/integrations/codecompanion/common.lua @@ -5,83 +5,6 @@ local vc_config = require("vectorcode.config") local notify_opts = vc_config.notify_opts local logger = vc_config.logger ----@type VectorCode.CodeCompanion.QueryToolOpts -local default_query_options = { - max_num = { chunk = -1, document = -1 }, - default_num = { chunk = 50, document = 10 }, - no_duplicate = true, - chunk_mode = false, - summarise = { - enabled = false, - query_augmented = true, - system_prompt = [[You are an expert and experienced code analyzer and summarizer. Your primary task is to analyze provided source code, which will be given as a list of XML objects, and generate a comprehensive, well-structured Markdown summary. This summary will serve as a concise source of information for others to quickly understand how the code works and how to interact with it, without needing to delve into the full source code. - -Input Format: -Each XML object represents either a full file or a chunk of a file, containing the following tags: -- `...`: The absolute file path of the source code. -- `...`: The full content of a source code file. This tag will not coexist with ``. -- `...`: A segment of source code from a file. This tag will not coexist with ``. -- `...` and `...`: These tags will be present only when a `` tag is used, indicating the starting and ending line numbers of the chunk within its respective file. - -Your goal is to process each of these XML objects. If multiple chunks belong to the same file, you must synthesize them to form a cohesive understanding of that file. Generate a single Markdown summary that combines insights from all provided objects. - -Markdown Structure: - - Top-Level Header (#): The absolute or relative file path of the source code. - - Secondary Headers (##): For each top-level symbol (e.g., functions, classes, global variables) defined directly within the source code file that are importable or includable by other programs. - - Tertiary Headers (###): For symbols nested one level deep within a secondary header's symbol (e.g., methods within a class, inner functions). - - Quaternary Headers (####): For symbols nested two levels deep (e.g., a function defined within a method of a class). - - Continue this pattern, incrementing the header level for each deeper level of nesting. - -Content for Each Section: - - Descriptive Summary: Each header section (from secondary headers downwards) must contain a concise and informative summary of the symbol defined by that header. - - For Functions/Methods: Explain their purpose, parameters (including types), return values (including types), high-level implementation details, and any significant side effects or core logic. For example, if summarizing a sorting function, include the sorting algorithm used. If summarizing a function that makes an HTTP request, mention the network library employed. - - For Classes: Describe the class's role, its main responsibilities, and key characteristics. - - For Variables (global or within scope): State their purpose, type (if discernible), and initial value or common usage. - - For Modules/Files (under the top-level header): Provide an overall description of the file's purpose, its main components, and its role within the larger project (if context is available). - -General Guidelines: - - Clarity and Conciseness: Summaries should be easy to understand, avoiding jargon where possible, and as brief as possible while retaining essential information. The full summary MUST NOT be longer than the original code input. When quoting a symbol in the code, include the line numbers where possible. - - Accuracy: Ensure the summary accurately reflects the code's functionality. - - Focus on Public Interface/Behavior: Prioritize describing what a function/class does and how it's used. Only include details about symbols (variables, functions, classes) that are importable/includable by other programs. DO NOT include local variables and functions that are not accessible by other functions outside their immediate scope. - - No Code Snippets: Do not include any actual code snippets in the summary. Focus solely on descriptive text. If you need to refer to a specific element for context (e.g., in an error description), describe it and provide line numbers for reference from the source code. - - Syntax/Semantic Errors: If the code contains syntax or semantic errors, describe them clearly within the summary, indicating the nature of the error. - - Language Agnostic: Adapt the summary to the specific programming language of the provided source code (e.g., Python, JavaScript, Java, C++, etc.). - - Handle Edge Cases/Dependencies: If a symbol relies heavily on external dependencies or handles specific edge cases, briefly mention these if they are significant to its overall function. - - Information Source: There will be no extra information available to you. Provide the summary solely based on the provided XML objects. - - Omit meaningless results: For an xml object that contains no meaningful information, you're free to omit it, but please leave a sentence in the summary saying that you did this. - - No extra reply: Your reply should solely consist of the summary. Do not say anything else. - - Merge chunks from the same file: When there are chunks that belong to the same file, merge their content so that they're grouped under the same top level header. -]], - }, -} - ----@type VectorCode.CodeCompanion.LsToolOpts -local default_ls_options = {} - ----@type VectorCode.CodeCompanion.VectoriseToolOpts -local default_vectorise_options = {} - local TOOL_RESULT_SOURCE = "VectorCodeToolResult" return { @@ -96,78 +19,9 @@ return { return table.concat(vim.iter(t):flatten(math.huge):totable(), "\n") end, - ---@param opts VectorCode.CodeCompanion.LsToolOpts|{}|nil - ---@return VectorCode.CodeCompanion.LsToolOpts - get_ls_tool_opts = function(opts) - opts = vim.tbl_deep_extend("force", default_ls_options, opts or {}) - logger.info( - string.format( - "Loading `vectorcode_ls` with the following opts:\n%s", - vim.inspect(opts) - ) - ) - return opts - end, - - ---@param opts VectorCode.CodeCompanion.VectoriseToolOpts|{}|nil - ---@return VectorCode.CodeCompanion.VectoriseToolOpts - get_vectorise_tool_opts = function(opts) - opts = vim.tbl_deep_extend("force", default_vectorise_options, opts or {}) - logger.info( - string.format( - "Loading `vectorcode_vectorise` with the following opts:\n%s", - vim.inspect(opts) - ) - ) - return opts - end, - - ---@param opts VectorCode.CodeCompanion.QueryToolOpts|{}|nil - ---@return VectorCode.CodeCompanion.QueryToolOpts - get_query_tool_opts = function(opts) - if opts == nil or opts.use_lsp == nil then - opts = vim.tbl_deep_extend( - "force", - opts or {}, - { use_lsp = vc_config.get_user_config().async_backend == "lsp" } - ) - end - opts = vim.tbl_deep_extend("force", default_query_options, opts) - if type(opts.default_num) == "table" then - if opts.chunk_mode then - opts.default_num = opts.default_num.chunk - else - opts.default_num = opts.default_num.document - end - assert( - type(opts.default_num) == "number", - "default_num should be an integer or a table: {chunk: integer, document: integer}" - ) - end - if type(opts.max_num) == "table" then - if opts.chunk_mode then - opts.max_num = opts.max_num.chunk - else - opts.max_num = opts.max_num.document - end - assert( - type(opts.max_num) == "number", - "max_num should be an integer or a table: {chunk: integer, document: integer}" - ) - end - logger.info( - string.format( - "Loading `vectorcode_query` with the following opts:\n%s", - vim.inspect(opts) - ) - ) - return opts - end, - ---@param result VectorCode.QueryResult ---@return string process_result = function(result) - -- TODO: Unify the handling of summarised and non-summarised result local llm_message if result.chunk then -- chunk mode diff --git a/lua/vectorcode/integrations/codecompanion/files_ls_tool.lua b/lua/vectorcode/integrations/codecompanion/files_ls_tool.lua index 0d956c2d..d5a3c064 100644 --- a/lua/vectorcode/integrations/codecompanion/files_ls_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/files_ls_tool.lua @@ -1,10 +1,18 @@ ---@module "codecompanion" local cc_common = require("vectorcode.integrations.codecompanion.common") +local vc_config = require("vectorcode.config") + +local default_opts = { + use_lsp = vc_config.get_user_config().async_backend == "lsp", + requires_approval = false, + include_in_toolbox = false, +} ---@param opts VectorCode.CodeCompanion.FilesLsToolOpts ---@return CodeCompanion.Agent.Tool return function(opts) + opts = vim.tbl_deep_extend("force", default_opts, opts or {}) local job_runner = require("vectorcode.integrations.codecompanion.common").initialise_runner( opts.use_lsp diff --git a/lua/vectorcode/integrations/codecompanion/files_rm_tool.lua b/lua/vectorcode/integrations/codecompanion/files_rm_tool.lua index f723ea8c..cf8d44de 100644 --- a/lua/vectorcode/integrations/codecompanion/files_rm_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/files_rm_tool.lua @@ -1,12 +1,21 @@ ---@module "codecompanion" local cc_common = require("vectorcode.integrations.codecompanion.common") +local vc_config = require("vectorcode.config") + +local default_opts = { + use_lsp = vc_config.get_user_config().async_backend == "lsp", + requires_approval = true, + include_in_toolbox = false, +} ---@alias FilesRmArgs { paths: string[], project_root: string } ---@param opts VectorCode.CodeCompanion.FilesRmToolOpts ---@return CodeCompanion.Agent.Tool return function(opts) + opts = vim.tbl_deep_extend("force", default_opts, opts or {}) + local tool_name = "vectorcode_files_rm" local job_runner = cc_common.initialise_runner(opts.use_lsp) diff --git a/lua/vectorcode/integrations/codecompanion/ls_tool.lua b/lua/vectorcode/integrations/codecompanion/ls_tool.lua index eb0bcc3d..36b0cf02 100644 --- a/lua/vectorcode/integrations/codecompanion/ls_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/ls_tool.lua @@ -2,11 +2,33 @@ local cc_common = require("vectorcode.integrations.codecompanion.common") local vectorcode = require("vectorcode") +local vc_config = require("vectorcode.config") +local logger = vc_config.logger + +---@type VectorCode.CodeCompanion.LsToolOpts +local default_ls_options = { + use_lsp = vc_config.get_user_config().async_backend == "lsp", + requires_approval = false, + include_in_toolbox = true, +} + +---@param opts VectorCode.CodeCompanion.LsToolOpts|{}|nil +---@return VectorCode.CodeCompanion.LsToolOpts +local get_ls_tool_opts = function(opts) + opts = vim.tbl_deep_extend("force", default_ls_options, opts or {}) + logger.info( + string.format( + "Loading `vectorcode_ls` with the following opts:\n%s", + vim.inspect(opts) + ) + ) + return opts +end ---@param opts VectorCode.CodeCompanion.LsToolOpts ---@return CodeCompanion.Agent.Tool return function(opts) - opts = cc_common.get_ls_tool_opts(opts) + opts = get_ls_tool_opts(opts) local job_runner = require("vectorcode.integrations.codecompanion.common").initialise_runner( opts.use_lsp diff --git a/lua/vectorcode/integrations/codecompanion/query_tool.lua b/lua/vectorcode/integrations/codecompanion/query_tool.lua index 6f9300ee..40ad5a28 100644 --- a/lua/vectorcode/integrations/codecompanion/query_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/query_tool.lua @@ -12,6 +12,122 @@ local job_runner = nil ---@alias QueryToolArgs { project_root:string, count: integer, query: string[], allow_summary: boolean } +---@type VectorCode.CodeCompanion.QueryToolOpts +local default_query_options = { + use_lsp = vc_config.get_user_config().async_backend == "lsp", + requires_approval = false, + include_in_toolbox = true, + max_num = { chunk = -1, document = -1 }, + default_num = { chunk = 50, document = 10 }, + no_duplicate = true, + chunk_mode = false, + summarise = { + enabled = false, + query_augmented = true, + system_prompt = [[You are an expert and experienced code analyzer and summarizer. Your primary task is to analyze provided source code, which will be given as a list of XML objects, and generate a comprehensive, well-structured Markdown summary. This summary will serve as a concise source of information for others to quickly understand how the code works and how to interact with it, without needing to delve into the full source code. + +Input Format: +Each XML object represents either a full file or a chunk of a file, containing the following tags: +- `...`: The absolute file path of the source code. +- `...`: The full content of a source code file. This tag will not coexist with ``. +- `...`: A segment of source code from a file. This tag will not coexist with ``. +- `...` and `...`: These tags will be present only when a `` tag is used, indicating the starting and ending line numbers of the chunk within its respective file. + +Your goal is to process each of these XML objects. If multiple chunks belong to the same file, you must synthesize them to form a cohesive understanding of that file. Generate a single Markdown summary that combines insights from all provided objects. + +Markdown Structure: + + Top-Level Header (#): The absolute or relative file path of the source code. + + Secondary Headers (##): For each top-level symbol (e.g., functions, classes, global variables) defined directly within the source code file that are importable or includable by other programs. + + Tertiary Headers (###): For symbols nested one level deep within a secondary header's symbol (e.g., methods within a class, inner functions). + + Quaternary Headers (####): For symbols nested two levels deep (e.g., a function defined within a method of a class). + + Continue this pattern, incrementing the header level for each deeper level of nesting. + +Content for Each Section: + + Descriptive Summary: Each header section (from secondary headers downwards) must contain a concise and informative summary of the symbol defined by that header. + + For Functions/Methods: Explain their purpose, parameters (including types), return values (including types), high-level implementation details, and any significant side effects or core logic. For example, if summarizing a sorting function, include the sorting algorithm used. If summarizing a function that makes an HTTP request, mention the network library employed. + + For Classes: Describe the class's role, its main responsibilities, and key characteristics. + + For Variables (global or within scope): State their purpose, type (if discernible), and initial value or common usage. + + For Modules/Files (under the top-level header): Provide an overall description of the file's purpose, its main components, and its role within the larger project (if context is available). + +General Guidelines: + + Clarity and Conciseness: Summaries should be easy to understand, avoiding jargon where possible, and as brief as possible while retaining essential information. The full summary MUST NOT be longer than the original code input. When quoting a symbol in the code, include the line numbers where possible. + + Accuracy: Ensure the summary accurately reflects the code's functionality. + + Focus on Public Interface/Behavior: Prioritize describing what a function/class does and how it's used. Only include details about symbols (variables, functions, classes) that are importable/includable by other programs. DO NOT include local variables and functions that are not accessible by other functions outside their immediate scope. + + No Code Snippets: Do not include any actual code snippets in the summary. Focus solely on descriptive text. If you need to refer to a specific element for context (e.g., in an error description), describe it and provide line numbers for reference from the source code. + + Syntax/Semantic Errors: If the code contains syntax or semantic errors, describe them clearly within the summary, indicating the nature of the error. + + Language Agnostic: Adapt the summary to the specific programming language of the provided source code (e.g., Python, JavaScript, Java, C++, etc.). + + Handle Edge Cases/Dependencies: If a symbol relies heavily on external dependencies or handles specific edge cases, briefly mention these if they are significant to its overall function. + + Information Source: There will be no extra information available to you. Provide the summary solely based on the provided XML objects. + + Omit meaningless results: For an xml object that contains no meaningful information, you're free to omit it, but please leave a sentence in the summary saying that you did this. + + No extra reply: Your reply should solely consist of the summary. Do not say anything else. + + Merge chunks from the same file: When there are chunks that belong to the same file, merge their content so that they're grouped under the same top level header. +]], + }, +} + +---@param opts VectorCode.CodeCompanion.QueryToolOpts|{}|nil +---@return VectorCode.CodeCompanion.QueryToolOpts +local get_query_tool_opts = function(opts) + if opts == nil or opts.use_lsp == nil then + opts = vim.tbl_deep_extend( + "force", + opts or {}, + { use_lsp = vc_config.get_user_config().async_backend == "lsp" } + ) + end + opts = vim.tbl_deep_extend("force", default_query_options, opts) + if type(opts.default_num) == "table" then + if opts.chunk_mode then + opts.default_num = opts.default_num.chunk + else + opts.default_num = opts.default_num.document + end + assert( + type(opts.default_num) == "number", + "default_num should be an integer or a table: {chunk: integer, document: integer}" + ) + end + if type(opts.max_num) == "table" then + if opts.chunk_mode then + opts.max_num = opts.max_num.chunk + else + opts.max_num = opts.max_num.document + end + assert( + type(opts.max_num) == "number", + "max_num should be an integer or a table: {chunk: integer, document: integer}" + ) + end + logger.info( + string.format( + "Loading `vectorcode_query` with the following opts:\n%s", + vim.inspect(opts) + ) + ) + return opts +end + ---@alias chat_id integer ---@alias result_id string ---@type @@ -171,7 +287,7 @@ end ---@param opts VectorCode.CodeCompanion.QueryToolOpts? ---@return CodeCompanion.Agent.Tool return check_cli_wrap(function(opts) - opts = cc_common.get_query_tool_opts(opts) + opts = get_query_tool_opts(opts) assert( type(opts.max_num) == "number" and type(opts.default_num) == "number", string.format("Options are not correctly formatted:%s", vim.inspect(opts)) diff --git a/lua/vectorcode/integrations/codecompanion/vectorise_tool.lua b/lua/vectorcode/integrations/codecompanion/vectorise_tool.lua index 29f64e3f..ce004e94 100644 --- a/lua/vectorcode/integrations/codecompanion/vectorise_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/vectorise_tool.lua @@ -2,15 +2,37 @@ local cc_common = require("vectorcode.integrations.codecompanion.common") local vectorcode = require("vectorcode") +local vc_config = require("vectorcode.config") +local logger = vc_config.logger ---@alias VectoriseToolArgs { paths: string[], project_root: string } ---@alias VectoriseResult { add: integer, update: integer, removed: integer } +---@type VectorCode.CodeCompanion.VectoriseToolOpts +local default_vectorise_options = { + use_lsp = vc_config.get_user_config().async_backend == "lsp", + requires_approval = true, + include_in_toolbox = true, +} + +---@param opts VectorCode.CodeCompanion.VectoriseToolOpts|{}|nil +---@return VectorCode.CodeCompanion.VectoriseToolOpts +local get_vectorise_tool_opts = function(opts) + opts = vim.tbl_deep_extend("force", default_vectorise_options, opts or {}) + logger.info( + string.format( + "Loading `vectorcode_vectorise` with the following opts:\n%s", + vim.inspect(opts) + ) + ) + return opts +end + ---@param opts VectorCode.CodeCompanion.VectoriseToolOpts|{}|nil ---@return CodeCompanion.Agent.Tool return function(opts) - opts = cc_common.get_vectorise_tool_opts(opts) + opts = get_vectorise_tool_opts(opts) local tool_name = "vectorcode_vectorise" local job_runner = cc_common.initialise_runner(opts.use_lsp) From d11175f40dee356f11c3f0b66c6e323536e22cb6 Mon Sep 17 00:00:00 2001 From: Zhe Yu Date: Tue, 1 Jul 2025 17:23:02 +0800 Subject: [PATCH 2/4] fix(nvim): Use correct tool opts getter for summary system prompt --- lua/codecompanion/_extensions/vectorcode/init.lua | 14 ++++++++------ .../integrations/codecompanion/query_tool.lua | 5 ++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/lua/codecompanion/_extensions/vectorcode/init.lua b/lua/codecompanion/_extensions/vectorcode/init.lua index 7843847d..fe11fbd0 100644 --- a/lua/codecompanion/_extensions/vectorcode/init.lua +++ b/lua/codecompanion/_extensions/vectorcode/init.lua @@ -15,12 +15,14 @@ local logger = vc_config.logger ---@type VectorCode.CodeCompanion.ExtensionOpts|{} local default_extension_opts = { tool_opts = { - -- NOTE: the default opts are defined in the source code files of the tools. - ls = {}, - query = {}, - vectorise = {}, - files_ls = {}, - files_rm = {}, + -- NOTE: the other default opts are defined in the source code files of the tools. + -- `include_in_toolbox` is here so that the extension setup works as expected. + + ls = { include_in_toolbox = true }, + query = { include_in_toolbox = true }, + vectorise = { include_in_toolbox = true }, + files_ls = { include_in_toolbox = false }, + files_rm = { include_in_toolbox = false }, }, tool_group = { enabled = true, collapse = true, extras = {} }, } diff --git a/lua/vectorcode/integrations/codecompanion/query_tool.lua b/lua/vectorcode/integrations/codecompanion/query_tool.lua index 40ad5a28..1db53e62 100644 --- a/lua/vectorcode/integrations/codecompanion/query_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/query_tool.lua @@ -237,9 +237,8 @@ local function generate_summary(result, summarise_opts, cmd, callback) local system_prompt = summarise_opts.system_prompt if type(system_prompt) == "function" then - system_prompt = system_prompt( - cc_common.get_query_tool_opts().summarise.system_prompt --[[@as string]] - ) + system_prompt = + system_prompt(get_query_tool_opts().summarise.system_prompt --[[@as string]]) end assert( From aca6617863db7b0d55d28434e48d26d4ee8ba4e7 Mon Sep 17 00:00:00 2001 From: Zhe Yu Date: Tue, 1 Jul 2025 17:44:10 +0800 Subject: [PATCH 3/4] refactor(nvim): Move `process_result` to `query_tool.lua` --- .../integrations/codecompanion/common.lua | 27 ---------------- .../integrations/codecompanion/query_tool.lua | 31 +++++++++++++++++-- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lua/vectorcode/integrations/codecompanion/common.lua b/lua/vectorcode/integrations/codecompanion/common.lua index 2b855aab..ee17d5ab 100644 --- a/lua/vectorcode/integrations/codecompanion/common.lua +++ b/lua/vectorcode/integrations/codecompanion/common.lua @@ -19,33 +19,6 @@ return { return table.concat(vim.iter(t):flatten(math.huge):totable(), "\n") end, - ---@param result VectorCode.QueryResult - ---@return string - process_result = function(result) - local llm_message - if result.chunk then - -- chunk mode - llm_message = - string.format("%s%s", result.path, result.chunk) - if result.start_line and result.end_line then - llm_message = llm_message - .. string.format( - "%d%d", - result.start_line, - result.end_line - ) - end - else - -- full document mode - llm_message = string.format( - "%s%s", - result.path, - result.document - ) - end - return llm_message - end, - ---@param use_lsp boolean ---@return VectorCode.JobRunner initialise_runner = function(use_lsp) diff --git a/lua/vectorcode/integrations/codecompanion/query_tool.lua b/lua/vectorcode/integrations/codecompanion/query_tool.lua index 1db53e62..aa20a4c6 100644 --- a/lua/vectorcode/integrations/codecompanion/query_tool.lua +++ b/lua/vectorcode/integrations/codecompanion/query_tool.lua @@ -128,6 +128,33 @@ local get_query_tool_opts = function(opts) return opts end +---@param result VectorCode.QueryResult +---@return string +local process_result = function(result) + local llm_message + if result.chunk then + -- chunk mode + llm_message = + string.format("%s%s", result.path, result.chunk) + if result.start_line and result.end_line then + llm_message = llm_message + .. string.format( + "%d%d", + result.start_line, + result.end_line + ) + end + else + -- full document mode + llm_message = string.format( + "%s%s", + result.path, + result.document + ) + end + return llm_message +end + ---@alias chat_id integer ---@alias result_id string ---@type @@ -226,7 +253,7 @@ local function generate_summary(result, summarise_opts, cmd, callback) local result_xml = table.concat(vim .iter(result) :map(function(res) - return cc_common.process_result(res) + return process_result(res) end) :totable()) @@ -527,7 +554,7 @@ Set this to `false` only if you've been instructed by the user to not enable sum or table.concat(vim .iter(stdout.raw_results or {}) :map(function(res) - return cc_common.process_result(res) + return process_result(res) end) :totable()), string.format("**VectorCode Tool**: Retrieved %d %s(s)", stdout.count, mode) From 45a863651116db50cac5edbb3a2135b2374c351e Mon Sep 17 00:00:00 2001 From: Zhe Yu Date: Tue, 1 Jul 2025 18:22:25 +0800 Subject: [PATCH 4/4] refactor(nvim): Refactor tool opts merging logic for CodeCompanion --- .../_extensions/vectorcode/init.lua | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/lua/codecompanion/_extensions/vectorcode/init.lua b/lua/codecompanion/_extensions/vectorcode/init.lua index fe11fbd0..ec25b1ad 100644 --- a/lua/codecompanion/_extensions/vectorcode/init.lua +++ b/lua/codecompanion/_extensions/vectorcode/init.lua @@ -21,8 +21,8 @@ local default_extension_opts = { ls = { include_in_toolbox = true }, query = { include_in_toolbox = true }, vectorise = { include_in_toolbox = true }, - files_ls = { include_in_toolbox = false }, - files_rm = { include_in_toolbox = false }, + files_ls = {}, + files_rm = {}, }, tool_group = { enabled = true, collapse = true, extras = {} }, } @@ -30,11 +30,26 @@ local default_extension_opts = { ---@type sub_cmd[] local valid_tools = { "ls", "query", "vectorise", "files_ls", "files_rm" } +---@param tool_opts table +---@return table +local function merge_tool_opts(tool_opts) + local wildcard_opts = tool_opts["*"] + if wildcard_opts then + for tool_name, opts in pairs(tool_opts) do + if tool_name ~= "*" then + tool_opts[tool_name] = vim.tbl_deep_extend("force", wildcard_opts, opts) + end + end + end + return tool_opts +end + ---@type CodeCompanion.Extension local M = { ---@param opts VectorCode.CodeCompanion.ExtensionOpts setup = vc_config.check_cli_wrap(function(opts) opts = vim.tbl_deep_extend("force", default_extension_opts, opts or {}) + opts.tool_opts = merge_tool_opts(opts.tool_opts) logger.info("Received codecompanion extension opts:\n", opts) local cc_config = require("codecompanion.config").config local cc_integration = require("vectorcode.integrations").codecompanion.chat @@ -58,14 +73,7 @@ local M = { else cc_config.strategies.chat.tools[tool_name] = { description = string.format("Run VectorCode %s tool", sub_cmd), - callback = cc_integration.make_tool( - sub_cmd, - vim.tbl_deep_extend( - "force", - opts.tool_opts["*"] or {}, - opts.tool_opts[sub_cmd] - ) - ), + callback = cc_integration.make_tool(sub_cmd, opts.tool_opts[sub_cmd]), opts = { requires_approval = opts.tool_opts[sub_cmd].requires_approval }, } logger.info(string.format("%s tool has been created.", tool_name))