Remove Semantic Similarity Provider (#191039)

Now that RelatedInformationProvider has landed

ref https://github.com/microsoft/vscode/issues/190909
This commit is contained in:
Tyler James Leonhardt
2023-08-25 09:35:31 -07:00
committed by GitHub
parent 256c5aa956
commit aced05cf7c
13 changed files with 25 additions and 327 deletions
@@ -87,7 +87,6 @@ import './mainThreadTesting';
import './mainThreadSecretState';
import './mainThreadShare';
import './mainThreadProfilContentHandlers';
import './mainThreadSemanticSimilarity';
import './mainThreadAiRelatedInformation';
import './mainThreadAiEmbeddingVector';
import './mainThreadIssueReporter';
@@ -1,36 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, DisposableMap } from 'vs/base/common/lifecycle';
import { ExtHostContext, ExtHostSemanticSimilarityShape, MainContext, MainThreadSemanticSimilarityShape } from 'vs/workbench/api/common/extHost.protocol';
import { IExtHostContext, extHostNamedCustomer } from 'vs/workbench/services/extensions/common/extHostCustomers';
import { ISemanticSimilarityProvider, ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService';
@extHostNamedCustomer(MainContext.MainThreadSemanticSimilarity)
export class MainThreadSemanticSimilarity extends Disposable implements MainThreadSemanticSimilarityShape {
private readonly _proxy: ExtHostSemanticSimilarityShape;
private readonly _registrations = this._register(new DisposableMap<number>());
constructor(
context: IExtHostContext,
@ISemanticSimilarityService private readonly _semanticSimilarityService: ISemanticSimilarityService
) {
super();
this._proxy = context.getProxy(ExtHostContext.ExtHostSemanticSimilarity);
}
$registerSemanticSimilarityProvider(handle: number): void {
const provider: ISemanticSimilarityProvider = {
provideSimilarityScore: (string1, comparisons, token) => {
return this._proxy.$provideSimilarityScore(handle, string1, comparisons, token);
},
};
this._registrations.set(handle, this._semanticSimilarityService.registerSemanticSimilarityProvider(provider));
}
$unregisterSemanticSimilarityProvider(handle: number): void {
this._registrations.deleteAndDispose(handle);
}
}
@@ -100,7 +100,6 @@ import { ExtHostQuickDiff } from 'vs/workbench/api/common/extHostQuickDiff';
import { ExtHostChat } from 'vs/workbench/api/common/extHostChat';
import { ExtHostInteractiveEditor } from 'vs/workbench/api/common/extHostInlineChat';
import { ExtHostNotebookDocumentSaveParticipant } from 'vs/workbench/api/common/extHostNotebookDocumentSaveParticipant';
import { ExtHostSemanticSimilarity } from 'vs/workbench/api/common/extHostSemanticSimilarity';
import { ExtHostIssueReporter } from 'vs/workbench/api/common/extHostIssueReporter';
import { IExtHostManagedSockets } from 'vs/workbench/api/common/extHostManagedSockets';
import { ExtHostShare } from 'vs/workbench/api/common/extHostShare';
@@ -212,7 +211,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostChatSlashCommands = rpcProtocol.set(ExtHostContext.ExtHostChatSlashCommands, new ExtHostChatSlashCommands(rpcProtocol, extHostChatProvider, extHostLogService));
const extHostChatVariables = rpcProtocol.set(ExtHostContext.ExtHostChatVariables, new ExtHostChatVariables(rpcProtocol));
const extHostChat = rpcProtocol.set(ExtHostContext.ExtHostChat, new ExtHostChat(rpcProtocol, extHostLogService));
const extHostSemanticSimilarity = rpcProtocol.set(ExtHostContext.ExtHostSemanticSimilarity, new ExtHostSemanticSimilarity(rpcProtocol));
const extHostAiRelatedInformation = rpcProtocol.set(ExtHostContext.ExtHostAiRelatedInformation, new ExtHostRelatedInformation(rpcProtocol));
const extHostAiEmbeddingVector = rpcProtocol.set(ExtHostContext.ExtHostAiEmbeddingVector, new ExtHostAiEmbeddingVector(rpcProtocol));
const extHostIssueReporter = rpcProtocol.set(ExtHostContext.ExtHostIssueReporter, new ExtHostIssueReporter(rpcProtocol));
@@ -1324,10 +1322,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
// namespace: ai
const ai: typeof vscode.ai = {
registerSemanticSimilarityProvider(provider: vscode.SemanticSimilarityProvider) {
checkProposedApiEnabled(extension, 'semanticSimilarity');
return extHostSemanticSimilarity.registerSemanticSimilarityProvider(extension, provider);
},
getRelatedInformation(query: string, types: vscode.RelatedInformationType[]): Thenable<vscode.RelatedInformationResult[]> {
checkProposedApiEnabled(extension, 'aiRelatedInformation');
return extHostAiRelatedInformation.getRelatedInformation(extension, query, types);
@@ -1665,15 +1665,6 @@ export interface ExtHostAuthenticationShape {
$setProviders(providers: AuthenticationProviderInformation[]): Promise<void>;
}
export interface ExtHostSemanticSimilarityShape {
$provideSimilarityScore(handle: number, string1: string, comparisons: string[], token: CancellationToken): Promise<number[]>;
}
export interface MainThreadSemanticSimilarityShape extends IDisposable {
$registerSemanticSimilarityProvider(handle: number): void;
$unregisterSemanticSimilarityProvider(handle: number): void;
}
export interface ExtHostAiRelatedInformationShape {
$provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise<RelatedInformationResult[]>;
}
@@ -2672,7 +2663,6 @@ export const MainContext = {
MainThreadTimeline: createProxyIdentifier<MainThreadTimelineShape>('MainThreadTimeline'),
MainThreadTesting: createProxyIdentifier<MainThreadTestingShape>('MainThreadTesting'),
MainThreadLocalization: createProxyIdentifier<MainThreadLocalizationShape>('MainThreadLocalizationShape'),
MainThreadSemanticSimilarity: createProxyIdentifier<MainThreadSemanticSimilarityShape>('MainThreadSemanticSimilarity'),
MainThreadAiRelatedInformation: createProxyIdentifier<MainThreadAiRelatedInformationShape>('MainThreadAiRelatedInformation'),
MainThreadAiEmbeddingVector: createProxyIdentifier<MainThreadAiEmbeddingVectorShape>('MainThreadAiEmbeddingVector'),
MainThreadIssueReporter: createProxyIdentifier<MainThreadIssueReporterShape>('MainThreadIssueReporter'),
@@ -2734,7 +2724,6 @@ export const ExtHostContext = {
ExtHostChatSlashCommands: createProxyIdentifier<ExtHostChatSlashCommandsShape>('ExtHostChatSlashCommands'),
ExtHostChatVariables: createProxyIdentifier<ExtHostChatVariablesShape>('ExtHostChatVariables'),
ExtHostChatProvider: createProxyIdentifier<ExtHostChatProviderShape>('ExtHostChatProvider'),
ExtHostSemanticSimilarity: createProxyIdentifier<ExtHostSemanticSimilarityShape>('ExtHostSemanticSimilarity'),
ExtHostAiRelatedInformation: createProxyIdentifier<ExtHostAiRelatedInformationShape>('ExtHostAiRelatedInformation'),
ExtHostAiEmbeddingVector: createProxyIdentifier<ExtHostAiEmbeddingVectorShape>('ExtHostAiEmbeddingVector'),
ExtHostTheming: createProxyIdentifier<ExtHostThemingShape>('ExtHostTheming'),
@@ -20,12 +20,12 @@ export class ExtHostRelatedInformation implements ExtHostAiRelatedInformationSha
async $provideAiRelatedInformation(handle: number, query: string, token: CancellationToken): Promise<RelatedInformationResult[]> {
if (this._relatedInformationProviders.size === 0) {
throw new Error('No semantic similarity providers registered');
throw new Error('No related information providers registered');
}
const provider = this._relatedInformationProviders.get(handle);
if (!provider) {
throw new Error('Semantic similarity provider not found');
throw new Error('related information provider not found');
}
const result = await provider.provideRelatedInformation(query, token) ?? [];
@@ -1,47 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostSemanticSimilarityShape, IMainContext, MainContext, MainThreadSemanticSimilarityShape } from 'vs/workbench/api/common/extHost.protocol';
import type { CancellationToken, SemanticSimilarityProvider } from 'vscode';
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
export class ExtHostSemanticSimilarity implements ExtHostSemanticSimilarityShape {
private _semanticSimilarityProviders: Map<number, SemanticSimilarityProvider> = new Map();
private _nextHandle = 0;
private readonly _proxy: MainThreadSemanticSimilarityShape;
constructor(
mainContext: IMainContext
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadSemanticSimilarity);
}
async $provideSimilarityScore(handle: number, string1: string, comparisons: string[], token: CancellationToken): Promise<number[]> {
if (this._semanticSimilarityProviders.size === 0) {
throw new Error('No semantic similarity providers registered');
}
const provider = this._semanticSimilarityProviders.get(handle);
if (!provider) {
throw new Error('Semantic similarity provider not found');
}
const result = await provider.provideSimilarityScore(string1, comparisons, token);
return result;
}
registerSemanticSimilarityProvider(extension: IExtensionDescription, provider: SemanticSimilarityProvider): Disposable {
const handle = this._nextHandle;
this._nextHandle++;
this._semanticSimilarityProviders.set(handle, provider);
this._proxy.$registerSemanticSimilarityProvider(handle);
return new Disposable(() => {
this._proxy.$unregisterSemanticSimilarityProvider(handle);
this._semanticSimilarityProviders.delete(handle);
});
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ export interface IWorkbenchQuickAccessConfiguration {
readonly preserveInput: boolean;
readonly experimental: {
readonly suggestCommands: boolean;
readonly useSemanticSimilarity: boolean;
readonly enableNaturalLanguageSearch: boolean;
};
};
readonly quickOpen: {
@@ -381,10 +381,10 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
'description': localize('suggestCommands', "Controls whether the command palette should have a list of commonly used commands."),
'default': false
},
'workbench.commandPalette.experimental.useSemanticSimilarity': {
'workbench.commandPalette.experimental.enableNaturalLanguageSearch': {
'type': 'boolean',
tags: ['experimental'],
'description': localize('useSemanticSimilarity', "Controls whether the command palette should include similar commands. You must have an extension installed that provides Semantic Similarity."),
'description': localize('enableNaturalLanguageSearch', "Controls whether the command palette should include similar commands. You must have an extension installed that provides Natural Language support."),
'default': true
},
'workbench.quickOpen.closeOnFocusLost': {
@@ -20,7 +20,6 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService';
import { IAiRelatedInformationService, RelatedInformationType, SettingInformationResult } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation';
export interface IEndpointDetails {
@@ -304,8 +303,7 @@ class RemoteSearchKeysProvider {
private currentPreferencesModel: ISettingsEditorModel | undefined;
constructor(
private readonly aiRelatedInformationService: IAiRelatedInformationService,
private readonly semanticSimilarityService: ISemanticSimilarityService
private readonly aiRelatedInformationService: IAiRelatedInformationService
) { }
updateModel(preferencesModel: ISettingsEditorModel) {
@@ -323,7 +321,7 @@ class RemoteSearchKeysProvider {
if (
!this.currentPreferencesModel ||
(!this.semanticSimilarityService.isEnabled() && !this.aiRelatedInformationService.isEnabled())
!this.aiRelatedInformationService.isEnabled()
) {
return;
}
@@ -351,17 +349,16 @@ class RemoteSearchKeysProvider {
}
export class RemoteSearchProvider implements ISearchProvider {
private static readonly SEMANTIC_SIMILARITY_THRESHOLD = 0.73;
private static readonly SEMANTIC_SIMILARITY_MAX_PICKS = 15;
private static readonly AI_RELATED_INFORMATION_THRESHOLD = 0.73;
private static readonly AI_RELATED_INFORMATION_MAX_PICKS = 15;
private readonly _keysProvider: RemoteSearchKeysProvider;
private _filter: string = '';
constructor(
@ISemanticSimilarityService private readonly semanticSimilarityService: ISemanticSimilarityService,
@IAiRelatedInformationService private readonly aiRelatedInformationService: IAiRelatedInformationService
) {
this._keysProvider = new RemoteSearchKeysProvider(aiRelatedInformationService, semanticSimilarityService);
this._keysProvider = new RemoteSearchKeysProvider(aiRelatedInformationService);
}
setFilter(filter: string) {
@@ -371,50 +368,18 @@ export class RemoteSearchProvider implements ISearchProvider {
async searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken | undefined): Promise<ISearchResult | null> {
if (
!this._filter ||
(!this.semanticSimilarityService.isEnabled() && !this.aiRelatedInformationService.isEnabled())) {
!this.aiRelatedInformationService.isEnabled()
) {
return null;
}
this._keysProvider.updateModel(preferencesModel);
const filterMatches = this.aiRelatedInformationService.isEnabled()
? await this.getAiRelatedInformationItems(token)
: this.semanticSimilarityService.isEnabled()
? await this.getSemanticSimilarityItems(token)
: [];
return {
filterMatches
filterMatches: await this.getAiRelatedInformationItems(token)
};
}
// TODO: Remove this when all semantic similarity providers are migrated to aiRelatedInformationService
private async getSemanticSimilarityItems(token?: CancellationToken | undefined) {
const settingKeys = this._keysProvider.getSettingKeys();
const settingsRecord = this._keysProvider.getSettingsRecord();
const scores = await this.semanticSimilarityService.getSimilarityScore(this._filter, settingKeys, token ?? CancellationToken.None);
const filterMatches: ISettingMatch[] = [];
const sortedIndices = scores.map((_, i) => i).sort((a, b) => scores[b] - scores[a]);
let numOfSmartPicks = 0;
for (const i of sortedIndices) {
const score = scores[i];
if (score < RemoteSearchProvider.SEMANTIC_SIMILARITY_THRESHOLD || numOfSmartPicks === RemoteSearchProvider.SEMANTIC_SIMILARITY_MAX_PICKS) {
break;
}
const pick = settingKeys[i];
filterMatches.push({
setting: settingsRecord[pick],
matches: [settingsRecord[pick].range],
matchType: SettingMatchType.RemoteMatch,
score
});
numOfSmartPicks++;
}
return filterMatches;
}
private async getAiRelatedInformationItems(token?: CancellationToken | undefined) {
const settingsRecord = this._keysProvider.getSettingsRecord();
@@ -423,7 +388,7 @@ export class RemoteSearchProvider implements ISearchProvider {
relatedInformation.sort((a, b) => b.weight - a.weight);
for (const info of relatedInformation) {
if (info.weight < RemoteSearchProvider.SEMANTIC_SIMILARITY_THRESHOLD || filterMatches.length === RemoteSearchProvider.SEMANTIC_SIMILARITY_MAX_PICKS) {
if (info.weight < RemoteSearchProvider.AI_RELATED_INFORMATION_THRESHOLD || filterMatches.length === RemoteSearchProvider.AI_RELATED_INFORMATION_MAX_PICKS) {
break;
}
const pick = info.setting;
@@ -33,16 +33,15 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
import { stripIcons } from 'vs/base/common/iconLabels';
import { isFirefox } from 'vs/base/browser/browser';
import { IProductService } from 'vs/platform/product/common/productService';
import { ISemanticSimilarityService } from 'vs/workbench/services/semanticSimilarity/common/semanticSimilarityService';
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
import { ASK_QUICK_QUESTION_ACTION_ID } from 'vs/workbench/contrib/chat/browser/actions/chatQuickInputActions';
import { CommandInformationResult, IAiRelatedInformationService, RelatedInformationType } from 'vs/workbench/services/aiRelatedInformation/common/aiRelatedInformation';
export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAccessProvider {
private static SEMANTIC_SIMILARITY_MAX_PICKS = 3;
private static SEMANTIC_SIMILARITY_THRESHOLD = 0.8;
private static SEMANTIC_SIMILARITY_DEBOUNCE = 200;
private static AI_RELATED_INFORMATION_MAX_PICKS = 3;
private static AI_RELATED_INFORMATION_THRESHOLD = 0.8;
private static AI_RELATED_INFORMATION_DEBOUNCE = 200;
// If extensions are not yet registered, we wait for a little moment to give them
// a chance to register so that the complete set of commands shows up as result
@@ -50,7 +49,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
// functional.
private readonly extensionRegistrationRace = raceTimeout(this.extensionService.whenInstalledExtensionsRegistered(), 800);
private useSemanticSimilarity = false;
private useAiRelatedInfo = false;
protected get activeTextEditorControl(): IEditor | undefined { return this.editorService.activeTextEditorControl; }
@@ -75,7 +74,6 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IPreferencesService private readonly preferencesService: IPreferencesService,
@IProductService private readonly productService: IProductService,
@ISemanticSimilarityService private readonly semanticSimilarityService: ISemanticSimilarityService,
@IAiRelatedInformationService private readonly aiRelatedInformationService: IAiRelatedInformationService,
@IChatService private readonly chatService: IChatService
) {
@@ -110,7 +108,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
? new Set(this.productService.commandPaletteSuggestedCommandIds)
: undefined;
this.options.suggestedCommandIds = suggestedCommandIds;
this.useSemanticSimilarity = config.experimental.useSemanticSimilarity;
this.useAiRelatedInfo = config.experimental.enableNaturalLanguageSearch;
}
protected async getCommandPicks(token: CancellationToken): Promise<Array<ICommandQuickPick>> {
@@ -140,10 +138,10 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
protected hasAdditionalCommandPicks(filter: string, token: CancellationToken): boolean {
if (
!this.useSemanticSimilarity
!this.useAiRelatedInfo
|| token.isCancellationRequested
|| filter === ''
|| !(this.semanticSimilarityService.isEnabled() || this.aiRelatedInformationService.isEnabled())
|| !this.aiRelatedInformationService.isEnabled()
) {
return false;
}
@@ -160,12 +158,8 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
try {
// Wait a bit to see if the user is still typing
await timeout(CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_DEBOUNCE, token);
additionalPicks = this.aiRelatedInformationService.isEnabled()
? await this.getRelatedInformationPicks(allPicks, picksSoFar, filter, token)
: this.semanticSimilarityService.isEnabled()
? await this.getSemanticSimilarityPicks(allPicks, picksSoFar, filter, token)
: [];
await timeout(CommandsQuickAccessProvider.AI_RELATED_INFORMATION_DEBOUNCE, token);
additionalPicks = await this.getRelatedInformationPicks(allPicks, picksSoFar, filter, token);
} catch (e) {
return [];
}
@@ -173,7 +167,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
if (additionalPicks.length) {
additionalPicks.unshift({
type: 'separator',
label: localize('semanticSimilarity', "similar commands")
label: localize('similarCommands', "similar commands")
});
}
@@ -195,35 +189,6 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
return additionalPicks;
}
private async getSemanticSimilarityPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken) {
const format = allPicks.map(p => p.commandId);
const scores = await this.semanticSimilarityService.getSimilarityScore(filter, format, token);
if (token.isCancellationRequested) {
return [];
}
const sortedIndices = scores.map((_, i) => i).sort((a, b) => scores[b] - scores[a]);
const setOfPicksSoFar = new Set(picksSoFar.map(p => p.commandId));
const additionalPicks = new Array<ICommandQuickPick | IQuickPickSeparator>();
let numOfSmartPicks = 0;
for (const i of sortedIndices) {
const score = scores[i];
if (score < CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_THRESHOLD || numOfSmartPicks === CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_MAX_PICKS) {
break;
}
const pick = allPicks[i];
if (!setOfPicksSoFar.has(pick.commandId)) {
additionalPicks.push(pick);
numOfSmartPicks++;
}
}
return additionalPicks;
}
private async getRelatedInformationPicks(allPicks: ICommandQuickPick[], picksSoFar: ICommandQuickPick[], filter: string, token: CancellationToken) {
const relatedInformation = await this.aiRelatedInformationService.getRelatedInformation(
filter,
@@ -238,7 +203,7 @@ export class CommandsQuickAccessProvider extends AbstractEditorCommandsQuickAcce
const additionalPicks = new Array<ICommandQuickPick | IQuickPickSeparator>();
for (const info of relatedInformation) {
if (info.weight < CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_THRESHOLD || additionalPicks.length === CommandsQuickAccessProvider.SEMANTIC_SIMILARITY_MAX_PICKS) {
if (info.weight < CommandsQuickAccessProvider.AI_RELATED_INFORMATION_THRESHOLD || additionalPicks.length === CommandsQuickAccessProvider.AI_RELATED_INFORMATION_MAX_PICKS) {
break;
}
const pick = allPicks.find(p => p.commandId === info.command && !setOfPicksSoFar.has(p.commandId));
@@ -79,7 +79,6 @@ export const allApiProposals = Object.freeze({
scmSelectedProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.scmSelectedProvider.d.ts',
scmTextDocument: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.scmTextDocument.d.ts',
scmValidation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.scmValidation.d.ts',
semanticSimilarity: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.semanticSimilarity.d.ts',
shareProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.shareProvider.d.ts',
showLocal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.showLocal.d.ts',
tabInputTextMerge: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tabInputTextMerge.d.ts',
@@ -1,108 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { CancellationToken } from 'vs/base/common/cancellation';
import { CancelablePromise, createCancelablePromise, raceCancellablePromises, timeout } from 'vs/base/common/async';
import { IDisposable } from 'vs/base/common/lifecycle';
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { StopWatch } from 'vs/base/common/stopwatch';
import { ILogService } from 'vs/platform/log/common/log';
/**
* @deprecated Use `IAiRelatedInformationService` instead.
*/
export const ISemanticSimilarityService = createDecorator<ISemanticSimilarityService>('ISemanticSimilarityService');
/**
* @deprecated Use `IAiRelatedInformationService` instead.
*/
export interface ISemanticSimilarityService {
readonly _serviceBrand: undefined;
isEnabled(): boolean;
getSimilarityScore(string1: string, comparisons: string[], token: CancellationToken): Promise<number[]>;
registerSemanticSimilarityProvider(provider: ISemanticSimilarityProvider): IDisposable;
}
export interface ISemanticSimilarityProvider {
provideSimilarityScore(string1: string, comparisons: string[], token: CancellationToken): Promise<number[]>;
}
export class SemanticSimilarityService implements ISemanticSimilarityService {
readonly _serviceBrand: undefined;
static readonly DEFAULT_TIMEOUT = 1000 * 10; // 10 seconds
private readonly _providers: ISemanticSimilarityProvider[] = [];
constructor(@ILogService private readonly logService: ILogService) { }
isEnabled(): boolean {
return this._providers.length > 0;
}
registerSemanticSimilarityProvider(provider: ISemanticSimilarityProvider): IDisposable {
this._providers.push(provider);
return {
dispose: () => {
const index = this._providers.indexOf(provider);
if (index >= 0) {
this._providers.splice(index, 1);
}
}
};
}
async getSimilarityScore(string1: string, comparisons: string[], token: CancellationToken): Promise<number[]> {
if (this._providers.length === 0) {
throw new Error('No semantic similarity providers registered');
}
const stopwatch = StopWatch.create();
const cancellablePromises: Array<CancelablePromise<number[]>> = [];
const timer = timeout(SemanticSimilarityService.DEFAULT_TIMEOUT);
const disposable = token.onCancellationRequested(() => {
disposable.dispose();
timer.cancel();
});
for (const provider of this._providers) {
cancellablePromises.push(createCancelablePromise(async t => {
try {
return await provider.provideSimilarityScore(string1, comparisons, t);
} catch (e) {
// logged in extension host
}
// Wait for the timer to finish to allow for another provider to resolve.
// Alternatively, if something resolved, or we've timed out, this will throw
// as expected.
await timer;
throw new Error('Semantic similarity provider timed out');
}));
}
cancellablePromises.push(createCancelablePromise(async (t) => {
const disposable = t.onCancellationRequested(() => {
timer.cancel();
disposable.dispose();
});
await timer;
throw new Error('Semantic similarity provider timed out');
}));
try {
const result = await raceCancellablePromises(cancellablePromises);
return result;
} finally {
stopwatch.stop();
this.logService.trace(`[SemanticSimilarityService]: getSimilarityScore took ${stopwatch.elapsed()}ms`);
}
}
}
registerSingleton(ISemanticSimilarityService, SemanticSimilarityService, InstantiationType.Delayed);
-22
View File
@@ -1,22 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
export interface SemanticSimilarityProvider {
/**
* Computes the semantic similarity score between two strings.
* @param string1 The string to compare to all other strings.
* @param comparisons An array of strings to compare string1 to. An array allows you to batch multiple comparisons in one call.
* @param token A cancellation token.
* @return A promise that resolves to the semantic similarity scores between string1 and each string in comparisons.
* The score should be a number between 0 and 1, where 0 means no similarity and 1 means
* perfect similarity.
*/
provideSimilarityScore(string1: string, comparisons: string[], token: CancellationToken): Thenable<number[]>;
}
export namespace ai {
export function registerSemanticSimilarityProvider(provider: SemanticSimilarityProvider): Disposable;
}
}