diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts index d07caa3ff62..d9327193dda 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts @@ -16,7 +16,7 @@ suite('chat', () => { // Register a dummy default model which is required for a participant request to go through disposables.push(lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [{ id: 'test-lm', name: 'test-lm', diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/lm.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/lm.test.ts index c3cb5879da8..3dbb447a052 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/lm.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/lm.test.ts @@ -41,7 +41,7 @@ suite('lm', function () { try { disposables.push(vscode.lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [testProviderOptions]; }, async provideLanguageModelChatResponse(_model, _messages, _options, progress, _token) { @@ -93,7 +93,7 @@ suite('lm', function () { test('lm request fail', async function () { disposables.push(vscode.lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [testProviderOptions]; }, async provideLanguageModelChatResponse(_model, _messages, _options, _progress, _token) { @@ -120,7 +120,7 @@ suite('lm', function () { const defer = new DeferredPromise(); disposables.push(vscode.lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [testProviderOptions]; }, async provideLanguageModelChatResponse(_model, _messages, _options, _progress, _token) { @@ -158,7 +158,7 @@ suite('lm', function () { test('LanguageModelError instance is not thrown to extensions#235322 (SYNC)', async function () { disposables.push(vscode.lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [testProviderOptions]; }, provideLanguageModelChatResponse(_model, _messages, _options, _progress, _token) { @@ -184,7 +184,7 @@ suite('lm', function () { test('LanguageModelError instance is not thrown to extensions#235322 (ASYNC)', async function () { disposables.push(vscode.lm.registerLanguageModelChatProvider('test-lm-vendor', { - async prepareLanguageModelChatInformation(_options, _token) { + async provideLanguageModelChatInformation(_options, _token) { return [testProviderOptions]; }, async provideLanguageModelChatResponse(_model, _messages, _options, _progress, _token) { diff --git a/src/vs/workbench/api/browser/mainThreadLanguageModels.ts b/src/vs/workbench/api/browser/mainThreadLanguageModels.ts index 078a4954770..3efa20e6f5e 100644 --- a/src/vs/workbench/api/browser/mainThreadLanguageModels.ts +++ b/src/vs/workbench/api/browser/mainThreadLanguageModels.ts @@ -58,8 +58,8 @@ export class MainThreadLanguageModels implements MainThreadLanguageModelsShape { const dipsosables = new DisposableStore(); dipsosables.add(this._chatProviderService.registerLanguageModelProvider(vendor, { onDidChange: Event.filter(this._lmProviderChange.event, e => e.vendor === vendor, dipsosables) as unknown as Event, - prepareLanguageModelChat: async (options, token) => { - const modelsAndIdentifiers = await this._proxy.$prepareLanguageModelProvider(vendor, options, token); + provideLanguageModelChatInfo: async (options, token) => { + const modelsAndIdentifiers = await this._proxy.$provideLanguageModelChatInfo(vendor, options, token); modelsAndIdentifiers.forEach(m => { if (m.metadata.auth) { dipsosables.add(this._registerAuthenticationProvider(m.metadata.extension, m.metadata.auth)); diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 9ba80c72bd3..799392c9e07 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1293,7 +1293,7 @@ export interface MainThreadLanguageModelsShape extends IDisposable { } export interface ExtHostLanguageModelsShape { - $prepareLanguageModelProvider(vendor: string, options: { silent: boolean }, token: CancellationToken): Promise; + $provideLanguageModelChatInfo(vendor: string, options: { silent: boolean }, token: CancellationToken): Promise; $updateModelAccesslist(data: { from: ExtensionIdentifier; to: ExtensionIdentifier; enabled: boolean }[]): void; $startChatRequest(modelId: string, requestId: number, from: ExtensionIdentifier, messages: SerializableObjectWithBuffers, options: { [name: string]: any }, token: CancellationToken): Promise; $acceptResponsePart(requestId: number, chunk: SerializableObjectWithBuffers): Promise; diff --git a/src/vs/workbench/api/common/extHostLanguageModels.ts b/src/vs/workbench/api/common/extHostLanguageModels.ts index 207a410495f..074bd916f43 100644 --- a/src/vs/workbench/api/common/extHostLanguageModels.ts +++ b/src/vs/workbench/api/common/extHostLanguageModels.ts @@ -141,8 +141,8 @@ export class ExtHostLanguageModels implements ExtHostLanguageModelsShape { this._proxy.$registerLanguageModelProvider(vendor); let providerChangeEventDisposable: IDisposable | undefined; - if (provider.onDidChangeLanguageModelInformation) { - providerChangeEventDisposable = provider.onDidChangeLanguageModelInformation(() => { + if (provider.onDidChangeLanguageModelChatInformation) { + providerChangeEventDisposable = provider.onDidChangeLanguageModelChatInformation(() => { this._proxy.$onLMProviderChange(vendor); }); } @@ -164,13 +164,14 @@ export class ExtHostLanguageModels implements ExtHostLanguageModelsShape { }); } - async $prepareLanguageModelProvider(vendor: string, options: { silent: boolean }, token: CancellationToken): Promise { + async $provideLanguageModelChatInfo(vendor: string, options: { silent: boolean }, token: CancellationToken): Promise { const data = this._languageModelProviders.get(vendor); if (!data) { return []; } this._clearModelCache(vendor); - const modelInformation = await data.provider.prepareLanguageModelChatInformation(options, token) ?? []; + // TODO @lramos15 - Remove this old prepare method support in debt week + const modelInformation: vscode.LanguageModelChatInformation[] = (data.provider.provideLanguageModelChatInformation ? await data.provider.provideLanguageModelChatInformation(options, token) : await (data.provider as any).prepareLanguageModelChatInformation(options, token)) ?? []; const modelMetadataAndIdentifier: ILanguageModelChatMetadataAndIdentifier[] = modelInformation.map(m => { let auth; if (m.requiresAuthorization && isProposedApiEnabled(data.extension, 'chatProvider')) { @@ -278,7 +279,7 @@ export class ExtHostLanguageModels implements ExtHostLanguageModelsShape { value = data.provider.provideLanguageModelChatResponse( knownModel.info, messages.value.map(typeConvert.LanguageModelChatMessage2.to), - { ...options, modelOptions: options.modelOptions ?? {}, requestInitiator: ExtensionIdentifier.toKey(from) }, + { ...options, modelOptions: options.modelOptions ?? {}, requestInitiator: ExtensionIdentifier.toKey(from), toolMode: options.toolMode ?? extHostTypes.LanguageModelChatToolMode.Auto }, progress, token ); diff --git a/src/vs/workbench/contrib/chat/common/languageModels.ts b/src/vs/workbench/contrib/chat/common/languageModels.ts index 9e9986c3078..7d69514dfed 100644 --- a/src/vs/workbench/contrib/chat/common/languageModels.ts +++ b/src/vs/workbench/contrib/chat/common/languageModels.ts @@ -204,7 +204,7 @@ export interface ILanguageModelChatResponse { export interface ILanguageModelChatProvider { onDidChange: Event; - prepareLanguageModelChat(options: { silent: boolean }, token: CancellationToken): Promise; + provideLanguageModelChatInfo(options: { silent: boolean }, token: CancellationToken): Promise; sendChatRequest(modelId: string, messages: IChatMessage[], from: ExtensionIdentifier, options: { [name: string]: any }, token: CancellationToken): Promise; provideTokenCount(modelId: string, message: string | IChatMessage, token: CancellationToken): Promise; } @@ -440,7 +440,7 @@ export class LanguageModelsService implements ILanguageModelsService { continue; } try { - let modelsAndIdentifiers = await provider.prepareLanguageModelChat({ silent }, CancellationToken.None); + let modelsAndIdentifiers = await provider.provideLanguageModelChatInfo({ silent }, CancellationToken.None); // This is a bit of a hack, when prompting user if the provider returns any models that are user selectable then we only want to show those and not the entire model list if (!silent && modelsAndIdentifiers.some(m => m.metadata.isUserSelectable)) { modelsAndIdentifiers = modelsAndIdentifiers.filter(m => m.metadata.isUserSelectable || this._modelPickerUserPreferences[m.identifier] === true); diff --git a/src/vs/workbench/contrib/chat/test/common/languageModels.test.ts b/src/vs/workbench/contrib/chat/test/common/languageModels.test.ts index 4826a63f843..e38cabb7e82 100644 --- a/src/vs/workbench/contrib/chat/test/common/languageModels.test.ts +++ b/src/vs/workbench/contrib/chat/test/common/languageModels.test.ts @@ -54,7 +54,7 @@ suite('LanguageModels', function () { store.add(languageModels.registerLanguageModelProvider('test-vendor', { onDidChange: Event.None, - prepareLanguageModelChat: async () => { + provideLanguageModelChatInfo: async () => { const modelMetadata = [ { extension: nullExtensionDescription.identifier, @@ -128,7 +128,7 @@ suite('LanguageModels', function () { store.add(languageModels.registerLanguageModelProvider('actual-vendor', { onDidChange: Event.None, - prepareLanguageModelChat: async () => { + provideLanguageModelChatInfo: async () => { const modelMetadata = [ { extension: nullExtensionDescription.identifier, diff --git a/src/vscode-dts/vscode.d.ts b/src/vscode-dts/vscode.d.ts index 984c56de43a..0f4fa464aaf 100644 --- a/src/vscode-dts/vscode.d.ts +++ b/src/vscode-dts/vscode.d.ts @@ -20378,10 +20378,9 @@ declare module 'vscode' { /** * The provider version of {@linkcode LanguageModelChatRequestOptions} */ - export interface LanguageModelChatRequestHandleOptions { + export interface ProvideLanguageModelChatResponseOptions { /** - * A set of options that control the behavior of the language model. These options are specific to the language model - * and need to be looked up in the respective documentation. + * A set of options that control the behavior of the language model. These options are specific to the language model. */ readonly modelOptions?: { readonly [name: string]: any }; @@ -20399,13 +20398,13 @@ declare module 'vscode' { readonly tools?: readonly LanguageModelChatTool[]; /** - * The tool-selecting mode to use. {@link LanguageModelChatToolMode.Auto} by default. + * The tool-selecting mode to use. The provider must implement respecting this. */ - readonly toolMode?: LanguageModelChatToolMode; + readonly toolMode: LanguageModelChatToolMode; } /** - * All the information representing a single language model contributed by a {@linkcode LanguageModelChatProvider}. + * Represents a language model provided by a {@linkcode LanguageModelChatProvider}. */ export interface LanguageModelChatInformation { @@ -20421,23 +20420,22 @@ declare module 'vscode' { /** * Opaque family-name of the language model. Values might be `gpt-3.5-turbo`, `gpt4`, `phi2`, or `llama` - * but they are defined by extensions contributing languages and subject to change. */ readonly family: string; /** - * The tooltip to render when hovering the model + * The tooltip to render when hovering the model. Used to provide more information about the model. */ readonly tooltip?: string; /** * An optional, human-readable string which will be rendered alongside the model. + * Useful for distinguishing models of the same name in the UI. */ readonly detail?: string; /** - * Opaque version string of the model. This is defined by the extension contributing the language model - * and subject to change while the identifier is stable. + * Opaque version string of the model. * This is used as a lookup value in {@linkcode LanguageModelChatSelector.version} * An example is how GPT 4o has multiple versions like 2024-11-20 and 2024-08-06 */ @@ -20466,7 +20464,7 @@ declare module 'vscode' { /** * Whether tool calling is supported by the model. - * If a number is provided, that is the maximum number of tools a model can call. + * If a number is provided, that is the maximum number of tools that can be provided in a request to the model. */ readonly toolCalling?: boolean | number; }; @@ -20482,7 +20480,7 @@ declare module 'vscode' { readonly role: LanguageModelChatMessageRole; /** - * A string or heterogeneous array of things that a message can contain as content. Some parts may be message-type + * A heterogeneous array of things that a message can contain as content. Some parts may be message-type * specific for some models. */ readonly content: ReadonlyArray; @@ -20504,23 +20502,23 @@ declare module 'vscode' { export type LanguageModelInputPart = LanguageModelTextPart | LanguageModelToolResultPart | LanguageModelToolCallPart; /** - * Represents a Language model chat provider. This provider provides multiple models in a 1 provider to many model relationship - * An example of this would be how an OpenAI provider would provide models like gpt-5, o3, etc. + * A LanguageModelChatProvider implements access to language models, which users can then use through the chat view, or through extension API by acquiring a LanguageModelChat. + * An example of this would be an OpenAI provider that provides models like gpt-5, o3, etc. */ export interface LanguageModelChatProvider { /** - * Signals a change from the provider to the editor so that {@linkcode prepareLanguageModelChatInformation} is called again + * An optional event fired when the available set of language models changes. */ - readonly onDidChangeLanguageModelInformation?: Event; + readonly onDidChangeLanguageModelChatInformation?: Event; /** - * Get the list of available language models contributed by this provider + * Get the list of available language models provided by this provider * @param options Options which specify the calling context of this function - * @param token A cancellation token which signals if the user cancelled the request or not - * @returns A promise that resolves to the list of available language models + * @param token A cancellation token + * @returns The list of available language models */ - prepareLanguageModelChatInformation(options: PrepareLanguageModelChatModelOptions, token: CancellationToken): ProviderResult; + provideLanguageModelChatInformation(options: PrepareLanguageModelChatModelOptions, token: CancellationToken): ProviderResult; /** * Returns the response for a chat request, passing the results to the progress callback. @@ -20529,23 +20527,23 @@ declare module 'vscode' { * @param messages The messages to include in the request * @param options Options for the request * @param progress The progress to emit the streamed response chunks to - * @param token A cancellation token for the request + * @param token A cancellation token * @returns A promise that resolves when the response is complete. Results are actually passed to the progress callback. */ - provideLanguageModelChatResponse(model: T, messages: readonly LanguageModelChatRequestMessage[], options: LanguageModelChatRequestHandleOptions, progress: Progress, token: CancellationToken): Thenable; + provideLanguageModelChatResponse(model: T, messages: readonly LanguageModelChatRequestMessage[], options: ProvideLanguageModelChatResponseOptions, progress: Progress, token: CancellationToken): Thenable; /** - * Returns the number of tokens for a given text using the model specific tokenizer logic + * Returns the number of tokens for a given text using the model-specific tokenizer logic * @param model The language model to use * @param text The text to count tokens for - * @param token A cancellation token for the request - * @returns A promise that resolves to the number of tokens + * @param token A cancellation token + * @returns The number of tokens */ provideTokenCount(model: T, text: string | LanguageModelChatRequestMessage, token: CancellationToken): Thenable; } /** - * The list of options passed into {@linkcode LanguageModelChatProvider.prepareLanguageModelChatInformation} + * The list of options passed into {@linkcode LanguageModelChatProvider.provideLanguageModelChatInformation} */ export interface PrepareLanguageModelChatModelOptions { /** diff --git a/src/vscode-dts/vscode.proposed.chatProvider.d.ts b/src/vscode-dts/vscode.proposed.chatProvider.d.ts index 0b2d508ea18..2eb9c968fba 100644 --- a/src/vscode-dts/vscode.proposed.chatProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.chatProvider.d.ts @@ -10,7 +10,7 @@ declare module 'vscode' { /** * The provider version of {@linkcode LanguageModelChatRequestOptions} */ - export interface LanguageModelChatRequestHandleOptions { + export interface ProvideLanguageModelChatResponseOptions { /** * What extension initiated the request to the language model @@ -39,7 +39,7 @@ declare module 'vscode' { readonly isDefault?: boolean; /** - * Whether or not the model will show up in the model picker immediately upon being made known via {@linkcode LanguageModelChatProvider.prepareLanguageModelChatInformation}. + * Whether or not the model will show up in the model picker immediately upon being made known via {@linkcode LanguageModelChatProvider.provideLanguageModelChatInformation}. * NOT BEING FINALIZED */ readonly isUserSelectable?: boolean; @@ -59,6 +59,6 @@ declare module 'vscode' { export type LanguageModelResponsePart2 = LanguageModelResponsePart | LanguageModelDataPart | LanguageModelThinkingPart; export interface LanguageModelChatProvider { - provideLanguageModelChatResponse(model: T, messages: readonly LanguageModelChatRequestMessage[], options: LanguageModelChatRequestHandleOptions, progress: Progress, token: CancellationToken): Thenable; + provideLanguageModelChatResponse(model: T, messages: readonly LanguageModelChatRequestMessage[], options: ProvideLanguageModelChatResponseOptions, progress: Progress, token: CancellationToken): Thenable; } }