Skip to content

Commit abccebf

Browse files
committed
fix(chat): hide tool context for ACP chats
1 parent f70759e commit abccebf

3 files changed

Lines changed: 131 additions & 2 deletions

File tree

lua/codecompanion/interactions/chat/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ function Chat:change_adapter(adapter, cb)
719719
end
720720

721721
self:set_system_prompt()
722+
self.tool_registry:update_context_visibility()
722723
self:update_metadata()
723724
self:apply_settings()
724725
fire()

lua/codecompanion/interactions/chat/tool_registry.lua

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ local function group_id(name)
3232
return fmt("<group>%s</group>", name)
3333
end
3434

35+
---Determine if tool context should be visible for a chat adapter
36+
---@param chat CodeCompanion.Chat The chat buffer
37+
---@return boolean
38+
local function tool_context_visible(chat)
39+
return not (chat.adapter and chat.adapter.type == "acp")
40+
end
41+
3542
---@class CodeCompanion.Chat.ToolsArgs
3643
---@field chat CodeCompanion.Chat
3744
---@field ctx CodeCompanion.SystemPrompt.Context
@@ -56,6 +63,12 @@ end
5663
---@param opts? table Optional parameters for the context_item
5764
---@return nil
5865
local function add_context(chat, id, opts)
66+
opts = opts or {}
67+
if opts.visible == nil then
68+
opts.visible = tool_context_visible(chat)
69+
opts._tool_context_auto_visibility = true
70+
end
71+
5972
chat.context:add({
6073
source = "tool",
6174
name = "tool",
@@ -121,7 +134,8 @@ end
121134
function ToolRegistry:add_single_tool(tool, opts)
122135
opts = opts or {}
123136
if opts.visible == nil then
124-
opts.visible = true
137+
opts.visible = tool_context_visible(self.chat)
138+
opts._tool_context_auto_visibility = true
125139
end
126140

127141
local tool_config = opts.config or config.interactions.chat.tools[tool]
@@ -166,6 +180,25 @@ function ToolRegistry:add_single_tool(tool, opts)
166180
return self
167181
end
168182

183+
---Update automatically managed tool context visibility for the current adapter
184+
---@return CodeCompanion.Chat.ToolRegistry
185+
function ToolRegistry:update_context_visibility()
186+
local visible = tool_context_visible(self.chat)
187+
188+
for _, context in ipairs(self.chat.context_items or {}) do
189+
if context.source == "tool" and context.opts and context.opts._tool_context_auto_visibility then
190+
context.opts.visible = visible
191+
end
192+
end
193+
194+
if self.chat.bufnr and vim.api.nvim_buf_is_valid(self.chat.bufnr) then
195+
self.chat.context:clear_rendered()
196+
self.chat.context:render()
197+
end
198+
199+
return self
200+
end
201+
169202
---Add tools from a group to the chat buffer
170203
---@param group string The name of the group
171204
---@param opts? { config: table }
@@ -216,7 +249,11 @@ function ToolRegistry:add_group(group, opts)
216249
for _, tool in ipairs(group_config.tools) do
217250
local tool_cfg = tools_config[tool]
218251
if tool_cfg then
219-
if self:add_single_tool(tool, { config = tool_cfg, visible = not collapse_tools }) then
252+
local tool_opts = { config = tool_cfg }
253+
if collapse_tools then
254+
tool_opts.visible = false
255+
end
256+
if self:add_single_tool(tool, tool_opts) then
220257
table.insert(added_tools, tool)
221258
end
222259
end

tests/interactions/chat/tools/test_tool_registry.lua

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ T["ToolRegistry"][":add"]["adds a group to the registry"] = function()
4747
h.expect_tbl_contains("cmd", registry)
4848
end
4949

50+
T["ToolRegistry"][":add"]["renders collapsed tool group without member tools"] = function()
51+
child.lua([[
52+
_G.chat.tool_registry:add("senior_dev")
53+
_G.chat.context:render()
54+
_G.buf_lines = h.get_buf_lines(_G.chat.bufnr)
55+
]])
56+
57+
local lines = child.lua_get([[_G.buf_lines]])
58+
local content = table.concat(lines, "\n")
59+
60+
h.expect_contains("senior_dev", content)
61+
h.eq(nil, content:find("<tool>func</tool>", 1, true))
62+
h.eq(nil, content:find("<tool>cmd</tool>", 1, true))
63+
end
64+
5065
T["ToolRegistry"][":add"]["renders tool in the chat buffer"] = function()
5166
child.lua([[
5267
_G.chat.tool_registry:add("func")
@@ -60,6 +75,82 @@ T["ToolRegistry"][":add"]["renders tool in the chat buffer"] = function()
6075
h.expect_contains("func", content)
6176
end
6277

78+
T["ToolRegistry"][":add"]["hides tool context for ACP chats"] = function()
79+
child.lua([[
80+
_G.chat = h.setup_chat_buffer({}, {
81+
name = "test_acp",
82+
config = {
83+
name = "test_acp",
84+
type = "acp",
85+
roles = { user = "user", assistant = "assistant" },
86+
handlers = {
87+
form_messages = function()
88+
return {}
89+
end,
90+
},
91+
},
92+
})
93+
_G.chat.tool_registry:add("func")
94+
_G.chat.context:render()
95+
_G.buf_lines = h.get_buf_lines(_G.chat.bufnr)
96+
]])
97+
98+
local lines = child.lua_get([[_G.buf_lines]])
99+
local content = table.concat(lines, "\n")
100+
101+
h.expect_tbl_contains("func", child.lua_get([[_G.chat.tool_registry.in_use]]))
102+
h.eq(nil, content:find("func", 1, true))
103+
end
104+
105+
T["ToolRegistry"][":add"]["hides tool group context for ACP chats"] = function()
106+
child.lua([[
107+
_G.chat = h.setup_chat_buffer({}, {
108+
name = "test_acp",
109+
config = {
110+
name = "test_acp",
111+
type = "acp",
112+
roles = { user = "user", assistant = "assistant" },
113+
handlers = {
114+
form_messages = function()
115+
return {}
116+
end,
117+
},
118+
},
119+
})
120+
_G.chat.tool_registry:add("senior_dev")
121+
_G.chat.context:render()
122+
_G.buf_lines = h.get_buf_lines(_G.chat.bufnr)
123+
]])
124+
125+
local lines = child.lua_get([[_G.buf_lines]])
126+
local content = table.concat(lines, "\n")
127+
128+
h.expect_tbl_contains("func", child.lua_get([[_G.chat.tool_registry.in_use]]))
129+
h.expect_tbl_contains("cmd", child.lua_get([[_G.chat.tool_registry.in_use]]))
130+
h.eq(nil, content:find("senior_dev", 1, true))
131+
h.eq(nil, content:find("func", 1, true))
132+
h.eq(nil, content:find("cmd", 1, true))
133+
end
134+
135+
T["ToolRegistry"][":add"]["updates tool context visibility when switching to ACP"] = function()
136+
child.lua([[
137+
_G.chat.tool_registry:add("senior_dev")
138+
_G.http_visible = _G.chat.context_items[1].opts.visible
139+
140+
_G.chat.adapter = { name = "test_acp", type = "acp" }
141+
_G.chat.tool_registry:update_context_visibility()
142+
_G.acp_visible = _G.chat.context_items[1].opts.visible
143+
144+
_G.chat.adapter = { name = "test_adapter", type = "http" }
145+
_G.chat.tool_registry:update_context_visibility()
146+
_G.http_again_visible = _G.chat.context_items[1].opts.visible
147+
]])
148+
149+
h.eq(true, child.lua_get([[_G.http_visible]]))
150+
h.eq(false, child.lua_get([[_G.acp_visible]]))
151+
h.eq(true, child.lua_get([[_G.http_again_visible]]))
152+
end
153+
63154
T["ToolRegistry"][":add"]["returns nil for unknown name"] = function()
64155
local result = child.lua_get([[_G.chat.tool_registry:add("nonexistent_tool_xyz")]])
65156

0 commit comments

Comments
 (0)