The GitHub Copilot provider pins two things that are not actually constant, which makes it unusable on GitHub Enterprise and sends non-Individual tokens to the wrong host.
Branch with the change:
main...ivseb:feat/copilot-enterprise
(Opening this as an issue rather than a PR — pull request creation is rejected on this repo, same as #78.)
The two problems
1. The inference host is not always api.githubcopilot.com. Copilot routes Individual, Business and Enterprise subscribers to different hosts. The host is carried in the Copilot token itself as proxy-ep=proxy.<tenant>.githubcopilot.com, and the token-exchange response can also name it directly — CopilotTokenResponse.endpoints.api is already declared in GitHubCopilotAuthService.ts but never read. Today baseURL is hardcoded, so anything other than an Individual subscription talks to a host its token does not belong to.
2. Enterprise deployments serve OAuth and token exchange from their own domain. DEVICE_CODE_URL, ACCESS_TOKEN_URL and COPILOT_TOKEN_URL all point at github.com / api.github.com, so on a GitHub Enterprise Server or GHE.com account sign-in cannot complete at all.
What the branch does
Resolves the inference host per request, most authoritative source first:
endpoints.api from the token response (declared, previously unused)
- the
proxy-ep field inside the token — survives a restart, since the token is persisted
- the configured deployment, else the existing github.com default
This is applied inside getCopilotFetch() rather than the constructor, because the OpenAI SDK pins baseURL at construction time — before any token exists, and it would never pick up a host change on refresh.
Adds an optional githubCopilotEnterpriseDomain setting (a field next to the existing custom client ID, empty = github.com). Device-flow and token-exchange URLs are derived from it, and it handles both Enterprise conventions, which differ:
| Deployment |
Token exchange |
| github.com |
https://api.github.com/copilot_internal/v2/token |
| GHE.com (Enterprise Cloud, data residency) |
https://api.<domain>/copilot_internal/v2/token |
| GitHub Enterprise Server (self-hosted) |
https://<host>/api/v3/copilot_internal/v2/token |
Input is normalized, so pasting https://github.acme.com/ or github.acme.com both work.
Defaults are unchanged. An empty domain reproduces the previous URLs exactly, so existing Individual setups are byte-for-byte unaffected — the only behavioural change for them is that the host now comes from their own token instead of a constant, which resolves to the same value.
Verification
npm run typecheck clean, eslint clean on the five touched files, production build succeeds. URL construction and proxy-ep extraction checked for github.com, GHES and GHE.com.
What I have not done: run it against a live Enterprise instance. The endpoint shapes follow GitHub's documented conventions (/api/v3 for GHES, api. subdomain for GHE.com), but they are not yet confirmed end-to-end. I do have access to a GitHub Enterprise Server instance and I'm happy to test the branch there and report back before you take any of it — just say the word and I'll do that first.
Tests
Same situation as #78: there are no *.test.ts files in this repository, so I couldn't extend the suite. normalizeEnterpriseDomain(), copilotEndpoints() and apiBaseFromCopilotToken() are exported as pure functions specifically so they're trivial to unit test — happy to write those if you tell me where they should live to match your private tree.
Smaller thing spotted nearby
CopilotTokenResponse.endpoints was typed but never read. The branch now uses it as the first-choice host; if it was left unused deliberately, drop that line and the proxy-ep fallback still covers every case I could find.
The GitHub Copilot provider pins two things that are not actually constant, which makes it unusable on GitHub Enterprise and sends non-Individual tokens to the wrong host.
Branch with the change:
main...ivseb:feat/copilot-enterprise
(Opening this as an issue rather than a PR — pull request creation is rejected on this repo, same as #78.)
The two problems
1. The inference host is not always
api.githubcopilot.com. Copilot routes Individual, Business and Enterprise subscribers to different hosts. The host is carried in the Copilot token itself asproxy-ep=proxy.<tenant>.githubcopilot.com, and the token-exchange response can also name it directly —CopilotTokenResponse.endpoints.apiis already declared inGitHubCopilotAuthService.tsbut never read. TodaybaseURLis hardcoded, so anything other than an Individual subscription talks to a host its token does not belong to.2. Enterprise deployments serve OAuth and token exchange from their own domain.
DEVICE_CODE_URL,ACCESS_TOKEN_URLandCOPILOT_TOKEN_URLall point at github.com / api.github.com, so on a GitHub Enterprise Server or GHE.com account sign-in cannot complete at all.What the branch does
Resolves the inference host per request, most authoritative source first:
endpoints.apifrom the token response (declared, previously unused)proxy-epfield inside the token — survives a restart, since the token is persistedThis is applied inside
getCopilotFetch()rather than the constructor, because the OpenAI SDK pinsbaseURLat construction time — before any token exists, and it would never pick up a host change on refresh.Adds an optional
githubCopilotEnterpriseDomainsetting (a field next to the existing custom client ID, empty = github.com). Device-flow and token-exchange URLs are derived from it, and it handles both Enterprise conventions, which differ:https://api.github.com/copilot_internal/v2/tokenhttps://api.<domain>/copilot_internal/v2/tokenhttps://<host>/api/v3/copilot_internal/v2/tokenInput is normalized, so pasting
https://github.acme.com/orgithub.acme.comboth work.Defaults are unchanged. An empty domain reproduces the previous URLs exactly, so existing Individual setups are byte-for-byte unaffected — the only behavioural change for them is that the host now comes from their own token instead of a constant, which resolves to the same value.
Verification
npm run typecheckclean,eslintclean on the five touched files, production build succeeds. URL construction andproxy-epextraction checked for github.com, GHES and GHE.com.What I have not done: run it against a live Enterprise instance. The endpoint shapes follow GitHub's documented conventions (
/api/v3for GHES,api.subdomain for GHE.com), but they are not yet confirmed end-to-end. I do have access to a GitHub Enterprise Server instance and I'm happy to test the branch there and report back before you take any of it — just say the word and I'll do that first.Tests
Same situation as #78: there are no
*.test.tsfiles in this repository, so I couldn't extend the suite.normalizeEnterpriseDomain(),copilotEndpoints()andapiBaseFromCopilotToken()are exported as pure functions specifically so they're trivial to unit test — happy to write those if you tell me where they should live to match your private tree.Smaller thing spotted nearby
CopilotTokenResponse.endpointswas typed but never read. The branch now uses it as the first-choice host; if it was left unused deliberately, drop that line and theproxy-epfallback still covers every case I could find.