Path: blob/main/src/vs/workbench/contrib/inlineChat/browser/inlineChatDefaultModel.ts
5238 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { localize } from '../../../../nls.js';6import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../../platform/configuration/common/configurationRegistry.js';7import { Registry } from '../../../../platform/registry/common/platform.js';8import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js';9import { Disposable } from '../../../../base/common/lifecycle.js';10import { ILanguageModelsService, ILanguageModelChatMetadata } from '../../chat/common/languageModels.js';11import { InlineChatConfigKeys } from '../common/inlineChat.js';12import { ILogService } from '../../../../platform/log/common/log.js';13import { DEFAULT_MODEL_PICKER_CATEGORY } from '../../chat/common/widget/input/modelPickerWidget.js';1415export class InlineChatDefaultModel extends Disposable {16static readonly ID = 'workbench.contrib.inlineChatDefaultModel';17static readonly configName = InlineChatConfigKeys.DefaultModel;1819static modelIds: string[] = [''];20static modelLabels: string[] = [localize('defaultModel', 'Auto (Vendor Default)')];21static modelDescriptions: string[] = [localize('defaultModelDescription', 'Use the vendor\'s default model')];2223constructor(24@ILanguageModelsService private readonly languageModelsService: ILanguageModelsService,25@ILogService private readonly logService: ILogService,26) {27super();28this._register(languageModelsService.onDidChangeLanguageModels(() => this._updateModelValues()));29this._updateModelValues();30}3132private _updateModelValues(): void {33try {34// Clear arrays35InlineChatDefaultModel.modelIds.length = 0;36InlineChatDefaultModel.modelLabels.length = 0;37InlineChatDefaultModel.modelDescriptions.length = 0;3839// Add default/empty option40InlineChatDefaultModel.modelIds.push('');41InlineChatDefaultModel.modelLabels.push(localize('defaultModel', 'Auto (Vendor Default)'));42InlineChatDefaultModel.modelDescriptions.push(localize('defaultModelDescription', 'Use the vendor\'s default model'));4344// Get all available models45const modelIds = this.languageModelsService.getLanguageModelIds();4647const models: { identifier: string; metadata: ILanguageModelChatMetadata }[] = [];4849// Look up each model's metadata50for (const modelId of modelIds) {51try {52const metadata = this.languageModelsService.lookupLanguageModel(modelId);53if (metadata) {54models.push({ identifier: modelId, metadata });55} else {56this.logService.warn(`[InlineChatDefaultModel] No metadata found for model ID: ${modelId}`);57}58} catch (e) {59this.logService.error(`[InlineChatDefaultModel] Error looking up model ${modelId}:`, e);60}61}6263// Filter models that are:64// 1. User selectable65// 2. Support tool calling (required for inline chat v2)66const supportedModels = models.filter(model => {67if (!model.metadata?.isUserSelectable) {68return false;69}70// Check if model supports inline chat - needs tool calling capability71if (!model.metadata.capabilities?.toolCalling) {72return false;73}74return true;75});7677// Sort by category order, then alphabetically by name within each category78supportedModels.sort((a, b) => {79const aCategory = a.metadata.modelPickerCategory ?? DEFAULT_MODEL_PICKER_CATEGORY;80const bCategory = b.metadata.modelPickerCategory ?? DEFAULT_MODEL_PICKER_CATEGORY;8182// First sort by category order83if (aCategory.order !== bCategory.order) {84return aCategory.order - bCategory.order;85}8687// Then sort by name within the same category88return a.metadata.name.localeCompare(b.metadata.name);89});9091// Populate arrays with filtered models92for (const model of supportedModels) {93try {94const qualifiedName = `${model.metadata.name} (${model.metadata.vendor})`;95InlineChatDefaultModel.modelIds.push(qualifiedName);96InlineChatDefaultModel.modelLabels.push(model.metadata.name);97InlineChatDefaultModel.modelDescriptions.push(model.metadata.tooltip ?? model.metadata.detail ?? '');98} catch (e) {99this.logService.error(`[InlineChatDefaultModel] Error adding model ${model.metadata.name}:`, e);100}101}102} catch (e) {103this.logService.error('[InlineChatDefaultModel] Error updating model values:', e);104}105}106}107108registerWorkbenchContribution2(InlineChatDefaultModel.ID, InlineChatDefaultModel, WorkbenchPhase.BlockRestore);109110Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({111...{ id: 'inlineChat', title: localize('inlineChatConfigurationTitle', 'Inline Chat'), order: 30, type: 'object' },112properties: {113[InlineChatDefaultModel.configName]: {114description: localize('inlineChatDefaultModelDescription', "Select the default language model to use for inline chat from the available providers. Model names may include the provider in parentheses, for example 'Claude Haiku 4.5 (copilot)'."),115type: 'string',116default: '',117order: 1,118enum: InlineChatDefaultModel.modelIds,119enumItemLabels: InlineChatDefaultModel.modelLabels,120markdownEnumDescriptions: InlineChatDefaultModel.modelDescriptions121}122}123});124125126