-
-
Notifications
You must be signed in to change notification settings - Fork 91
Expand file tree
/
Copy pathslash_commands.lua
More file actions
136 lines (120 loc) · 4.97 KB
/
Copy pathslash_commands.lua
File metadata and controls
136 lines (120 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
local M = {}
local mcphub = require("mcphub")
local shared = require("mcphub.extensions.shared")
function M.register()
local config = require("codecompanion.config")
local hub = mcphub.get_hub_instance()
if not hub then
return
end
local prompts = hub:get_prompts()
local slash_commands = config.interactions.chat.slash_commands
-- Remove existing MCP slash commands
for key, _ in pairs(slash_commands) do
if type(key) == "string" and key:sub(1, 4) == "mcp:" then
slash_commands[key] = nil
end
end
-- Add current prompts as slash commands
for _, prompt in ipairs(prompts) do
local server_name = prompt.server_name
local prompt_name = prompt.name or ""
local description = prompt.description or ""
description = description:gsub("\n", " ")
description = prompt_name .. " (" .. description .. ")"
local arguments = prompt.arguments or {}
if type(arguments) == "function" then
local ok, args = pcall(arguments, prompt)
if ok then
arguments = args or {}
else
vim.notify("Error in arguments function: " .. (args or ""), vim.log.levels.ERROR)
arguments = {}
end
end
slash_commands["mcp:" .. prompt_name] = {
description = description,
callback = function(self)
shared.collect_arguments(arguments, function(values)
-- Sync call - blocks UI (can't use async in slash_commands yet)
local response, err = hub:get_prompt(server_name, prompt_name, values, {
caller = {
type = "codecompanion",
codecompanion = self,
meta = {
is_within_slash_command = true,
},
},
parse_response = true,
})
if not response then
if err then
vim.notify("Error in slash command: " .. err, vim.log.levels.ERROR)
vim.notify("Prompt cancelled", vim.log.levels.INFO)
end
return
end
local messages = response.messages or {}
local text_messages = 0
for i, message in ipairs(messages) do
local output = message.output
local mapped_role = message.role == "assistant" and config.constants.LLM_ROLE
or message.role == "system" and config.constants.SYSTEM_ROLE
or config.constants.USER_ROLE
if output.text and output.text ~= "" then
text_messages = text_messages + 1
-- If last message is from user, add it to chat buffer
if i == #messages and mapped_role == config.constants.USER_ROLE then
self:add_buf_message({
role = mapped_role,
content = output.text,
})
else
self:add_message({
role = mapped_role,
content = output.text,
})
end
end
-- Handle images
if output.images and #output.images > 0 then
for _, image in ipairs(output.images) do
local id = string.format("mcp-%s", os.time())
self:add_image_message({
id = id,
base64 = image.data,
mimetype = image.mimeType,
}, { role = mapped_role })
end
end
end
vim.notify(
string.format(
"%s message%s added successfully",
text_messages,
text_messages == 1 and "" or "s"
),
vim.log.levels.INFO
)
end)
end,
}
end
end
--- Setup MCP prompts as CodeCompanion slash commands
---@param opts MCPHub.Extensions.CodeCompanionConfig
function M.setup(opts)
if not opts.make_slash_commands then
return
end
vim.schedule(function()
M.register()
end)
mcphub.on(
{ "servers_updated", "prompt_list_changed" },
vim.schedule_wrap(function()
M.register()
end)
)
end
return M