Path: blob/main/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearchService.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { DeferredPromise, raceCancellation } from '../../../../base/common/async.js';6import { CancellationToken } from '../../../../base/common/cancellation.js';7import { Emitter, Event } from '../../../../base/common/event.js';8import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';9import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';10import { AiSettingsSearchResult, AiSettingsSearchResultKind, IAiSettingsSearchProvider, IAiSettingsSearchService } from './aiSettingsSearch.js';1112export class AiSettingsSearchService extends Disposable implements IAiSettingsSearchService {13readonly _serviceBrand: undefined;14private static readonly MAX_PICKS = 5;1516private _providers: IAiSettingsSearchProvider[] = [];17private _llmRankedResultsPromises: Map<string, DeferredPromise<string[]>> = new Map();18private _embeddingsResultsPromises: Map<string, DeferredPromise<string[]>> = new Map();1920private _onProviderRegistered: Emitter<void> = this._register(new Emitter<void>());21readonly onProviderRegistered: Event<void> = this._onProviderRegistered.event;2223isEnabled(): boolean {24return this._providers.length > 0;25}2627registerSettingsSearchProvider(provider: IAiSettingsSearchProvider): IDisposable {28this._providers.push(provider);29this._onProviderRegistered.fire();30return {31dispose: () => {32const index = this._providers.indexOf(provider);33if (index !== -1) {34this._providers.splice(index, 1);35}36}37};38}3940startSearch(query: string, embeddingsOnly: boolean, token: CancellationToken): void {41if (!this.isEnabled()) {42throw new Error('No settings search providers registered');43}4445this._embeddingsResultsPromises.delete(query);46this._llmRankedResultsPromises.delete(query);4748this._providers.forEach(provider => provider.searchSettings(query, { limit: AiSettingsSearchService.MAX_PICKS, embeddingsOnly }, token));49}5051async getEmbeddingsResults(query: string, token: CancellationToken): Promise<string[] | null> {52if (!this.isEnabled()) {53throw new Error('No settings search providers registered');54}5556const existingPromise = this._embeddingsResultsPromises.get(query);57if (existingPromise) {58const result = await existingPromise.p;59return result ?? null;60}6162const promise = new DeferredPromise<string[]>();63this._embeddingsResultsPromises.set(query, promise);64const result = await raceCancellation(promise.p, token);65return result ?? null;66}6768async getLLMRankedResults(query: string, token: CancellationToken): Promise<string[] | null> {69if (!this.isEnabled()) {70throw new Error('No settings search providers registered');71}7273const existingPromise = this._llmRankedResultsPromises.get(query);74if (existingPromise) {75const result = await existingPromise.p;76return result ?? null;77}7879const promise = new DeferredPromise<string[]>();80this._llmRankedResultsPromises.set(query, promise);81const result = await raceCancellation(promise.p, token);82return result ?? null;83}8485handleSearchResult(result: AiSettingsSearchResult): void {86if (!this.isEnabled()) {87return;88}8990if (result.kind === AiSettingsSearchResultKind.EMBEDDED) {91const promise = this._embeddingsResultsPromises.get(result.query);92if (promise) {93promise.complete(result.settings);94} else {95const parkedPromise = new DeferredPromise<string[]>();96parkedPromise.complete(result.settings);97this._embeddingsResultsPromises.set(result.query, parkedPromise);98}99} else if (result.kind === AiSettingsSearchResultKind.LLM_RANKED) {100const promise = this._llmRankedResultsPromises.get(result.query);101if (promise) {102promise.complete(result.settings);103} else {104const parkedPromise = new DeferredPromise<string[]>();105parkedPromise.complete(result.settings);106this._llmRankedResultsPromises.set(result.query, parkedPromise);107}108}109}110}111112registerSingleton(IAiSettingsSearchService, AiSettingsSearchService, InstantiationType.Delayed);113114115