Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/services/aiSettingsSearch/common/aiSettingsSearchService.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 { DeferredPromise, raceCancellation } from '../../../../base/common/async.js';
7
import { CancellationToken } from '../../../../base/common/cancellation.js';
8
import { Emitter, Event } from '../../../../base/common/event.js';
9
import { Disposable, IDisposable } from '../../../../base/common/lifecycle.js';
10
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
11
import { AiSettingsSearchResult, AiSettingsSearchResultKind, IAiSettingsSearchProvider, IAiSettingsSearchService } from './aiSettingsSearch.js';
12
13
export class AiSettingsSearchService extends Disposable implements IAiSettingsSearchService {
14
readonly _serviceBrand: undefined;
15
private static readonly MAX_PICKS = 5;
16
17
private _providers: IAiSettingsSearchProvider[] = [];
18
private _llmRankedResultsPromises: Map<string, DeferredPromise<string[]>> = new Map();
19
private _embeddingsResultsPromises: Map<string, DeferredPromise<string[]>> = new Map();
20
21
private _onProviderRegistered: Emitter<void> = this._register(new Emitter<void>());
22
readonly onProviderRegistered: Event<void> = this._onProviderRegistered.event;
23
24
isEnabled(): boolean {
25
return this._providers.length > 0;
26
}
27
28
registerSettingsSearchProvider(provider: IAiSettingsSearchProvider): IDisposable {
29
this._providers.push(provider);
30
this._onProviderRegistered.fire();
31
return {
32
dispose: () => {
33
const index = this._providers.indexOf(provider);
34
if (index !== -1) {
35
this._providers.splice(index, 1);
36
}
37
}
38
};
39
}
40
41
startSearch(query: string, embeddingsOnly: boolean, token: CancellationToken): void {
42
if (!this.isEnabled()) {
43
throw new Error('No settings search providers registered');
44
}
45
46
this._embeddingsResultsPromises.delete(query);
47
this._llmRankedResultsPromises.delete(query);
48
49
this._providers.forEach(provider => provider.searchSettings(query, { limit: AiSettingsSearchService.MAX_PICKS, embeddingsOnly }, token));
50
}
51
52
async getEmbeddingsResults(query: string, token: CancellationToken): Promise<string[] | null> {
53
if (!this.isEnabled()) {
54
throw new Error('No settings search providers registered');
55
}
56
57
const existingPromise = this._embeddingsResultsPromises.get(query);
58
if (existingPromise) {
59
const result = await existingPromise.p;
60
return result ?? null;
61
}
62
63
const promise = new DeferredPromise<string[]>();
64
this._embeddingsResultsPromises.set(query, promise);
65
const result = await raceCancellation(promise.p, token);
66
return result ?? null;
67
}
68
69
async getLLMRankedResults(query: string, token: CancellationToken): Promise<string[] | null> {
70
if (!this.isEnabled()) {
71
throw new Error('No settings search providers registered');
72
}
73
74
const existingPromise = this._llmRankedResultsPromises.get(query);
75
if (existingPromise) {
76
const result = await existingPromise.p;
77
return result ?? null;
78
}
79
80
const promise = new DeferredPromise<string[]>();
81
this._llmRankedResultsPromises.set(query, promise);
82
const result = await raceCancellation(promise.p, token);
83
return result ?? null;
84
}
85
86
handleSearchResult(result: AiSettingsSearchResult): void {
87
if (!this.isEnabled()) {
88
return;
89
}
90
91
if (result.kind === AiSettingsSearchResultKind.EMBEDDED) {
92
const promise = this._embeddingsResultsPromises.get(result.query);
93
if (promise) {
94
promise.complete(result.settings);
95
} else {
96
const parkedPromise = new DeferredPromise<string[]>();
97
parkedPromise.complete(result.settings);
98
this._embeddingsResultsPromises.set(result.query, parkedPromise);
99
}
100
} else if (result.kind === AiSettingsSearchResultKind.LLM_RANKED) {
101
const promise = this._llmRankedResultsPromises.get(result.query);
102
if (promise) {
103
promise.complete(result.settings);
104
} else {
105
const parkedPromise = new DeferredPromise<string[]>();
106
parkedPromise.complete(result.settings);
107
this._llmRankedResultsPromises.set(result.query, parkedPromise);
108
}
109
}
110
}
111
}
112
113
registerSingleton(IAiSettingsSearchService, AiSettingsSearchService, InstantiationType.Delayed);
114
115