Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions doc/codecompanion.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*codecompanion.txt* For NVIM v0.11 Last change: 2025 November 24
*codecompanion.txt* For NVIM v0.11 Last change: 2025 November 27

==============================================================================
Table of Contents *codecompanion-table-of-contents*
Expand Down Expand Up @@ -878,9 +878,10 @@ The configuration for both types of adapters is exactly the same, however they
sit within their own tables (`adapters.http.*` and `adapters.acp.*`) and have
different options available. HTTP adapters use `models` to allow users to
select the specific LLM they’d like to interact with. ACP adapters use
`commands` to allow users to customize their interaction with agents (e.g.�
enabling `yolo` mode). As there is a lot of shared functionality between the
two adapters, it is recommend that you read this page alongside the ACP one.
`commands` to allow users to customize their interaction with agents
(e.g. enabling `yolo` mode). As there is a lot of shared functionality between
the two adapters, it is recommend that you read this page alongside the ACP
one.


CHANGING THE DEFAULT ADAPTER ~
Expand Down Expand Up @@ -912,7 +913,7 @@ the adapter’s URL, headers, parameters and other fields at runtime.

Supported `env` value types: - **Plain environment variable name (string)**: if
the value is the name of an environment variable that has already been set
(e.g.`"HOME"` or `"GEMINI_API_KEY"`), the plugin will read the value. -
(e.g. `"HOME"` or `"GEMINI_API_KEY"`), the plugin will read the value. -
**Command (string prefixed with cmd:)**: any value that starts with `cmd:` will
be executed via the shell. Example: `"cmd:op read
op://personal/Gemini/credential --no-newline"`. - **Function**: you can provide
Expand Down Expand Up @@ -2909,7 +2910,7 @@ The fastest way to copy an LLM’s code output is with `gy`. This will yank the
nearest codeblock.


APPLYING AN LLM€�S EDITS TO A BUFFER OR FILE ~
APPLYING AN LLMS EDITS TO A BUFFER OR FILE ~

The |codecompanion-usage-chat-buffer-tools-files| tool, combined with the
|codecompanion-usage-chat-buffer-variables.html-buffer| variable or
Expand Down Expand Up @@ -4977,7 +4978,7 @@ These handlers manage tool/function calling:
as a great reference to understand how they’re working with the output of the
API

OPENAI€�S API OUTPUT
OPENAIS API OUTPUT

If we reference the OpenAI documentation
<https://platform.openai.com/docs/guides/text-generation/chat-completions-api>
Expand Down Expand Up @@ -6884,7 +6885,7 @@ tool to function. In the case of Anthropic, we insert additional headers.
<

Some adapter tools can be a `hybrid` in terms of their implementation. That is,
they’re an adapter tool that requires a client-side component (i.e.a
they’re an adapter tool that requires a client-side component (i.e. a
built-in tool). This is the case for the
|codecompanion-usage-chat-buffer-tools-memory| tool from Anthropic. To allow
for this, ensure that the tool definition in `available_tools` has
Expand Down
6 changes: 6 additions & 0 deletions lua/codecompanion/strategies/chat/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1398,19 +1398,25 @@ function Chat:check_context()
-- Clear any tool's schemas
local schemas_to_keep = {}
local tools_in_use_to_keep = {}
local groups_in_use_to_keep = {}
for id, tool_schema in pairs(self.tool_registry.schemas) do
if not vim.tbl_contains(to_remove, id) then
schemas_to_keep[id] = tool_schema
local tool_name = id:match("<tool>(.*)</tool>")
if tool_name and self.tool_registry.in_use[tool_name] then
tools_in_use_to_keep[tool_name] = true
end
local group_name = id:match("<group>(.*)</group>")
if group_name and self.tool_registry.groups_in_use[group_name] then
groups_in_use_to_keep[group_name] = true
end
else
log:debug("Removing tool schema and usage flag for ID: %s", id) -- Optional logging
end
end
self.tool_registry.schemas = schemas_to_keep
self.tool_registry.in_use = tools_in_use_to_keep
self.tool_registry.groups_in_use = groups_in_use_to_keep
end

---Refresh the chat context by syncing to message-linked context IDs and re-rendering
Expand Down
11 changes: 11 additions & 0 deletions lua/codecompanion/strategies/chat/tool_registry.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Methods for handling interactions between the chat buffer and tools
---@field chat CodeCompanion.Chat
---@field flags table Flags that external functions can update and subscribers can interact with
---@field in_use table<string, boolean> Tools that are in use on the chat buffer
---@field groups_in_use table<string, boolean> Tool groups that are in use on the chat buffer
---@field schemas table<string, table> The config for the tools in use

---@class CodeCompanion.Chat.ToolRegistry
Expand All @@ -23,6 +24,7 @@ function ToolRegistry.new(args)
chat = args.chat,
flags = {},
in_use = {},
groups_in_use = {},
schemas = {},
}, { __index = ToolRegistry })

Expand Down Expand Up @@ -122,6 +124,11 @@ function ToolRegistry:add_group(group, tools_config)
return
end

-- Check if group is already in use to prevent duplicates
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can lose the comments as they don't add any value

if self.groups_in_use[group] then
return
end

local opts = vim.tbl_deep_extend("force", { collapse_tools = true }, group_config.opts or {})
local collapse_tools = opts.collapse_tools

Expand All @@ -144,6 +151,9 @@ function ToolRegistry:add_group(group, tools_config)
for _, tool in ipairs(group_config.tools) do
self:add(tool, tools_config[tool], { visible = not collapse_tools })
end

-- Mark group as in use
self.groups_in_use[group] = true
end

---Add a tool system prompt to the chat buffer, updated for every tool addition
Expand Down Expand Up @@ -179,6 +189,7 @@ end
function ToolRegistry:clear()
self.flags = {}
self.in_use = {}
self.groups_in_use = {}
self.schemas = {}
end

Expand Down
16 changes: 15 additions & 1 deletion lua/codecompanion/strategies/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ function Strategies:workflow()
messages = messages,
})

-- Process initial messages for tools and variables
for _, msg in ipairs(chat.messages) do
if msg.content then
chat:replace_vars_and_tools(msg)
end
end

---TODO: Remove workflow.references in v18.0.0
if workflow.references or workflow.context then
self.add_context(workflow, chat)
Expand All @@ -228,7 +235,14 @@ function Strategies:workflow()
if type(val.content) == "function" then
val.content = val.content(self.buffer_context)
end
chat:add_buf_message(val)
-- Parse tools and variables from the message content in the following prompts
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, lose the comments. It's pretty clear what is happening with the code

chat:replace_vars_and_tools(val)
-- Add to messages table (for LLM) - always needed
chat:add_message(val, val.opts)
-- Only add to buffer if visible is not false
if not (val.opts and val.opts.visible == false) then
chat:add_buf_message(val, val.opts)
end
if val.opts and val.opts.adapter and val.opts.adapter.name then
chat:change_adapter(val.opts.adapter.name, val.opts.adapter.model)
end
Expand Down