Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Feat/add GitHub copilot subscription#384

Open
yashksaini-coder wants to merge 26 commits intoNano-Collective:mainfrom
yashksaini-coder:feat/add-github-copilot-subscription
Open

Feat/add GitHub copilot subscription#384
yashksaini-coder wants to merge 26 commits intoNano-Collective:mainfrom
yashksaini-coder:feat/add-github-copilot-subscription

Conversation

@yashksaini-coder
Copy link
Contributor

Description

Adds first-class support for the GitHub Copilot subscription as a model provider in nanocoder. This allows users with Copilot Pro/Pro+/Business subscriptions to use their Copilot allowance via nanocoder, not only the GitHub Models API (which uses token-based billing). The integration includes new authentication (OAuth device flow), token refresh, and a Copilot-compatible provider template. User configuration and provider factory now support Copilot as a subscription-backed OpenAI-compatible provider.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:all completes successfully)
  • Tests cover both success and error scenarios

Manual Testing

  • Tested with Ollama
  • Tested with OpenRouter
  • Tested with OpenAI-compatible API
  • Tested MCP integration (Copilot "login" and provider config)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (user guides + provider references clarify Copilot vs Models)
  • No breaking changes (or clearly documented in migration notes)
  • Appropriate logging added using structured logging (see CONTRIBUTING.md)

Summary of main changes

  • Implements device OAuth flow, storing a Copilot refresh token in a user-scoped credential store
  • Adds provider support for Copilot subscription: including template config, Copilot-aware fetch wrapper, and token refresh logic
  • Updates provider factory and client instantiation to recognize sdkProvider: 'github-copilot'
  • Adds CLI command for OAuth login/refresh
  • Integration tests added for Copilot login flow, credential roundtrip, and template presence

@will-lamerton Hi I've add copilot integration support to the best of my ability, would like to see if it passes the integration support layer properly for nanocoder, tests have also been add, This is first time working on such a change,

yashksaini-coder and others added 18 commits February 27, 2026 20:25
Add manual context length override for models not listed on models.dev.
Resolution order: session override > env variable > models.dev > null.

Closes Nano-Collective#379
…tion

Ollama users configuring 127.0.0.1 instead of localhost experienced connection
failures and misleading errors. Added shared isLocalURL() utility and replaced
broad 'connect' substring match with specific error codes to prevent
misclassifying "disconnect"/"reconnect" as connection failures.

Closes Nano-Collective#366
Copilot AI review requested due to automatic review settings March 1, 2026 08:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds GitHub Copilot subscription-backed support to nanocoder by introducing device-flow auth + credential storage and wiring a new sdkProvider: 'github-copilot' through templates, provider factory, commands, and CLI.

Changes:

  • Add Copilot provider template + config validation/test cases and extend SdkProvider union with 'github-copilot'.
  • Implement Copilot device-flow login UI/command + CLI entrypoint and store a user-scoped Copilot credential.
  • Add provider-factory support that injects Copilot-specific auth headers and token refresh behavior.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
source/wizards/validation.spec.ts Adds config-building test coverage for sdkProvider: 'github-copilot'.
source/wizards/templates/provider-templates.ts Introduces “GitHub Copilot” provider template and config builder.
source/wizards/templates/provider-templates.spec.ts Tests Copilot template defaults and sdkProvider value.
source/types/config.ts Extends SdkProvider union to include github-copilot.
source/hooks/useAppInitialization.tsx Registers the new copilot-login command.
source/config/copilot-credentials.ts Implements user-level persistence for Copilot credentials.
source/config/copilot-credentials.spec.ts Adds tests for Copilot credential store round-trips.
source/commands/index.ts Exports Copilot login command from commands barrel.
source/commands/copilot-login.tsx Adds Ink UI component for device-flow login + polling.
source/commands/copilot-login.spec.tsx Tests command handler returns CopilotLogin element and props.
source/commands/copilot-login-command.tsx Adds /copilot-login command wiring to render the login UI.
source/client-factory.ts Updates connection validation to require Copilot credential instead of apiKey.
source/cli.tsx Adds nanocoder copilot login CLI path to run device-flow without rendering the full App.
source/auth/github-copilot.ts Implements Copilot OAuth device flow + token acquisition/caching helpers.
source/auth/github-copilot.spec.ts Adds tests for URL generation and token caching behavior.
source/ai-sdk-client/providers/provider-factory.ts Adds provider factory branch for github-copilot with custom fetch and auth headers.
source/ai-sdk-client/providers/provider-factory.spec.ts Adds test ensuring missing Copilot credential throws.
scripts/test-copilot.sh Adds a helper script intended to sanity-check build outputs + credential storage.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@will-lamerton
Copy link
Member

Hey @yashksaini-coder, nice work on this! The overall structure is solid and follows existing patterns well. I've got some feedback before this is ready to merge:

Security stuff:

  • The credential file permissions (writeFileSync with mode: 0o600) only apply on file creation. If the file already exists with looser permissions, they won't get tightened. Worth adding an explicit chmod on every write.
  • The token cache key uses only the first 8 chars of the OAuth token (githubOAuthToken.slice(0, 8)) - two different tokens with the same prefix would share a cache entry. Use the full token or a hash instead.
  • Might want to add a clearCopilotTokenCache() export so credentials can actually be invalidated without waiting for expiry.

Naming:

  • refreshToken in CopilotCredential actually stores the OAuth access token. Since this is a brand new feature with no existing users, now's the time to rename it to oauthToken or accessToken before it ships and actually creates a backward-compat burden.

Code duplication:

  • The "No Copilot credentials" error message is defined identically in both provider-factory.ts and client-factory.ts - extract to a shared constant.
  • COPILOT_HEADERS is defined in github-copilot.ts but then re-hardcoded in provider-factory.ts. Import and reuse.
  • The CLI login path in cli.tsx reimplements the device flow inline instead of reusing logic from copilot-login.tsx. Would be cleaner to extract the core flow into a shared function both paths can call.

Robustness:

  • pollForOAuthToken has a while (true) with no timeout or max iterations. If the user never completes the device flow and the server never returns expired_token, this loops forever. Add a timeout (maybe 15 min?).
  • apiKey: 'dummy-key' in the provider factory works because the custom fetch overrides the auth header, but it's fragile - at least drop a comment explaining why it's there.

Tests:

  • The cache test doesn't cover the case where the cached token is expired - worth adding one where expires_at is in the past.
  • The new provider-factory test manipulates process.env.NANOCODER_CONFIG_DIR without test.serial, which could race with other tests. Mark it serial or isolate it differently.
  • test-copilot.sh imports from ./dist/ which couples it to a fresh build. Consider using tsx like the AVA tests do.

Minor:

  • A few new files are missing trailing newlines.
  • Default models gpt-4o,claude-3-5-sonnet-20241022 are aged - could we choose different model defaults?
  • The hardcoded VS Code Copilot OAuth client ID (Iv1.b507a08c87ecfe98) is worth documenting prominently so maintainers know about the external dependency.

Overall the feature design is good - the main blockers are the refreshToken rename, the unbounded polling loop, and the cache key issue. The rest is cleanup. Nice contribution! :D

@will-lamerton
Copy link
Member

Hey @yashksaini-coder, just continuing to test and found a few more issues to address:

1. /copilot-login is broken - the component is frozen on render

The CopilotLogin component uses useState, useEffect, useInput, and <Spinner> - but command output goes through addToChatQueue -> chatComponents -> ChatQueue -> Ink's <Static>. <Static> renders items once and freezes them. That means:

  • The spinner never animates (which is what I see — it's stuck on )
  • The useEffect that calls startDeviceFlow() fires but state updates never re-render
  • The user code / verification URL never appear on screen
  • useInput for "Press Enter to continue" never works

This is an architectural mismatch. The component needs to render as a live component (using setLiveComponent / the liveComponent slot) instead of being added to the chat queue, or the login flow needs to be non-interactive (just print static text and open the browser automatically). Other commands that work fine in <Static> are ones that return a single static React element - not stateful interactive components.

2. The CLI path (nanocoder copilot login) has the same underlying issue as my earlier comment - startDeviceFlow() has no fetch timeout, so it can hang forever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants