Skip to content

Commit 043ceac

Browse files
authored
implement action to open language models configuration file (microsoft#289059)
1 parent 5c0c389 commit 043ceac

3 files changed

Lines changed: 126 additions & 41 deletions

File tree

src/vs/workbench/contrib/chat/browser/chatManagement/chatManagement.contribution.ts

Lines changed: 122 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { KeyCode } from '../../../../../base/common/keyCodes.js';
77
import { isObject, isString } from '../../../../../base/common/types.js';
88
import { localize, localize2 } from '../../../../../nls.js';
9-
import { Action2, registerAction2 } from '../../../../../platform/actions/common/actions.js';
9+
import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../../platform/actions/common/actions.js';
1010
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
1111
import { SyncDescriptor } from '../../../../../platform/instantiation/common/descriptors.js';
1212
import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
@@ -17,11 +17,28 @@ import { EditorExtensions, IEditorFactoryRegistry, IEditorSerializer } from '../
1717
import { EditorInput } from '../../../../common/editor/editorInput.js';
1818
import { IEditorGroupsService } from '../../../../services/editor/common/editorGroupsService.js';
1919
import { IEditorService } from '../../../../services/editor/common/editorService.js';
20+
import { ResourceContextKey } from '../../../../common/contextkeys.js';
2021
import { ChatContextKeys } from '../../common/actions/chatContextKeys.js';
2122
import { CONTEXT_MODELS_EDITOR, CONTEXT_MODELS_SEARCH_FOCUS, MANAGE_CHAT_COMMAND_ID } from '../../common/constants.js';
2223
import { CHAT_CATEGORY } from '../actions/chatActions.js';
2324
import { ChatManagementEditor, ModelsManagementEditor } from './chatManagementEditor.js';
2425
import { ChatManagementEditorInput, ModelsManagementEditorInput } from './chatManagementEditorInput.js';
26+
import { ILanguageModelsConfigurationService } from '../../common/languageModelsConfiguration.js';
27+
import { Codicon } from '../../../../../base/common/codicons.js';
28+
import { registerIcon } from '../../../../../platform/theme/common/iconRegistry.js';
29+
import { Disposable } from '../../../../../base/common/lifecycle.js';
30+
import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../../common/contributions.js';
31+
32+
const languageModelsOpenSettingsIcon = registerIcon('language-models-open-settings', Codicon.goToFile, localize('languageModelsOpenSettings', 'Icon for open language models settings commands.'));
33+
34+
const LANGUAGE_MODELS_ENTITLEMENT_PRECONDITION = ContextKeyExpr.and(ChatContextKeys.enabled, ContextKeyExpr.or(
35+
ChatContextKeys.Entitlement.planFree,
36+
ChatContextKeys.Entitlement.planPro,
37+
ChatContextKeys.Entitlement.planProPlus,
38+
ChatContextKeys.Entitlement.planBusiness,
39+
ChatContextKeys.Entitlement.planEnterprise,
40+
ChatContextKeys.Entitlement.internal
41+
));
2542

2643
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane(
2744
EditorPaneDescriptor.create(
@@ -100,49 +117,113 @@ function sanitizeOpenManageCopilotEditorArgs(input: unknown): IOpenManageCopilot
100117
};
101118
}
102119

103-
registerAction2(class extends Action2 {
104-
constructor() {
105-
super({
106-
id: MANAGE_CHAT_COMMAND_ID,
107-
title: localize2('openAiManagement', "Manage Language Models"),
108-
category: CHAT_CATEGORY,
109-
precondition: ContextKeyExpr.and(ChatContextKeys.enabled, ContextKeyExpr.or(
110-
ChatContextKeys.Entitlement.planFree,
111-
ChatContextKeys.Entitlement.planPro,
112-
ChatContextKeys.Entitlement.planProPlus,
113-
ChatContextKeys.Entitlement.planBusiness,
114-
ChatContextKeys.Entitlement.planEnterprise,
115-
ChatContextKeys.Entitlement.internal
116-
)),
117-
f1: true,
118-
});
120+
class ChatManagementActionsContribution extends Disposable implements IWorkbenchContribution {
121+
122+
static readonly ID = 'workbench.contrib.chatManagementActions';
123+
124+
constructor(
125+
@ILanguageModelsConfigurationService private readonly languageModelsConfigurationService: ILanguageModelsConfigurationService,
126+
) {
127+
super();
128+
this.registerChatManagementActions();
129+
this.registerLanguageModelsEditorTitleActions();
119130
}
120-
async run(accessor: ServicesAccessor, args: string | IOpenManageCopilotEditorActionOptions) {
121-
const editorGroupsService = accessor.get(IEditorGroupsService);
122-
args = sanitizeOpenManageCopilotEditorArgs(args);
123-
return editorGroupsService.activeGroup.openEditor(new ModelsManagementEditorInput(), { pinned: true });
131+
132+
private registerChatManagementActions() {
133+
this._register(registerAction2(class extends Action2 {
134+
constructor() {
135+
super({
136+
id: MANAGE_CHAT_COMMAND_ID,
137+
title: localize2('openAiManagement', "Manage Language Models"),
138+
category: CHAT_CATEGORY,
139+
precondition: LANGUAGE_MODELS_ENTITLEMENT_PRECONDITION,
140+
f1: true,
141+
});
142+
}
143+
async run(accessor: ServicesAccessor, args: string | IOpenManageCopilotEditorActionOptions) {
144+
const editorGroupsService = accessor.get(IEditorGroupsService);
145+
args = sanitizeOpenManageCopilotEditorArgs(args);
146+
return editorGroupsService.activeGroup.openEditor(new ModelsManagementEditorInput(), { pinned: true });
147+
}
148+
}));
149+
150+
this._register(registerAction2(class extends Action2 {
151+
constructor() {
152+
super({
153+
id: 'chat.models.action.clearSearchResults',
154+
precondition: CONTEXT_MODELS_EDITOR,
155+
keybinding: {
156+
primary: KeyCode.Escape,
157+
weight: KeybindingWeight.EditorContrib,
158+
when: CONTEXT_MODELS_SEARCH_FOCUS
159+
},
160+
title: localize2('models.clearResults', "Clear Models Search Results")
161+
});
162+
}
163+
164+
run(accessor: ServicesAccessor) {
165+
const activeEditorPane = accessor.get(IEditorService).activeEditorPane;
166+
if (activeEditorPane instanceof ModelsManagementEditor) {
167+
activeEditorPane.clearSearch();
168+
}
169+
return null;
170+
}
171+
}));
172+
173+
this._register(registerAction2(class extends Action2 {
174+
constructor() {
175+
super({
176+
id: 'workbench.action.openLanguageModelsJson',
177+
title: localize2('openLanguageModelsJson', "Open Language Models (JSON)"),
178+
category: CHAT_CATEGORY,
179+
precondition: LANGUAGE_MODELS_ENTITLEMENT_PRECONDITION,
180+
f1: true,
181+
});
182+
}
183+
184+
async run(accessor: ServicesAccessor) {
185+
const languageModelsConfigurationService = accessor.get(ILanguageModelsConfigurationService);
186+
await languageModelsConfigurationService.configureLanguageModels();
187+
}
188+
}));
124189
}
125-
});
126-
127-
registerAction2(class extends Action2 {
128-
constructor() {
129-
super({
130-
id: 'chat.models.action.clearSearchResults',
131-
precondition: CONTEXT_MODELS_EDITOR,
132-
keybinding: {
133-
primary: KeyCode.Escape,
134-
weight: KeybindingWeight.EditorContrib,
135-
when: CONTEXT_MODELS_SEARCH_FOCUS
190+
191+
private registerLanguageModelsEditorTitleActions() {
192+
const modelsConfigurationFile = this.languageModelsConfigurationService.configurationFile;
193+
const openModelsManagementEditorWhen = ContextKeyExpr.and(
194+
CONTEXT_MODELS_EDITOR.toNegated(),
195+
ResourceContextKey.Resource.isEqualTo(modelsConfigurationFile.toString()),
196+
ContextKeyExpr.not('isInDiffEditor'),
197+
LANGUAGE_MODELS_ENTITLEMENT_PRECONDITION
198+
);
199+
200+
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
201+
command: {
202+
id: MANAGE_CHAT_COMMAND_ID,
203+
title: localize2('openAiManagement', "Manage Language Models"),
204+
icon: languageModelsOpenSettingsIcon
136205
},
137-
title: localize2('models.clearResults', "Clear Models Search Results")
206+
when: openModelsManagementEditorWhen,
207+
group: 'navigation',
208+
order: 1
138209
});
139-
}
140210

141-
run(accessor: ServicesAccessor) {
142-
const activeEditorPane = accessor.get(IEditorService).activeEditorPane;
143-
if (activeEditorPane instanceof ModelsManagementEditor) {
144-
activeEditorPane.clearSearch();
145-
}
146-
return null;
211+
const openLanguageModelsJsonWhen = ContextKeyExpr.and(
212+
CONTEXT_MODELS_EDITOR,
213+
LANGUAGE_MODELS_ENTITLEMENT_PRECONDITION
214+
);
215+
216+
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
217+
command: {
218+
id: 'workbench.action.openLanguageModelsJson',
219+
title: localize2('openLanguageModelsJson', "Open Language Models (JSON)"),
220+
icon: languageModelsOpenSettingsIcon
221+
},
222+
when: openLanguageModelsJsonWhen,
223+
group: 'navigation',
224+
order: 1
225+
});
147226
}
148-
});
227+
}
228+
229+
registerWorkbenchContribution2(ChatManagementActionsContribution.ID, ChatManagementActionsContribution, WorkbenchPhase.AfterRestored);

src/vs/workbench/contrib/chat/browser/languageModelsConfigurationService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class LanguageModelsConfigurationService extends Disposable implements IL
3434
declare _serviceBrand: undefined;
3535

3636
private readonly modelsConfigurationFile: URI;
37+
get configurationFile(): URI { return this.modelsConfigurationFile; }
3738

3839
private readonly _onDidChangeLanguageModelGroups = new Emitter<void>();
3940
readonly onDidChangeLanguageModelGroups: Event<void> = this._onDidChangeLanguageModelGroups.event;

src/vs/workbench/contrib/chat/common/languageModelsConfiguration.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Event } from '../../../../base/common/event.js';
7+
import { URI } from '../../../../base/common/uri.js';
78
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
89
import { IRange } from '../../../../editor/common/core/range.js';
910
import { IStringDictionary } from '../../../../base/common/collections.js';
@@ -13,6 +14,8 @@ export const ILanguageModelsConfigurationService = createDecorator<ILanguageMode
1314
export interface ILanguageModelsConfigurationService {
1415
readonly _serviceBrand: undefined;
1516

17+
readonly configurationFile: URI;
18+
1619
readonly onDidChangeLanguageModelGroups: Event<void>;
1720

1821
getLanguageModelsProviderGroups(): readonly ILanguageModelsProviderGroup[];

0 commit comments

Comments
 (0)