Skip to content

Commit d3e638a

Browse files
committed
feat: add support for Github Marketplace models
Adds integration with Github Marketplace models available through Azure ML API. The models are fetched from the Azure catalog and exposed through the same interface as regular Copilot models. This provides users with access to additional experimental models while maintaining consistent UX. The docs are updated to point to official Copilot model documentation and marketplace models page rather than listing models inline. Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
1 parent dbce8a2 commit d3e638a

7 files changed

Lines changed: 453 additions & 374 deletions

File tree

README.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,16 +239,8 @@ You can also set default sticky prompts in the configuration:
239239

240240
You can list available models with `:CopilotChatModels` command. Model determines the AI model used for the chat.
241241
You can set the model in the prompt by using `$` followed by the model name or default model via config using `model` key.
242-
Default models are:
243-
244-
- `gpt-4o` - This is the default Copilot Chat model. It is a versatile, multimodal model that excels in both text and image processing and is designed to provide fast, reliable responses. It also has superior performance in non-English languages.
245-
- `claude-3.5-sonnet` - This model excels at coding tasks across the entire software development lifecycle, from initial design to bug fixes, maintenance to optimizations. Claude is **not available everywhere** so if you do not see it, try github codespaces or VPN.
246-
- `gemini-2.0-flash-001` - This model has strong coding, math, and reasoning capabilities that makes it well suited to assist with software development.
247-
- `o1` - This model is focused on advanced reasoning and solving complex problems, in particular in math and science. It responds more slowly than the GPT 4o model. You can make 10 requests to this model per day.
248-
- `o3-mini` - This model is the next generation of reasoning models, following from o1 and o1-mini. The o3-mini model outperforms o1 on coding benchmarks with response times that are comparable to o1-mini, providing improved quality at nearly the same latency. It is best suited for code generation and small context operations. You can make 50 requests to this model every 12 hours.
249-
250-
For more information about models, see [here](https://docs.github.com/en/copilot/using-github-copilot/asking-github-copilot-questions-in-your-ide#ai-models-for-copilot-chat)
251-
You can use more models from [here](https://github.com/marketplace/models) by using `@models` agent from [here](https://github.com/marketplace/models-github) (example: `@models Using Mistral-small, what is 1 + 11`)
242+
For list of models supported by Copilot Chat see [here](https://docs.github.com/en/copilot/using-github-copilot/ai-models/changing-the-ai-model-for-copilot-chat#ai-models-for-copilot-chat).
243+
This plugin also supports Github Marketplace Models. These have fairly low limits but are useful for experimentation. For more information see [here](https://github.com/marketplace/models).
252244

253245
## Agents
254246

lua/CopilotChat/config.lua

Lines changed: 5 additions & 303 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
1-
local prompts = require('CopilotChat.prompts')
2-
local context = require('CopilotChat.context')
1+
local prompts = require('CopilotChat.config.prompts')
32
local select = require('CopilotChat.select')
4-
local utils = require('CopilotChat.utils')
5-
6-
---@class CopilotChat.config.context
7-
---@field description string?
8-
---@field input fun(callback: fun(input: string?), source: CopilotChat.source)?
9-
---@field resolve fun(input: string?, source: CopilotChat.source):table<CopilotChat.context.embed>
10-
11-
---@class CopilotChat.config.prompt : CopilotChat.config.shared
12-
---@field prompt string?
13-
---@field description string?
14-
---@field mapping string?
153

164
---@class CopilotChat.config.window
175
---@field layout string?
@@ -25,32 +13,6 @@ local utils = require('CopilotChat.utils')
2513
---@field footer string?
2614
---@field zindex number?
2715

28-
---@class CopilotChat.config.mapping
29-
---@field normal string?
30-
---@field insert string?
31-
---@field detail string?
32-
33-
---@class CopilotChat.config.mapping.yank_diff : CopilotChat.config.mapping
34-
---@field register string?
35-
36-
---@class CopilotChat.config.mapping.show_diff : CopilotChat.config.mapping
37-
---@field full_diff boolean?
38-
39-
---@class CopilotChat.config.mappings
40-
---@field complete CopilotChat.config.mapping?
41-
---@field close CopilotChat.config.mapping?
42-
---@field reset CopilotChat.config.mapping?
43-
---@field submit_prompt CopilotChat.config.mapping?
44-
---@field toggle_sticky CopilotChat.config.mapping?
45-
---@field accept_diff CopilotChat.config.mapping?
46-
---@field jump_to_diff CopilotChat.config.mapping?
47-
---@field quickfix_diffs CopilotChat.config.mapping?
48-
---@field yank_diff CopilotChat.config.mapping.yank_diff?
49-
---@field show_diff CopilotChat.config.mapping.show_diff?
50-
---@field show_info CopilotChat.config.mapping?
51-
---@field show_context CopilotChat.config.mapping?
52-
---@field show_help CopilotChat.config.mapping?
53-
5416
---@class CopilotChat.config.shared
5517
---@field system_prompt string?
5618
---@field model string?
@@ -90,7 +52,7 @@ return {
9052

9153
-- Shared config starts here (can be passed to functions at runtime and configured via setup function)
9254

93-
system_prompt = prompts.COPILOT_INSTRUCTIONS, -- System prompt to use (can be specified manually in prompt via /).
55+
system_prompt = prompts.COPILOT_INSTRUCTIONS.system_prompt, -- System prompt to use (can be specified manually in prompt via /).
9456

9557
model = 'gpt-4o', -- Default model to use, see ':CopilotChatModels' for available models (can be specified manually in prompt via $).
9658
agent = 'copilot', -- Default agent to use, see ':CopilotChatAgents' for available agents (can be specified manually in prompt via @).
@@ -146,271 +108,11 @@ return {
146108
separator = '───', -- Separator to use in chat
147109

148110
-- default contexts
149-
contexts = {
150-
buffer = {
151-
description = 'Includes specified buffer in chat context. Supports input (default current).',
152-
input = function(callback)
153-
vim.ui.select(
154-
vim.tbl_map(
155-
function(buf)
156-
return { id = buf, name = vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buf), ':p:.') }
157-
end,
158-
vim.tbl_filter(function(buf)
159-
return utils.buf_valid(buf) and vim.fn.buflisted(buf) == 1
160-
end, vim.api.nvim_list_bufs())
161-
),
162-
{
163-
prompt = 'Select a buffer> ',
164-
format_item = function(item)
165-
return item.name
166-
end,
167-
},
168-
function(choice)
169-
callback(choice and choice.id)
170-
end
171-
)
172-
end,
173-
resolve = function(input, source)
174-
input = input and tonumber(input) or source.bufnr
175-
return {
176-
context.buffer(input),
177-
}
178-
end,
179-
},
180-
buffers = {
181-
description = 'Includes all buffers in chat context. Supports input (default listed).',
182-
input = function(callback)
183-
vim.ui.select({ 'listed', 'visible' }, {
184-
prompt = 'Select buffer scope> ',
185-
}, callback)
186-
end,
187-
resolve = function(input)
188-
input = input or 'listed'
189-
return context.buffers(input)
190-
end,
191-
},
192-
file = {
193-
description = 'Includes content of provided file in chat context. Supports input.',
194-
input = function(callback, source)
195-
local cwd = utils.win_cwd(source.winnr)
196-
local files = vim.tbl_filter(function(file)
197-
return vim.fn.isdirectory(file) == 0
198-
end, vim.fn.glob(cwd .. '/**/*', false, true))
199-
200-
vim.ui.select(files, {
201-
prompt = 'Select a file> ',
202-
}, callback)
203-
end,
204-
resolve = function(input)
205-
return {
206-
context.file(input),
207-
}
208-
end,
209-
},
210-
files = {
211-
description = 'Includes all non-hidden files in the current workspace in chat context. Supports input (default list).',
212-
input = function(callback)
213-
local choices = utils.kv_list({
214-
list = 'Only lists file names',
215-
full = 'Includes file content for each file found. Can be slow on large workspaces, use with care.',
216-
})
217-
218-
vim.ui.select(choices, {
219-
prompt = 'Select files content> ',
220-
format_item = function(choice)
221-
return choice.key .. ' - ' .. choice.value
222-
end,
223-
}, function(choice)
224-
callback(choice and choice.key)
225-
end)
226-
end,
227-
resolve = function(input, source)
228-
return context.files(source.winnr, input == 'full')
229-
end,
230-
},
231-
git = {
232-
description = 'Requires `git`. Includes current git diff in chat context. Supports input (default unstaged, also accepts commit number).',
233-
input = function(callback)
234-
vim.ui.select({ 'unstaged', 'staged' }, {
235-
prompt = 'Select diff type> ',
236-
}, callback)
237-
end,
238-
resolve = function(input, source)
239-
input = input or 'unstaged'
240-
return {
241-
context.gitdiff(input, source.winnr),
242-
}
243-
end,
244-
},
245-
url = {
246-
description = 'Includes content of provided URL in chat context. Supports input.',
247-
input = function(callback)
248-
vim.ui.input({
249-
prompt = 'Enter URL> ',
250-
default = 'https://',
251-
}, callback)
252-
end,
253-
resolve = function(input)
254-
return {
255-
context.url(input),
256-
}
257-
end,
258-
},
259-
register = {
260-
description = 'Includes contents of register in chat context. Supports input (default +, e.g clipboard).',
261-
input = function(callback)
262-
local choices = utils.kv_list({
263-
['+'] = 'synchronized with the system clipboard',
264-
['*'] = 'synchronized with the selection clipboard',
265-
['"'] = 'last deleted, changed, or yanked content',
266-
['0'] = 'last yank',
267-
['-'] = 'deleted or changed content smaller than one line',
268-
['.'] = 'last inserted text',
269-
['%'] = 'name of the current file',
270-
[':'] = 'most recent executed command',
271-
['#'] = 'alternate buffer',
272-
['='] = 'result of an expression',
273-
['/'] = 'last search pattern',
274-
})
275-
276-
vim.ui.select(choices, {
277-
prompt = 'Select a register> ',
278-
format_item = function(choice)
279-
return choice.key .. ' - ' .. choice.value
280-
end,
281-
}, function(choice)
282-
callback(choice and choice.key)
283-
end)
284-
end,
285-
resolve = function(input)
286-
input = input or '+'
287-
return {
288-
context.register(input),
289-
}
290-
end,
291-
},
292-
quickfix = {
293-
description = 'Includes quickfix list file contents in chat context.',
294-
resolve = function()
295-
return context.quickfix()
296-
end,
297-
},
298-
},
111+
contexts = require('CopilotChat.config.contexts'),
299112

300113
-- default prompts
301-
prompts = {
302-
Explain = {
303-
prompt = '> /COPILOT_EXPLAIN\n\nWrite an explanation for the selected code as paragraphs of text.',
304-
},
305-
Review = {
306-
prompt = '> /COPILOT_REVIEW\n\nReview the selected code.',
307-
callback = function(response, source)
308-
local diagnostics = {}
309-
for line in response:gmatch('[^\r\n]+') do
310-
if line:find('^line=') then
311-
local start_line = nil
312-
local end_line = nil
313-
local message = nil
314-
local single_match, message_match = line:match('^line=(%d+): (.*)$')
315-
if not single_match then
316-
local start_match, end_match, m_message_match = line:match('^line=(%d+)-(%d+): (.*)$')
317-
if start_match and end_match then
318-
start_line = tonumber(start_match)
319-
end_line = tonumber(end_match)
320-
message = m_message_match
321-
end
322-
else
323-
start_line = tonumber(single_match)
324-
end_line = start_line
325-
message = message_match
326-
end
327-
328-
if start_line and end_line then
329-
table.insert(diagnostics, {
330-
lnum = start_line - 1,
331-
end_lnum = end_line - 1,
332-
col = 0,
333-
message = message,
334-
severity = vim.diagnostic.severity.WARN,
335-
source = 'Copilot Review',
336-
})
337-
end
338-
end
339-
end
340-
vim.diagnostic.set(
341-
vim.api.nvim_create_namespace('copilot_diagnostics'),
342-
source.bufnr,
343-
diagnostics
344-
)
345-
end,
346-
},
347-
Fix = {
348-
prompt = '> /COPILOT_GENERATE\n\nThere is a problem in this code. Rewrite the code to show it with the bug fixed.',
349-
},
350-
Optimize = {
351-
prompt = '> /COPILOT_GENERATE\n\nOptimize the selected code to improve performance and readability.',
352-
},
353-
Docs = {
354-
prompt = '> /COPILOT_GENERATE\n\nPlease add documentation comments to the selected code.',
355-
},
356-
Tests = {
357-
prompt = '> /COPILOT_GENERATE\n\nPlease generate tests for my code.',
358-
},
359-
Commit = {
360-
prompt = '> #git:staged\n\nWrite commit message for the change with commitizen convention. Make sure the title has maximum 50 characters and message is wrapped at 72 characters. Wrap the whole message in code block with language gitcommit.',
361-
},
362-
},
114+
prompts = prompts,
363115

364116
-- default mappings
365-
mappings = {
366-
complete = {
367-
insert = '<Tab>',
368-
},
369-
close = {
370-
normal = 'q',
371-
insert = '<C-c>',
372-
},
373-
reset = {
374-
normal = '<C-l>',
375-
insert = '<C-l>',
376-
},
377-
submit_prompt = {
378-
normal = '<CR>',
379-
insert = '<C-s>',
380-
},
381-
toggle_sticky = {
382-
detail = 'Makes line under cursor sticky or deletes sticky line.',
383-
normal = 'gr',
384-
},
385-
accept_diff = {
386-
normal = '<C-y>',
387-
insert = '<C-y>',
388-
},
389-
jump_to_diff = {
390-
normal = 'gj',
391-
},
392-
quickfix_answers = {
393-
normal = 'gqa',
394-
},
395-
quickfix_diffs = {
396-
normal = 'gqd',
397-
},
398-
yank_diff = {
399-
normal = 'gy',
400-
register = '"', -- Default register to use for yanking
401-
},
402-
show_diff = {
403-
normal = 'gd',
404-
full_diff = false, -- Show full diff instead of unified diff when showing diff window
405-
},
406-
show_info = {
407-
normal = 'gi',
408-
},
409-
show_context = {
410-
normal = 'gc',
411-
},
412-
show_help = {
413-
normal = 'gh',
414-
},
415-
},
117+
mappings = require('CopilotChat.config.mappings'),
416118
}

0 commit comments

Comments
 (0)