Skip to content
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3355,6 +3355,15 @@
],
"markdownDescription": "%github.copilot.config.imageUpload.enabled%"
},
"github.copilot.chat.modelPickerVendorOrdering": {
"type": "boolean",
"default": false,
"markdownDescription": "Enable vendor-prioritized ordering in the model picker (OpenAI → Anthropic → Gemini → others).",
"tags": [
"experimental",
"onExp"
]
},
"github.copilot.chat.codeGeneration.instructions": {
"markdownDeprecationMessage": "%github.copilot.config.codeGeneration.instructions.deprecated%",
"type": "array",
Expand Down
25 changes: 24 additions & 1 deletion src/extension/conversation/vscode-node/languageModelAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CopilotToken } from '../../../platform/authentication/common/copilotTok
import { IBlockedExtensionService } from '../../../platform/chat/common/blockedExtensionService';
import { ChatFetchResponseType, ChatLocation, getErrorDetailsFromChatFetchError } from '../../../platform/chat/common/commonTypes';
import { getTextPart } from '../../../platform/chat/common/globalStringUtils';
import { IConfigurationService } from '../../../platform/configuration/common/configurationService';
import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';
import { EmbeddingType, getWellKnownEmbeddingTypeInfo, IEmbeddingsComputer } from '../../../platform/embeddings/common/embeddingsComputer';
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
import { CustomDataPartMimeTypes } from '../../../platform/endpoint/common/endpointTypes';
Expand Down Expand Up @@ -159,6 +159,24 @@ function getModelCapabilitiesDescription(endpoint: IChatEndpoint): string | unde
return undefined;
}

/**
* Returns a numeric priority for ordering in the model picker.
* Lower values appear first. Top-level featuring remains controlled by
* VS Code's models control manifest; this priority only affects ordering.
*/
function getVendorPriority(modelProvider: string): number {
switch (modelProvider.toLowerCase()) {
case 'openai':
return 0;
case 'anthropic':
return 1;
case 'google':
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

getVendorPriority doesn't match the setting description ("...OpenAI → Anthropic → Gemini...") and will not prioritize BYOK Gemini models because their vendor/provider name is 'Gemini' (see GeminiNativeBYOKLMProvider.providerName = 'Gemini'). Consider handling 'gemini' (and/or more robust matching) so Gemini models actually get priority 2 when this setting is enabled.

Suggested change
case 'google':
case 'google':
case 'gemini':

Copilot uses AI. Check for mistakes.
return 2;
default:
return 3;
}
}

export class LanguageModelAccess extends Disposable implements IExtensionContribution {

readonly id = 'languageModelAccess';
Expand All @@ -180,6 +198,7 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
@IVSCodeExtensionContext private readonly _vsCodeExtensionContext: IVSCodeExtensionContext,
@IAutomodeService private readonly _automodeService: IAutomodeService,
@IExperimentationService private readonly _expService: IExperimentationService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
super();

Expand Down Expand Up @@ -236,6 +255,7 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
}

const models: vscode.LanguageModelChatInformation[] = [];
const vendorOrderingEnabled = this._configurationService.getConfig(ConfigKey.ModelPickerVendorOrdering);
const allEndpoints = await this._endpointProvider.getAllChatEndpoints();
const chatEndpoints = allEndpoints.filter(e => e.showInModelPicker || e.model === 'gpt-4o-mini');
const autoEndpoint = await this._automodeService.resolveAutoModeEndpoint(undefined, allEndpoints);
Expand Down Expand Up @@ -344,6 +364,9 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
},
...buildConfigurationSchema(endpoint),
};
if (vendorOrderingEnabled && !(endpoint instanceof AutoChatEndpoint)) {
(model as vscode.LanguageModelChatInformation & { vendorPriority?: number }).vendorPriority = getVendorPriority(endpoint.modelProvider);
}

models.push(model);

Expand Down
3 changes: 3 additions & 0 deletions src/platform/configuration/common/configurationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,9 @@ export namespace ConfigKey {

export const RateLimitAutoSwitchToAuto = defineSetting<boolean>('chat.rateLimitAutoSwitchToAuto', ConfigType.Simple, false, vBoolean());

/** Enable vendor-prioritized ordering in the model picker */
export const ModelPickerVendorOrdering = defineSetting<boolean>('chat.modelPickerVendorOrdering', ConfigType.Simple, false, vBoolean());

/** Use the Messages API instead of Chat Completions when supported */
export const UseAnthropicMessagesApi = defineSetting<boolean | undefined>('chat.anthropic.useMessagesApi', ConfigType.ExperimentBased, true);
/** Context editing mode for Anthropic Messages API. 'off' disables context editing. */
Expand Down