Skip to content

Commit f877dde

Browse files
authored
Merge pull request #1 from bahaaza/main
bahaaza: ravitemer#279
2 parents 7cd5db3 + f94e1c8 commit f877dde

4 files changed

Lines changed: 78 additions & 80 deletions

File tree

lua/mcphub/extensions/codecompanion/core.lua

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ local shared = require("mcphub.extensions.shared")
88
---@param output_handler function Callback for asynchronous calls
99
---@param context MCPHub.ToolCallContext
1010
---@return nil|{ status: "success"|"error", data: string }
11-
function M.execute_mcp_tool(params, agent, output_handler, context)
11+
function M.execute_mcp_tool(params, tools, output_handler, context)
1212
context = context or {}
1313
---@diagnostic disable-next-line: missing-parameter
1414
async.run(function()
@@ -43,7 +43,7 @@ function M.execute_mcp_tool(params, agent, output_handler, context)
4343
hub:access_resource(parsed_params.server_name, parsed_params.uri, {
4444
caller = {
4545
type = "codecompanion",
46-
codecompanion = agent,
46+
codecompanion = tools,
4747
auto_approve = result.approve,
4848
},
4949
parse_response = true,
@@ -63,7 +63,7 @@ function M.execute_mcp_tool(params, agent, output_handler, context)
6363
hub:call_tool(parsed_params.server_name, parsed_params.tool_name, parsed_params.arguments, {
6464
caller = {
6565
type = "codecompanion",
66-
codecompanion = agent,
66+
codecompanion = tools,
6767
auto_approve = result.approve,
6868
},
6969
parse_response = true,
@@ -108,7 +108,6 @@ local function add_tool_output(
108108
images
109109
)
110110
local config = require("codecompanion.config")
111-
local helpers = require("codecompanion.interactions.chat.helpers")
112111
local show_result_in_chat = opts.show_result_in_chat == true
113112
local text = llm_msg
114113
local formatted_name = opts.format_tool and opts.format_tool(display_name, tool) or display_name
@@ -121,7 +120,7 @@ local function add_tool_output(
121120
or string.format("**`%s` Tool**: Successfully finished", formatted_name)
122121
)
123122
for _, image in ipairs(images) do
124-
helpers.add_image(chat, image)
123+
chat:add_image_message(image)
125124
end
126125
else
127126
if show_result_in_chat or is_error then
@@ -148,17 +147,14 @@ end
148147
---@return {error: function, success: function}
149148
function M.create_output_handlers(display_name, has_function_calling, opts)
150149
return {
151-
---@param self CodeCompanion.Agent.Tool
152-
---@param agent CodeCompanion.Agent
153-
---@param stderr table The error output from the command
154-
error = function(self, agent, cmd, stderr)
155-
---@diagnostic disable-next-line: cast-local-type
156-
stderr = has_function_calling and (stderr[#stderr] or "") or cmd[#cmd]
157-
---@diagnostic disable-next-line: cast-local-type
158-
agent = has_function_calling and agent or self
159-
if type(stderr) == "table" then
160-
---@diagnostic disable-next-line: cast-local-type
161-
stderr = vim.inspect(stderr)
150+
---@param self CodeCompanion.Tools.Tool The tool object
151+
---@param stderr table|nil The error output from the command
152+
---@param meta { cmd: table, tools: CodeCompanion.Tools } Metadata with tools coordinator
153+
error = function(self, stderr, meta)
154+
local chat = meta.tools.chat
155+
local err_data = stderr and (stderr[#stderr] or "") or ""
156+
if type(err_data) == "table" then
157+
err_data = vim.inspect(err_data)
162158
end
163159
local formatted_name = opts.format_tool and opts.format_tool(display_name, self) or display_name
164160
local err_msg = string.format(
@@ -169,21 +165,19 @@ function M.create_output_handlers(display_name, has_function_calling, opts)
169165
````
170166
]],
171167
formatted_name,
172-
stderr
168+
err_data
173169
)
174-
add_tool_output(display_name, self, agent.chat, err_msg, true, has_function_calling, opts, nil, {})
170+
add_tool_output(display_name, self, chat, err_msg, true, has_function_calling, opts, nil, {})
175171
end,
176172

177-
---@param self CodeCompanion.Agent.Tool
178-
---@param agent CodeCompanion.Agent
179-
---@param cmd table The command that was executed
180-
---@param stdout table The output from the command
181-
success = function(self, agent, cmd, stdout)
173+
---@param self CodeCompanion.Tools.Tool The tool object
174+
---@param stdout table|nil The output from the command
175+
---@param meta { cmd: table, tools: CodeCompanion.Tools } Metadata with tools coordinator
176+
success = function(self, stdout, meta)
177+
local chat = meta.tools.chat
182178
local image_cache = require("mcphub.utils.image_cache")
183179
---@type MCPResponseOutput
184-
local result = has_function_calling and stdout[#stdout] or cmd[#cmd]
185-
---@diagnostic disable-next-line: cast-local-type
186-
agent = has_function_calling and agent or self
180+
local result = stdout and stdout[#stdout] or {}
187181
local formatted_name = opts.format_tool and opts.format_tool(display_name, self) or display_name
188182
local to_llm = nil
189183
local to_user = nil
@@ -243,7 +237,7 @@ function M.create_output_handlers(display_name, has_function_calling, opts)
243237
add_tool_output(
244238
display_name,
245239
self,
246-
agent.chat,
240+
chat,
247241
to_llm or fallback_to_llm,
248242
false,
249243
has_function_calling,

lua/mcphub/extensions/codecompanion/slash_commands.lua

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ function M.register()
1414
local slash_commands = config.interactions.chat.slash_commands
1515

1616
-- Remove existing MCP slash commands
17-
for key, value in pairs(slash_commands) do
18-
local id = value.id or ""
19-
if id:sub(1, 3) == "mcp" then
17+
for key, _ in pairs(slash_commands) do
18+
if type(key) == "string" and key:sub(1, 4) == "mcp:" then
2019
slash_commands[key] = nil
2120
end
2221
end
@@ -41,7 +40,6 @@ function M.register()
4140
end
4241

4342
slash_commands["mcp:" .. prompt_name] = {
44-
id = "mcp" .. server_name .. prompt_name,
4543
description = description,
4644
callback = function(self)
4745
shared.collect_arguments(arguments, function(values)
@@ -92,10 +90,9 @@ function M.register()
9290

9391
-- Handle images
9492
if output.images and #output.images > 0 then
95-
local helpers = require("codecompanion.interactions.chat.helpers")
9693
for _, image in ipairs(output.images) do
9794
local id = string.format("mcp-%s", os.time())
98-
helpers.add_image(self, {
95+
self:add_image_message({
9996
id = id,
10097
base64 = image.data,
10198
mimetype = image.mimeType,

lua/mcphub/extensions/codecompanion/tools.lua

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ end
2525
---@param has_function_calling boolean
2626
---@param opts MCPHub.Extensions.CodeCompanionConfig
2727
local function create_static_handler(action_name, has_function_calling, opts)
28-
---@param agent CodeCompanion.Agent The Editor tool
29-
---@param args MCPHub.ToolCallArgs | MCPHub.ResourceAccessArgs The arguments from the LLM's tool call
30-
---@param output_handler function Callback for asynchronous calls
28+
---@param self CodeCompanion.Tools The tools coordinator
29+
---@param action MCPHub.ToolCallArgs | MCPHub.ResourceAccessArgs The arguments from the LLM's tool call
30+
---@param cmd_opts { input?: any, output_cb: function } Options including the output callback
3131
---@return nil|{ status: "success"|"error", data: string }
32-
return function(agent, args, _, output_handler)
32+
return function(self, action, cmd_opts)
3333
local context = {
3434
tool_display_name = action_name,
3535
is_individual_tool = false,
3636
action = action_name,
3737
}
38-
core.execute_mcp_tool(args, agent, output_handler, context)
38+
core.execute_mcp_tool(action, self, cmd_opts.output_cb, context)
3939
end
4040
end
4141

@@ -50,22 +50,22 @@ end
5050
---@param namespaced_name string Namespaced tool name (safe_server_name__safe_tool_name)
5151
---@return function
5252
local function create_individual_tool_handler(server_name, tool_name, namespaced_name)
53-
---@param agent CodeCompanion.Agent The Editor tool
54-
---@param args MCPHub.ToolCallArgs
55-
---@param output_handler function Callback for asynchronous calls
56-
return function(agent, args, _, output_handler)
53+
---@param self CodeCompanion.Tools The tools coordinator
54+
---@param action MCPHub.ToolCallArgs The arguments from the LLM's tool call
55+
---@param cmd_opts { input?: any, output_cb: function } Options including the output callback
56+
return function(self, action, cmd_opts)
5757
local params = {
5858
server_name = server_name,
5959
tool_name = tool_name,
60-
tool_input = args,
60+
tool_input = action,
6161
}
6262
---@type MCPHub.ToolCallContext
6363
local context = {
6464
tool_display_name = namespaced_name,
6565
is_individual_tool = true,
6666
action = "use_mcp_tool",
6767
}
68-
core.execute_mcp_tool(params, agent, output_handler, context)
68+
core.execute_mcp_tool(params, self, cmd_opts.output_cb, context)
6969
end
7070
end
7171

@@ -137,7 +137,7 @@ function M.create_static_tools(opts)
137137
id = "mcp_static:mcp",
138138
description = " Call tools and resources from MCP servers with:\n\n - `use_mcp_tool`\n - `access_mcp_resource`\n",
139139
hide_in_help_window = false,
140-
system_prompt = function(_)
140+
system_prompt = function(group_config, ctx)
141141
local hub = require("mcphub").get_hub_instance()
142142
if not hub then
143143
vim.notify("MCP Hub is not initialized", vim.log.levels.WARN)
@@ -170,15 +170,21 @@ function M.create_static_tools(opts)
170170
hide_in_help_window = true,
171171
visible = false,
172172
---@class MCPHub.Extensions.CodeCompanionTool: CodeCompanion.Agent.Tool
173-
callback = {
174-
name = action_name,
175-
cmds = { create_static_handler(action_name, has_function_calling, opts) },
176-
system_prompt = function()
177-
return string.format("You can use the %s tool to %s\n", action_name, schema["function"].description)
178-
end,
179-
output = core.create_output_handlers(action_name, has_function_calling, opts),
180-
schema = schema,
181-
},
173+
callback = function()
174+
return {
175+
name = action_name,
176+
cmds = { create_static_handler(action_name, has_function_calling, opts) },
177+
system_prompt = function(group_config, ctx)
178+
return string.format(
179+
"You can use the %s tool to %s\n",
180+
action_name,
181+
schema["function"].description
182+
)
183+
end,
184+
output = core.create_output_handlers(action_name, has_function_calling, opts),
185+
schema = schema,
186+
}
187+
end,
182188
}
183189
table.insert(tools.groups.mcp.tools, action_name)
184190
end
@@ -277,19 +283,23 @@ function M.register(opts)
277283
description = tool.description,
278284
hide_in_help_window = true,
279285
visible = opts.show_server_tools_in_chat == true,
280-
callback = {
281-
name = namespaced_tool_name,
282-
cmds = { create_individual_tool_handler(server.name, tool_name, namespaced_tool_name) },
283-
output = core.create_output_handlers(namespaced_tool_name, true, opts),
284-
schema = {
285-
type = "function",
286-
["function"] = {
287-
name = namespaced_tool_name,
288-
description = tool.description,
289-
parameters = tool.inputSchema,
286+
callback = function()
287+
return {
288+
name = namespaced_tool_name,
289+
cmds = {
290+
create_individual_tool_handler(server.name, tool_name, namespaced_tool_name),
291+
},
292+
output = core.create_output_handlers(namespaced_tool_name, true, opts),
293+
schema = {
294+
type = "function",
295+
["function"] = {
296+
name = namespaced_tool_name,
297+
description = tool.description,
298+
parameters = tool.inputSchema,
299+
},
290300
},
291-
},
292-
},
301+
}
302+
end,
293303
}
294304
end
295305
end
@@ -328,7 +338,7 @@ function M.register(opts)
328338
)
329339
),
330340
tools = tool_names,
331-
system_prompt = function(self)
341+
system_prompt = function(group_config, ctx)
332342
if custom_instructions and custom_instructions ~= "" then
333343
return custom_instructions
334344
end

lua/mcphub/extensions/codecompanion/variables.lua

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,17 @@ function M.register(opts)
1414
return
1515
end
1616

17-
local cc_variables = config.interactions.chat.variables
17+
local cc_editor_context = config.config.interactions.shared.editor_context
1818

19-
-- Remove existing MCP variables
20-
for key, value in pairs(cc_variables) do
21-
local id = value.id or ""
22-
if id:sub(1, 3) == "mcp" then
23-
cc_variables[key] = nil
19+
-- Remove existing MCP editor context entries
20+
for key, _ in pairs(cc_editor_context) do
21+
if type(key) == "string" and key:sub(1, 4) == "mcp:" then
22+
cc_editor_context[key] = nil
2423
end
2524
end
2625

2726
local added_resources = {}
28-
-- Add current resources as variables
27+
-- Add current resources as editor context
2928
for _, resource in ipairs(resources) do
3029
local server_name = resource.server_name
3130
local uri = resource.uri
@@ -34,12 +33,11 @@ function M.register(opts)
3433
description = description:gsub("\n", " ")
3534
description = resource_name .. " (" .. description .. ")"
3635
local var_id = "mcp:" .. uri
37-
cc_variables[var_id] = {
38-
id = "mcp" .. server_name .. uri,
36+
cc_editor_context[var_id] = {
3937
description = description,
4038
hide_in_help_window = true,
4139
callback = function(self)
42-
-- Sync call - blocks UI (can't use async in variables yet)
40+
-- Sync call - blocks UI (can't use async in editor context yet)
4341
local result = hub:access_resource(server_name, uri, {
4442
caller = {
4543
type = "codecompanion",
@@ -57,10 +55,9 @@ function M.register(opts)
5755

5856
-- Handle images
5957
if result.images and #result.images > 0 then
60-
local helpers = require("codecompanion.interactions.chat.helpers")
6158
for _, image in ipairs(result.images) do
6259
local id = string.format("mcp-%s", os.time())
63-
helpers.add_image(self.Chat, {
60+
self.Chat:add_image_message({
6461
id = id,
6562
base64 = image.data,
6663
mimetype = image.mimeType,
@@ -74,7 +71,7 @@ function M.register(opts)
7471
table.insert(added_resources, var_id)
7572
end
7673

77-
-- Update syntax highlighting for variables
74+
-- Update syntax highlighting for editor context
7875
M.update_variable_syntax(added_resources)
7976
end
8077
-- Setup MCP resources as CodeCompanion variables

0 commit comments

Comments
 (0)