feat: add GitHub Copilot as LLM provider with device flow OAuth#323
Open
maros7 wants to merge 13 commits intocampfirein:mainfrom
Open
feat: add GitHub Copilot as LLM provider with device flow OAuth#323maros7 wants to merge 13 commits intocampfirein:mainfrom
maros7 wants to merge 13 commits intocampfirein:mainfrom
Conversation
Add Copilot OAuth/API constants (client ID, endpoints, scopes) and extend shared transport types to support device flow authentication mode with userCode and verificationUri fields. Co-authored-by: Claude <noreply@anthropic.com>
Implement GitHub OAuth device flow (RFC 8628) for Copilot authentication including device code request, access token polling, and Copilot session token exchange. Includes 12 unit tests covering success paths, error handling, and polling states. Co-authored-by: Claude <noreply@anthropic.com>
Add github-copilot entry to PROVIDER_REGISTRY with device callback mode, priority 8, and default model claude-sonnet-4. Update providerRequiresApiKey to return false for Copilot. Includes registry test coverage. Co-authored-by: Claude <noreply@anthropic.com>
Implement CopilotModelFetcher that fetches available models from the Copilot API using session tokens, register it in the fetcher registry, and add Copilot case to provider config resolver. Includes model fetcher and config resolver test coverage. Co-authored-by: Claude <noreply@anthropic.com>
Extend provider handler to support device flow OAuth: add startDeviceFlow and awaitDeviceFlow methods, refactor callback flow into awaitCallbackFlow, and fix return-await in try/catch for proper error propagation. Includes handler test coverage for all device flow paths. Co-authored-by: Claude <noreply@anthropic.com>
Extend TokenRefreshManager with doCopilotRefresh method that detects device callback mode and exchanges the stored GitHub token for a fresh Copilot session token. Refactor shared error handling into handleRefreshError. Includes 8 new tests for Copilot refresh paths. Co-authored-by: Claude <noreply@anthropic.com>
Implement multi-API routing provider that detects model family from ID and routes to Anthropic SDK for Claude models or OpenAI-compatible SDK for GPT/Gemini/o-series. Injects Copilot session token as bearer auth. Includes 18 tests covering all model families and error paths. Co-authored-by: Claude <noreply@anthropic.com>
Bare AxiosError from exchangeForCopilotToken bypassed isPermanentOAuthError detection, causing revoked tokens (401/403) to be treated as transient errors. Wrap axios errors in ProviderTokenExchangeError with status code to match the pattern used by refresh-token-exchange.ts. Co-authored-by: Claude <noreply@anthropic.com>
Extract duplicated 'Editor-Version' and 'Copilot-Integration-Id' headers into COPILOT_REQUEST_HEADERS constant. Replace hardcoded URL strings with COPILOT_API_BASE_URL in model fetcher. Single source of truth for all Copilot API configuration values. Co-authored-by: Claude <noreply@anthropic.com>
…to token exchange
…ired headers Switch from @ai-sdk/anthropic to @ai-sdk/openai-compatible for all models since the Copilot API only supports OpenAI chat completions format. Add required Copilot headers (Editor-Plugin-Version, User-Agent, openai-intent, x-github-api-version) and update default model to claude-sonnet-4.6.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
github-copilotprovider: OAuth device flow authentication, automatic Copilot token refresh, dynamic model listing from the Copilot API, and OpenAI-compatible chat completions for all models (including Claude, Gemini). CLI and TUI connect flows display the device code for the user to enter at github.com/login/device.devicecallback mode in shared types/events.Type of change
Scope (select all touched areas)
Linked issues
Root cause (bug fixes only, otherwise write
N/A)N/A
Test plan
test/unit/infra/provider-oauth/device-flow.test.ts— 14 tests (device code request, polling, token exchange, error handling)test/unit/infra/llm/providers/github-copilot.test.ts— 18 tests (provider creation, model routing, header injection, error handling)test/unit/infra/http/copilot-model-fetcher.test.ts— 12 tests (model listing, token auth, error handling, empty responses)test/unit/infra/provider-oauth/token-refresh-manager.test.ts— 8 new tests (Copilot token refresh, expiry detection, error wrapping)test/unit/infra/transport/handlers/provider-handler.test.ts— new device flow handler teststest/unit/infra/provider/provider-config-resolver.test.ts— Copilot config resolution teststest/unit/core/domain/entities/provider-registry.test.ts— registry entry teststest/commands/providers/connect.test.ts— CLI connect command device flow testsauthorization_pending,slow_down(interval backoff),expired_token,access_deniedProviderTokenExchangeErrorCopilot-Integration-Id,Editor-Version, etc.)User-visible changes
github-copilotavailable in/providers connectclaude-sonnet-4.6Evidence
npm run lint: 0 errors (69 pre-existing warnings, none from new code)npm run typecheck: cleannpm run build: cleannpm test: 4766 passing, 6 pending, 0 failinggithub-copilot.ts100% lines,device-flow.ts95% lines,token-refresh-manager.ts100% lines,copilot.ts100% lines,CopilotModelFetcher100% lines — all well above 50% minimum/curatewithclaude-sonnet-4.6through Copilot API successfullyChecklist
npm test)npm run lint)npm run typecheck)npm run build)mainRisks and mitigations
src/shared/constants/copilot.ts— a single file to update. Token exchange errors are wrapped inProviderTokenExchangeErrorwith descriptive messages.Iv1.b507a08c87ecfe98is a well-known public ID (used by VS Code, Goose, gpt4free, etc.) but not officially documented for third-party use.