Skip to content

Commit c426bc9

Browse files
authored
support modelSelector option when running inline chat (#279976)
microsoft/vscode-copilot-evaluation#894
1 parent 898431e commit c426bc9

File tree

3 files changed

+43
-8
lines changed

3 files changed

+43
-8
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,23 @@ export interface ILanguageModelChatSelector {
229229
readonly extension?: ExtensionIdentifier;
230230
}
231231

232+
233+
export function isILanguageModelChatSelector(value: unknown): value is ILanguageModelChatSelector {
234+
if (typeof value !== 'object' || value === null) {
235+
return false;
236+
}
237+
const obj = value as Record<string, unknown>;
238+
return (
239+
(obj.name === undefined || typeof obj.name === 'string') &&
240+
(obj.id === undefined || typeof obj.id === 'string') &&
241+
(obj.vendor === undefined || typeof obj.vendor === 'string') &&
242+
(obj.version === undefined || typeof obj.version === 'string') &&
243+
(obj.family === undefined || typeof obj.family === 'string') &&
244+
(obj.tokens === undefined || typeof obj.tokens === 'number') &&
245+
(obj.extension === undefined || typeof obj.extension === 'object')
246+
);
247+
}
248+
232249
export const ILanguageModelsService = createDecorator<ILanguageModelsService>('ILanguageModelsService');
233250

234251
export interface ILanguageModelChatMetadataAndIdentifier {

src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export class StartSessionAction extends Action2 {
120120
if (arg && InlineChatRunOptions.isInlineChatRunOptions(arg)) {
121121
options = arg;
122122
}
123-
InlineChatController.get(editor)?.run({ ...options });
123+
return InlineChatController.get(editor)?.run({ ...options });
124124
}
125125
}
126126

src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { IChatService } from '../../chat/common/chatService.js';
5858
import { IChatRequestVariableEntry, IDiagnosticVariableEntryFilterData } from '../../chat/common/chatVariableEntries.js';
5959
import { isResponseVM } from '../../chat/common/chatViewModel.js';
6060
import { ChatAgentLocation } from '../../chat/common/constants.js';
61+
import { ILanguageModelChatSelector, ILanguageModelsService, isILanguageModelChatSelector } from '../../chat/common/languageModels.js';
6162
import { isNotebookContainingCellEditor as isNotebookWithCellEditor } from '../../notebook/browser/notebookEditor.js';
6263
import { INotebookEditorService } from '../../notebook/browser/services/notebookEditorService.js';
6364
import { ICellEditOperation } from '../../notebook/common/notebookCommon.js';
@@ -91,16 +92,23 @@ const enum Message {
9192
}
9293

9394
export abstract class InlineChatRunOptions {
95+
9496
initialSelection?: ISelection;
9597
initialRange?: IRange;
9698
message?: string;
9799
attachments?: URI[];
98100
autoSend?: boolean;
99101
existingSession?: Session;
100102
position?: IPosition;
103+
modelSelector?: ILanguageModelChatSelector;
104+
105+
static isInlineChatRunOptions(options: unknown): options is InlineChatRunOptions {
101106

102-
static isInlineChatRunOptions(options: any): options is InlineChatRunOptions {
103-
const { initialSelection, initialRange, message, autoSend, position, existingSession, attachments: attachments } = <InlineChatRunOptions>options;
107+
if (typeof options !== 'object' || options === null) {
108+
return false;
109+
}
110+
111+
const { initialSelection, initialRange, message, autoSend, position, existingSession, attachments, modelSelector } = <InlineChatRunOptions>options;
104112
if (
105113
typeof message !== 'undefined' && typeof message !== 'string'
106114
|| typeof autoSend !== 'undefined' && typeof autoSend !== 'boolean'
@@ -109,9 +117,11 @@ export abstract class InlineChatRunOptions {
109117
|| typeof position !== 'undefined' && !Position.isIPosition(position)
110118
|| typeof existingSession !== 'undefined' && !(existingSession instanceof Session)
111119
|| typeof attachments !== 'undefined' && (!Array.isArray(attachments) || !attachments.every(item => item instanceof URI))
120+
|| typeof modelSelector !== 'undefined' && !isILanguageModelChatSelector(modelSelector)
112121
) {
113122
return false;
114123
}
124+
115125
return true;
116126
}
117127
}
@@ -1270,6 +1280,7 @@ export class InlineChatController2 implements IEditorContribution {
12701280
@IChatAttachmentResolveService private readonly _chatAttachmentResolveService: IChatAttachmentResolveService,
12711281
@IEditorService private readonly _editorService: IEditorService,
12721282
@IMarkerDecorationsService private readonly _markerDecorationsService: IMarkerDecorationsService,
1283+
@ILanguageModelsService private readonly _languageModelService: ILanguageModelsService,
12731284
@IChatService chatService: IChatService,
12741285
) {
12751286

@@ -1520,10 +1531,6 @@ export class InlineChatController2 implements IEditorContribution {
15201531
this._zone.rawValue?.widget.focus();
15211532
}
15221533

1523-
markActiveController() {
1524-
this._isActiveController.set(true, undefined);
1525-
}
1526-
15271534
async run(arg?: InlineChatRunOptions): Promise<boolean> {
15281535
assertType(this._editor.hasModel());
15291536

@@ -1536,7 +1543,7 @@ export class InlineChatController2 implements IEditorContribution {
15361543
existingSession.dispose();
15371544
}
15381545

1539-
this.markActiveController();
1546+
this._isActiveController.set(true, undefined);
15401547

15411548
const session = await this._inlineChatSessions.createSession2(this._editor, uri, CancellationToken.None);
15421549

@@ -1572,6 +1579,17 @@ export class InlineChatController2 implements IEditorContribution {
15721579
}));
15731580
delete arg.attachments;
15741581
}
1582+
if (arg.modelSelector) {
1583+
const id = (await this._languageModelService.selectLanguageModels(arg.modelSelector, false)).sort().at(0);
1584+
if (!id) {
1585+
throw new Error(`No language models found matching selector: ${JSON.stringify(arg.modelSelector)}.`);
1586+
}
1587+
const model = this._languageModelService.lookupLanguageModel(id);
1588+
if (!model) {
1589+
throw new Error(`Language model not loaded: ${id}.`);
1590+
}
1591+
this._zone.value.widget.chatWidget.input.setCurrentLanguageModel({ metadata: model, identifier: id });
1592+
}
15751593
if (arg.message) {
15761594
this._zone.value.widget.chatWidget.setInput(arg.message);
15771595
if (arg.autoSend) {

0 commit comments

Comments
 (0)