-
Notifications
You must be signed in to change notification settings - Fork 497
feat: add github copilot provider #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c4436a5
to
4d5f123
Compare
i will be very grateful for this |
) | ||
|
||
// GitHub Copilot models available through GitHub's API | ||
var CopilotModels = map[ModelID]Model{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing here, maybe we can call https://api.githubcopilot.com/models
instead of hard coding these here?
All of these configurations should be way simpler than they are now, will find a better way to handle this in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I added TODO comment sitting in the config.go
of the PR to move to a dynamic model polling system for Copilot at least, if not all the providers; however this would require rearchitecting the entire model/provider system.
For now, I wanted to keep the scope of the PR tight so we can at least make sure the agent's prompts work with the copilot supervisor/server-side system prompt on known mainline models.
If you agree that moving to a dynamic provider definition makes sense for the future (similar how avante.nvim
handles config), I'd say we should open a separate issue as it will require a fair amount of work (also to decide the amount of backward compatibility you want to support.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep that makes sense for sure, I would say let's start a discussion thread on this. Would love to understand more how avante.nvin
handles this, the main reason we have the setup we have today is for calculating cost and max token context.
I used to use avante before but it started behaving weird after the introduction of cursor agent mode.
No worries, ironically getting the copilot model files setup was 30 min task, but I had to burn a fair amount of dev hours understanding how the model/provider config system works in order to actually get Just another note, one of the my devs sent me a msg last night that their |
@bryanvaz yeah the whole provider/model config is not ideal and I really want to rework that. I think the biggest issue with the github copilot models is that they are not made to be used outside their stuff but if we figure it out it will be awesome, there is a way to define special provider specific system prompts https://github.com/opencode-ai/opencode/blob/main/internal/llm/prompt/coder.go#L18 maybe tweaking this helps 🤔 |
Added support for Support is experimental for two reasons:
Additional note: @kujtimiihoxha note for future |
I have a feeling I have seen 4o call multiple tools at the same time (don't use OpenAI models that much)🤔 can you maybe share how the tool call looks like from copilot ? |
FYI I will try to dig into this PR later today, thanks again for all the work you put into this. |
I've improved the logging system as part of the PR, in order to properly diagnose the issue. So when you run the PR's build use OPENCODE_DEV_DEBUG="true" opencode -d The request/response messages coming from the api will be written to Essentially the issue with the Copilot API's streaming response, is that there is not method for tool delimination (e.g. Anthropic has {
"id": "msg_vrtx_01SKV5kFauTpBjDsHnX7vdbY",
"choices": [
{
"finish_reason": "tool_calls",
"index": 0,
"logprobs": {
"content": null,
"refusal": null
},
"message": {
"content": "I'll examine the existing customer controller and models to understand the pattern, then create a similar user controller.",
"refusal": "",
"role": "assistant",
"annotations": null,
"audio": {
"id": "",
"data": "",
"expires_at": 0,
"transcript": ""
},
"function_call": {
"arguments": "",
"name": ""
},
"tool_calls": [
{
"id": "toolu_vrtx_01CEjLz5xTHRhGyaM8D9o6Jq",
"function": {
"arguments": "{\"file_path\": \"/Users/bryan/code/work/randoapp/pkg/services/customers_ctlr.go\"}{\"file_path\": \"/Users/bryan/code/work/randoapp/pkg/models/customer.go\"}{\"file_path\": \"/Users/bryan/code/work/randoapp/pkg/models/user.go\"}{\"file_path\": \"/Users/bryan/code/work/randoapp/db/migrations/cstore/20250228010158_CreateUsersTable.up.sql\"}",
"name": "viewviewviewview"
},
"type": "function"
}
]
}
}
],
"created": 1750093719,
"model": "claude-sonnet-4",
"object": "chat.completion",
"service_tier": "",
"system_fingerprint": "",
"usage": {
"completion_tokens": 277,
"prompt_tokens": 22544,
"total_tokens": 22821,
"completion_tokens_details": {
"accepted_prediction_tokens": 0,
"audio_tokens": 0,
"reasoning_tokens": 0,
"rejected_prediction_tokens": 0
},
"prompt_tokens_details": {
"audio_tokens": 0,
"cached_tokens": 0
}
}
} Essentially all 4 view calls becomes |
- ~/.config/github-copilot/[hosts,apps].json | ||
- $XDG_CONFIG_HOME/github-copilot/[hosts,apps].json | ||
|
||
If using an explicit github token, you may either set the $GITHUB_TOKEN environment variable or add it to the opencode.json config file at `providers.copilot.apiKey`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"If using explicit github token" - suggests there is another way. Is there? If not I would change that wording to have just two options - GITHUB_TOKEN variable or opencode.json setting.
Also it would be good to add, which file to use (hosts.json or apps.json), because those contain different tokens.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The primary auth method, and also the recommended method by aider.chat
and avante.nvim
, is to first login to github copilot using an IDE (VSCode, JetBrains, Neovim); then let the agent use the token created by the IDE. This ensures that the token has the required scope, as those IDEs plugins are first party and will always generate a token with the correct scopes.
The GITHUB_TOKEN
env var should only really be used, if you are manually overriding the token for testing, need to toggle between two github copilot accounts (e.g. personal vs work), or the user has sufficient knowledge on how to generate an auth token with the correct scopes. Given that API access to Copilot Chat is not formally documented, documenting manual token generation, and maintaining that documentation is a support task that no one is really interested (Github has taken additional measures to hide the source code for newer revisions, so the fact that we have a Copilot plugin at all is really just us being luck with me having enough free time to reverse engineer one).
As far as which json file has the correct auth token, this is also obfuscated by Github and not documented. Both aider
and third-party neovim
plugins basically guess which file has the correct one based on format. The token searching logic included in this PR is replicated from avante
, but is by no means perfect. In theory, it might be possible preflight each token against the copilot api, but that kind of edge case hand holding is well beyond the scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I get that. But I wasn't sure if this plugin does the search in the github-copilot config files (and I think others might be confused also), or the user should do that and provide the token manually as with other providers inside the opencode.json file (with the env variable as another method).
BTW. Both opencode and your plugin are awesome, thank you all for the work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good
Adds Github Copilot as a provider.
Closes #209, #173
Notes
Tool use with Claude Sonnet 4 currently does not work reliablyClaude 4 works with preview cavetgh
, vscode, ornvim
), or to have prior knowledge on how to obtain a github token.