Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/chat/browser/actions/manageModelsActions.ts
3296 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 { coalesce } from '../../../../../base/common/arrays.js';
7
import { Codicon } from '../../../../../base/common/codicons.js';
8
import { DisposableStore } from '../../../../../base/common/lifecycle.js';
9
import { ThemeIcon } from '../../../../../base/common/themables.js';
10
import { localize2 } from '../../../../../nls.js';
11
import { Action2 } from '../../../../../platform/actions/common/actions.js';
12
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
13
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
14
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
15
import { IQuickInputService, IQuickPickItem } from '../../../../../platform/quickinput/common/quickInput.js';
16
import { ChatContextKeys } from '../../common/chatContextKeys.js';
17
import { ILanguageModelChatMetadataAndIdentifier, ILanguageModelsService } from '../../common/languageModels.js';
18
import { CHAT_CATEGORY } from './chatActions.js';
19
20
interface IVendorQuickPickItem extends IQuickPickItem {
21
managementCommand?: string;
22
vendor: string;
23
}
24
25
interface IModelQuickPickItem extends IQuickPickItem {
26
modelId: string;
27
vendor: string;
28
}
29
30
export class ManageModelsAction extends Action2 {
31
static readonly ID = 'workbench.action.chat.manageLanguageModels';
32
33
constructor() {
34
super({
35
id: ManageModelsAction.ID,
36
title: localize2('manageLanguageModels', 'Manage Language Models...'),
37
category: CHAT_CATEGORY,
38
precondition: ContextKeyExpr.and(ChatContextKeys.enabled, ContextKeyExpr.or(
39
ChatContextKeys.Entitlement.planFree,
40
ChatContextKeys.Entitlement.planPro,
41
ChatContextKeys.Entitlement.planProPlus,
42
ChatContextKeys.Entitlement.internal
43
)),
44
f1: true
45
});
46
}
47
override async run(accessor: ServicesAccessor, ...args: any[]): Promise<void> {
48
const languageModelsService = accessor.get(ILanguageModelsService);
49
const quickInputService = accessor.get(IQuickInputService);
50
const commandService = accessor.get(ICommandService);
51
52
const vendors = languageModelsService.getVendors();
53
const store = new DisposableStore();
54
55
const quickPickItems: IVendorQuickPickItem[] = vendors.map(vendor => ({
56
label: vendor.displayName,
57
vendor: vendor.vendor,
58
managementCommand: vendor.managementCommand,
59
buttons: vendor.managementCommand ? [{
60
iconClass: ThemeIcon.asClassName(Codicon.settingsGear),
61
tooltip: `Manage ${vendor.displayName}`
62
}] : undefined
63
}));
64
65
const quickPick = store.add(quickInputService.createQuickPick<IQuickPickItem>());
66
quickPick.title = 'Manage Language Models';
67
quickPick.placeholder = 'Select a provider...';
68
quickPick.items = quickPickItems;
69
quickPick.show();
70
71
store.add(quickPick.onDidAccept(async () => {
72
quickPick.hide();
73
const selectedItem: IVendorQuickPickItem = quickPick.selectedItems[0] as IVendorQuickPickItem;
74
if (selectedItem) {
75
const models: ILanguageModelChatMetadataAndIdentifier[] = coalesce((await languageModelsService.selectLanguageModels({ vendor: selectedItem.vendor }, true)).map(modelIdentifier => {
76
const modelMetadata = languageModelsService.lookupLanguageModel(modelIdentifier);
77
if (!modelMetadata) {
78
return undefined;
79
}
80
return {
81
metadata: modelMetadata,
82
identifier: modelIdentifier,
83
};
84
}));
85
await this.showModelSelectorQuickpick(models, quickInputService, languageModelsService);
86
}
87
}));
88
89
store.add(quickPick.onDidTriggerItemButton(async (event) => {
90
const selectedItem = event.item as IVendorQuickPickItem;
91
const managementCommand = selectedItem.managementCommand;
92
if (managementCommand) {
93
commandService.executeCommand(managementCommand, selectedItem.vendor);
94
}
95
}));
96
97
store.add(quickPick.onDidHide(() => {
98
store.dispose();
99
}));
100
}
101
102
private async showModelSelectorQuickpick(
103
modelsAndIdentifiers: ILanguageModelChatMetadataAndIdentifier[],
104
quickInputService: IQuickInputService,
105
languageModelsService: ILanguageModelsService
106
): Promise<void> {
107
const store = new DisposableStore();
108
const modelItems: IModelQuickPickItem[] = modelsAndIdentifiers.map(model => ({
109
label: model.metadata.name,
110
detail: model.metadata.id,
111
modelId: model.identifier,
112
vendor: model.metadata.vendor,
113
picked: model.metadata.isUserSelectable
114
}));
115
116
if (modelItems.length === 0) {
117
store.dispose();
118
return;
119
}
120
121
const quickPick = quickInputService.createQuickPick<IModelQuickPickItem>();
122
quickPick.items = modelItems;
123
quickPick.title = 'Manage Language Models';
124
quickPick.placeholder = 'Select language models...';
125
quickPick.selectedItems = modelItems.filter(item => item.picked);
126
quickPick.canSelectMany = true;
127
quickPick.show();
128
129
// Handle selection
130
store.add(quickPick.onDidAccept(async () => {
131
quickPick.hide();
132
const items: IModelQuickPickItem[] = quickPick.items as IModelQuickPickItem[];
133
items.forEach(item => {
134
languageModelsService.updateModelPickerPreference(item.modelId, quickPick.selectedItems.includes(item));
135
});
136
}));
137
138
store.add(quickPick.onDidHide(() => {
139
store.dispose();
140
}));
141
}
142
}
143
144