Skip to content

Fix enterprise BYOK issues: hidden models, disabled button, account carryover#309889

Open
pierceboggan wants to merge 2 commits intomainfrom
pierceboggan/fix-enterprise-byok-issues
Open

Fix enterprise BYOK issues: hidden models, disabled button, account carryover#309889
pierceboggan wants to merge 2 commits intomainfrom
pierceboggan/fix-enterprise-byok-issues

Conversation

@pierceboggan
Copy link
Copy Markdown
Contributor

Fixes three bugs reported against #309023 in the BYOK (Bring Your Own Key) model feature:

#309499 — BYOK model hidden by default

byokKnownModelToAPIInfo() was missing isUserSelectable: true, so the view model defaulted newly added BYOK models to hidden (metadata.isUserSelectable ?? false).

Fix: Add isUserSelectable: true to the returned LanguageModelChatInformation.

#309492 — Add Models button disabled when BYOK is enabled

ContextKeysContribution constructor called _inspectContext() and _updatePermissiveSessionContext() on init, but never _updateClientByokEnabledContext(). The BYOK context key was only set on auth changes, so if auth was already established at extension activation, the context key remained unset and clientByokEnabled returned false.

Fix: Call _updateClientByokEnabledContext() during initialization.

#309501 — BYOK model carries over from individual account

BYOK provider registrations were added to the main DisposableStore and never cleaned up on account switch. When switching from an individual account (BYOK enabled) to an enterprise account (BYOK disabled), providers remained registered and models persisted in the picker.

Fix: Use a separate DisposableStore for BYOK provider registrations, clear it when auth changes and BYOK is disabled, and reset the _byokProvidersRegistered flag.


Note: #309495 (rough edges for invalid BYOK flows — no validation warning on add, no UI auto-update on remove) is not addressed in this PR and needs further investigation.

…arryover

Fix three bugs in the BYOK (Bring Your Own Key) model feature:

1. #309499 - BYOK models hidden by default: Add isUserSelectable: true
   to byokKnownModelToAPIInfo() so models appear in the picker on
   registration instead of defaulting to hidden.

2. #309492 - Add Models button disabled when BYOK enabled: Call
   _updateClientByokEnabledContext() during ContextKeysContribution
   initialization so the clientByokEnabled context key is set before
   the Language Models view renders.

3. #309501 - BYOK model carries over from individual account: Use a
   separate DisposableStore for BYOK provider registrations and clear
   them when switching to an account with BYOK disabled, resetting
   the registration flag to allow re-registration on next auth change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 14, 2026 16:10
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

Screenshot Changes

Base: d87671df Current: 981a87b3

Changed (2)

chat/aiCustomizations/aiCustomizationManagementEditor/McpBrowseMode/Dark
Before After
before after
chat/aiCustomizations/aiCustomizationManagementEditor/PromptsTabScrolled/Dark
Before After
before after

Copy link
Copy Markdown
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

Fixes enterprise BYOK (Bring Your Own Key) model integration issues in the Copilot extension so BYOK models appear correctly, the “Add Models” UI enables reliably, and BYOK providers don’t persist across account switches when entitlement changes.

Changes:

  • Initialize the github.copilot.clientByokEnabled context key during activation (not only on auth changes).
  • Track BYOK language model provider registrations in a dedicated DisposableStore and clear them when BYOK becomes disabled on auth change.
  • Mark BYOK known models as user-selectable by default (isUserSelectable: true).
Show a summary per file
File Description
extensions/copilot/src/extension/contextKeys/vscode-node/contextKeys.contribution.ts Sets the BYOK entitlement context key during initialization to avoid a disabled “Add Models” button when auth already exists.
extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts Separates BYOK provider registrations for cleanup on account/entitlement changes.
extensions/copilot/src/extension/byok/common/byokProvider.ts Ensures newly added BYOK models are visible by default in the picker by setting isUserSelectable.

Copilot's findings

Comments suppressed due to low confidence (2)

extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts:67

  • There’s a race if authentication changes while fetchKnownModelList is in-flight: _byokProvidersRegistered is set to true before the await, so a later auth change can clear registrations and set the flag back to false, but the original call can still resume and re-register providers even when BYOK is now disabled. Add a cancellation/version guard (or re-check BYOK enablement + current token after the await) before registering providers, and consider setting _byokProvidersRegistered only once registration is actually committed.
		if (byokEnabled && !this._byokProvidersRegistered) {
			this._byokProvidersRegistered = true;
			// Update known models list from CDN so all providers have the same list
			const knownModels = await this.fetchKnownModelList(this._fetcherService);
			if (this._store.isDisposed) {
				return;
			}
			this._providers.set(OllamaLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OllamaLMProvider, this._byokStorageService));

extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts:64

  • _authChange is invoked without await/.catch() from the constructor and auth-change listener. If fetchKnownModelList (or later provider setup) throws, this will surface as an unhandled promise rejection. Please catch and log errors within _authChange (or ensure call sites use void this._authChange(...).catch(...)) so transient network failures don’t destabilize the extension host.
			// Update known models list from CDN so all providers have the same list
			const knownModels = await this.fetchKnownModelList(this._fetcherService);
			if (this._store.isDisposed) {
  • Files reviewed: 3/3 changed files
  • Comments generated: 1


private async _authChange(authService: IAuthenticationService, instantiationService: IInstantiationService) {
if (authService.copilotToken && isBYOKEnabled(authService.copilotToken, this._capiClientService) && !this._byokProvidersRegistered) {
const byokEnabled = authService.copilotToken && isBYOKEnabled(authService.copilotToken, this._capiClientService);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

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

byokEnabled is derived via authService.copilotToken && ..., which yields boolean | undefined (and relies on truthiness checks). Consider coercing to a strict boolean (e.g. !!authService.copilotToken && ...) so the intent is explicit and the variable’s type stays boolean.

Suggested change
const byokEnabled = authService.copilotToken && isBYOKEnabled(authService.copilotToken, this._capiClientService);
const byokEnabled = !!authService.copilotToken && isBYOKEnabled(authService.copilotToken, this._capiClientService);

Copilot uses AI. Check for mistakes.
roblourens
roblourens previously approved these changes Apr 14, 2026
The Language Models view did not auto-update when:
- Adding a BYOK model with an invalid configuration (error status)
- Removing a BYOK model group

Root cause: _resolveAllLanguageModels only checked model cache changes
to decide whether to fire onDidChangeLanguageModels. When groups were
added/removed but the model set didn't change (e.g., groups with errors
or empty groups), the event never fired and the UI stayed stale.

Fixes:
1. Add _hasGroupStructureChanged to detect group-level changes (count,
   names, statuses) independently of model cache changes
2. Add explicit viewModel.refresh() after delete action, matching the
   pattern already used by the managementCommand path
3. Await configureLanguageModelsProviderGroup in addModelsForVendor and
   refresh the view model after the add flow completes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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