mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-07 15:26:49 +01:00
Remove Semantic Similarity Provider (#191039)
Now that RelatedInformationProvider has landed ref https://github.com/microsoft/vscode/issues/190909
This commit is contained in:
committed by
GitHub
parent
256c5aa956
commit
aced05cf7c
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user