Fix enterprise BYOK issues: hidden models, disabled button, account carryover#309889
Open
pierceboggan wants to merge 2 commits intomainfrom
Open
Fix enterprise BYOK issues: hidden models, disabled button, account carryover#309889pierceboggan wants to merge 2 commits intomainfrom
pierceboggan wants to merge 2 commits intomainfrom
Conversation
…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>
Contributor
Contributor
There was a problem hiding this comment.
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.clientByokEnabledcontext key during activation (not only on auth changes). - Track BYOK language model provider registrations in a dedicated
DisposableStoreand 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
fetchKnownModelListis in-flight:_byokProvidersRegisteredis set totruebefore theawait, so a later auth change can clear registrations and set the flag back tofalse, 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_byokProvidersRegisteredonly 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
_authChangeis invoked withoutawait/.catch()from the constructor and auth-change listener. IffetchKnownModelList(or later provider setup) throws, this will surface as an unhandled promise rejection. Please catch and log errors within_authChange(or ensure call sites usevoid 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); |
There was a problem hiding this comment.
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); |
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>
Yoyokrazy
approved these changes
Apr 14, 2026
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.
Fixes three bugs reported against #309023 in the BYOK (Bring Your Own Key) model feature:
#309499 — BYOK model hidden by default
byokKnownModelToAPIInfo()was missingisUserSelectable: true, so the view model defaulted newly added BYOK models to hidden (metadata.isUserSelectable ?? false).Fix: Add
isUserSelectable: trueto the returnedLanguageModelChatInformation.#309492 — Add Models button disabled when BYOK is enabled
ContextKeysContributionconstructor 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 andclientByokEnabledreturnedfalse.Fix: Call
_updateClientByokEnabledContext()during initialization.#309501 — BYOK model carries over from individual account
BYOK provider registrations were added to the main
DisposableStoreand 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
DisposableStorefor BYOK provider registrations, clear it when auth changes and BYOK is disabled, and reset the_byokProvidersRegisteredflag.