Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/inlineChat/browser/inlineChatDefaultModel.ts
5238 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { localize } from '../../../../nls.js';
7
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from '../../../../platform/configuration/common/configurationRegistry.js';
8
import { Registry } from '../../../../platform/registry/common/platform.js';
9
import { registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js';
10
import { Disposable } from '../../../../base/common/lifecycle.js';
11
import { ILanguageModelsService, ILanguageModelChatMetadata } from '../../chat/common/languageModels.js';
12
import { InlineChatConfigKeys } from '../common/inlineChat.js';
13
import { ILogService } from '../../../../platform/log/common/log.js';
14
import { DEFAULT_MODEL_PICKER_CATEGORY } from '../../chat/common/widget/input/modelPickerWidget.js';
15
16
export class InlineChatDefaultModel extends Disposable {
17
static readonly ID = 'workbench.contrib.inlineChatDefaultModel';
18
static readonly configName = InlineChatConfigKeys.DefaultModel;
19
20
static modelIds: string[] = [''];
21
static modelLabels: string[] = [localize('defaultModel', 'Auto (Vendor Default)')];
22
static modelDescriptions: string[] = [localize('defaultModelDescription', 'Use the vendor\'s default model')];
23
24
constructor(
25
@ILanguageModelsService private readonly languageModelsService: ILanguageModelsService,
26
@ILogService private readonly logService: ILogService,
27
) {
28
super();
29
this._register(languageModelsService.onDidChangeLanguageModels(() => this._updateModelValues()));
30
this._updateModelValues();
31
}
32
33
private _updateModelValues(): void {
34
try {
35
// Clear arrays
36
InlineChatDefaultModel.modelIds.length = 0;
37
InlineChatDefaultModel.modelLabels.length = 0;
38
InlineChatDefaultModel.modelDescriptions.length = 0;
39
40
// Add default/empty option
41
InlineChatDefaultModel.modelIds.push('');
42
InlineChatDefaultModel.modelLabels.push(localize('defaultModel', 'Auto (Vendor Default)'));
43
InlineChatDefaultModel.modelDescriptions.push(localize('defaultModelDescription', 'Use the vendor\'s default model'));
44
45
// Get all available models
46
const modelIds = this.languageModelsService.getLanguageModelIds();
47
48
const models: { identifier: string; metadata: ILanguageModelChatMetadata }[] = [];
49
50
// Look up each model's metadata
51
for (const modelId of modelIds) {
52
try {
53
const metadata = this.languageModelsService.lookupLanguageModel(modelId);
54
if (metadata) {
55
models.push({ identifier: modelId, metadata });
56
} else {
57
this.logService.warn(`[InlineChatDefaultModel] No metadata found for model ID: ${modelId}`);
58
}
59
} catch (e) {
60
this.logService.error(`[InlineChatDefaultModel] Error looking up model ${modelId}:`, e);
61
}
62
}
63
64
// Filter models that are:
65
// 1. User selectable
66
// 2. Support tool calling (required for inline chat v2)
67
const supportedModels = models.filter(model => {
68
if (!model.metadata?.isUserSelectable) {
69
return false;
70
}
71
// Check if model supports inline chat - needs tool calling capability
72
if (!model.metadata.capabilities?.toolCalling) {
73
return false;
74
}
75
return true;
76
});
77
78
// Sort by category order, then alphabetically by name within each category
79
supportedModels.sort((a, b) => {
80
const aCategory = a.metadata.modelPickerCategory ?? DEFAULT_MODEL_PICKER_CATEGORY;
81
const bCategory = b.metadata.modelPickerCategory ?? DEFAULT_MODEL_PICKER_CATEGORY;
82
83
// First sort by category order
84
if (aCategory.order !== bCategory.order) {
85
return aCategory.order - bCategory.order;
86
}
87
88
// Then sort by name within the same category
89
return a.metadata.name.localeCompare(b.metadata.name);
90
});
91
92
// Populate arrays with filtered models
93
for (const model of supportedModels) {
94
try {
95
const qualifiedName = `${model.metadata.name} (${model.metadata.vendor})`;
96
InlineChatDefaultModel.modelIds.push(qualifiedName);
97
InlineChatDefaultModel.modelLabels.push(model.metadata.name);
98
InlineChatDefaultModel.modelDescriptions.push(model.metadata.tooltip ?? model.metadata.detail ?? '');
99
} catch (e) {
100
this.logService.error(`[InlineChatDefaultModel] Error adding model ${model.metadata.name}:`, e);
101
}
102
}
103
} catch (e) {
104
this.logService.error('[InlineChatDefaultModel] Error updating model values:', e);
105
}
106
}
107
}
108
109
registerWorkbenchContribution2(InlineChatDefaultModel.ID, InlineChatDefaultModel, WorkbenchPhase.BlockRestore);
110
111
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({
112
...{ id: 'inlineChat', title: localize('inlineChatConfigurationTitle', 'Inline Chat'), order: 30, type: 'object' },
113
properties: {
114
[InlineChatDefaultModel.configName]: {
115
description: 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)'."),
116
type: 'string',
117
default: '',
118
order: 1,
119
enum: InlineChatDefaultModel.modelIds,
120
enumItemLabels: InlineChatDefaultModel.modelLabels,
121
markdownEnumDescriptions: InlineChatDefaultModel.modelDescriptions
122
}
123
}
124
});
125
126