Skip to content

fix: surface GitHub Copilot AI provider in Coder Agents chat#26387

Draft
DanielleMaywood wants to merge 1 commit into
mainfrom
fix/copilot-chat-provider-availability
Draft

fix: surface GitHub Copilot AI provider in Coder Agents chat#26387
DanielleMaywood wants to merge 1 commit into
mainfrom
fix/copilot-chat-provider-availability

Conversation

@DanielleMaywood

Copy link
Copy Markdown
Contributor

Note

🤖 This PR was written by Coder Agent on behalf of Danielle Maywood

Problem

After an admin configures a GitHub Copilot AI provider and creates a model for it, the Coder Agents page still shows "set up a provider then add a model" and the model never appears in the selector. Configuring an Anthropic provider + model works.

Root cause

The chat model catalog only surfaces providers it marks available: true. For a Copilot provider, that flag is never set:

  • chatprovider.NormalizeProvider had no copilot case, so "copilot" normalized to "" and was dropped before availability was ever computed (in ResolveUserProviderKeys, ListConfiguredModels, and orderProviders via supportedProviderNames).
  • Even if it were normalized, ResolveUserProviderKeys had no path to mark Copilot available. Copilot rejects API keys by design (coderd/ai_providers.go) and authenticates via request-time GitHub OAuth tokens injected by aibridge, so it can never satisfy the key-based availability check. The only keyless ("ambient credentials") path was hard-coded to Bedrock.

Net effect on the frontend: getAvailableProviders filters to provider.available === true, so countConfiguredProviderConfigs and getModelOptionsFromConfigs both drop Copilot, collapsing providerCount/modelCount to 0 and rendering the setup notice. Anthropic works only because it carries a stored API key.

Execution was never the problem: chatd already routes Copilot through the AI Gateway via the OpenAI-compatible default branch of fantasyConfigForAIBridge, with credentials delegated to aibridged.

Fix

In coderd/x/chatd/chatprovider/chatprovider.go:

  • Recognize copilot as a supported provider (NormalizeProvider, supportedProviderNames, display name GitHub Copilot).
  • Treat Copilot like Bedrock's ambient-credential path: ProviderAllowsAmbientCredentials returns true for Copilot, and ResolveUserProviderKeys resolves a configured Copilot provider as available without an API key. A missing GitHub link now surfaces as a runtime error instead of silently hiding the provider.

In site/src/utils/aiProviders.ts:

  • Add a GitHub Copilot display label for the model selector.

Tests

  • TestResolveUserProviderKeys_Copilot — a keyless Copilot provider resolves Available: true with an ambient (empty) key entry.
  • TestListConfiguredModels_Copilot — a Copilot provider + model appears in the catalog and is available.

Both fail on main and pass with this change. Existing TestListChatModels and the full chatprovider package still pass.

Verification
go test ./coderd/x/chatd/chatprovider/ -count=1   # ok
go test ./coderd/ -run TestListChatModels -count=1 # ok
go build ./coderd/... ; go vet ./coderd/x/chatd/chatprovider/ ; gofmt -l (clean)

Notes / follow-ups

  • Availability here means "the provider is configured and routable." It intentionally does not pre-validate that the requesting user has a linked GitHub external-auth token; that failure surfaces at request time, consistent with Bedrock's ambient-credential model. If we want a pre-flight check that the user has a usable GitHub link, that can be a follow-up.

A Copilot AI provider was always reported unavailable in the chat model
catalog. chatprovider.NormalizeProvider had no copilot case, so the
provider normalized to an empty string and was dropped before
availability resolution, and ResolveUserProviderKeys had no path to mark
it available without an API key. Copilot rejects API keys by design and
authenticates via request-time GitHub OAuth tokens injected by aibridge,
so it could never satisfy the key-based availability check.

This left the Agents page showing 'set up a provider then add a model'
even after an admin created a Copilot provider and model, while Anthropic
worked because it carries a stored API key.

Recognize copilot as a supported provider, treat it like Bedrock's
ambient-credential path so it resolves available without a key, and add
its display label on both backend and frontend.
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.

1 participant