diff --git a/src/definitions/lightspeed.ts b/src/definitions/lightspeed.ts index f630deb2f..43a704e84 100644 --- a/src/definitions/lightspeed.ts +++ b/src/definitions/lightspeed.ts @@ -14,8 +14,9 @@ export interface CompletionRequestParams { } export enum UserAction { - ACCEPT = 0, - IGNORE = 1, + ACCEPTED = 0, // accepted the suggestion + REJECTED = 1, // rejected the suggestion + IGNORED = 2, // ignored the suggestion or didn't wait for suggestion to be displayed } export enum AnsibleContentUploadTrigger { diff --git a/src/extension.ts b/src/extension.ts index 753fe5fe4..292b6234f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -10,7 +10,7 @@ import { } from "vscode"; import { toggleEncrypt } from "./features/vault"; import { AnsibleCommands } from "./definitions/constants"; -import { LightSpeedCommands } from "./definitions/lightspeed"; +import { LightSpeedCommands, UserAction } from "./definitions/lightspeed"; import { TelemetryErrorHandler, TelemetryOutputChannel, @@ -197,7 +197,13 @@ export async function activate(context: ExtensionContext): Promise { context.subscriptions.push( vscode.commands.registerTextEditorCommand( LightSpeedCommands.LIGHTSPEED_SUGGESTION_HIDE, - inlineSuggestionHideHandler + async ( + textEditor: vscode.TextEditor, + edit: vscode.TextEditorEdit, + userAction?: UserAction + ) => { + await inlineSuggestionHideHandler(userAction); + } ) ); diff --git a/src/features/lightspeed/api.ts b/src/features/lightspeed/api.ts index 159d6a752..c5bd273a5 100644 --- a/src/features/lightspeed/api.ts +++ b/src/features/lightspeed/api.ts @@ -23,6 +23,7 @@ export class LightSpeedAPI { private axiosInstance: AxiosInstance | undefined; private settingsManager: SettingsManager; private lightSpeedAuthProvider: LightSpeedAuthenticationProvider; + public _completionRequestInProgress: boolean; constructor( settingsManager: SettingsManager, @@ -30,6 +31,7 @@ export class LightSpeedAPI { ) { this.settingsManager = settingsManager; this.lightSpeedAuthProvider = lightSpeedAuthProvider; + this._completionRequestInProgress = false; } private async getApiInstance(): Promise { @@ -82,6 +84,7 @@ export class LightSpeedAPI { )}` ); try { + this._completionRequestInProgress = true; const response = await axiosInstance.post( LIGHTSPEED_SUGGESTION_COMPLETION_URL, inputData, @@ -89,7 +92,7 @@ export class LightSpeedAPI { timeout: ANSIBLE_LIGHTSPEED_API_TIMEOUT, } ); - + this._completionRequestInProgress = false; if ( response.status === 204 || response.data.predictions.length === 0 || @@ -152,7 +155,10 @@ export class LightSpeedAPI { "Failed to fetch inline suggestion from Ansible Lightspeed. Try again after some time." ); } + this._completionRequestInProgress = false; return {} as CompletionResponseParams; + } finally { + this._completionRequestInProgress = false; } } diff --git a/src/features/lightspeed/inlineSuggestions.ts b/src/features/lightspeed/inlineSuggestions.ts index ae6afa99e..6845acc90 100644 --- a/src/features/lightspeed/inlineSuggestions.ts +++ b/src/features/lightspeed/inlineSuggestions.ts @@ -56,6 +56,13 @@ export class LightSpeedInlineSuggestionProvider context: vscode.InlineCompletionContext, token: vscode.CancellationToken ): vscode.ProviderResult { + if (lightSpeedManager.apiInstance._completionRequestInProgress) { + vscode.commands.executeCommand( + LightSpeedCommands.LIGHTSPEED_SUGGESTION_HIDE, + UserAction.IGNORED + ); + return []; + } const activeTextEditor = vscode.window.activeTextEditor; if (!activeTextEditor) { resetInlineSuggestionDisplayed(); @@ -402,7 +409,6 @@ async function requestInlineSuggest( const outputData: CompletionResponseParams = await lightSpeedManager.apiInstance.completionRequest(completionData); lightSpeedManager.statusBarProvider.statusBar.tooltip = "Done"; - console.log( `[inline-suggestions] ${getCurrentUTCDateTime().toISOString()}: Completion response received from Ansible Lightspeed.` ); @@ -531,25 +537,34 @@ export async function inlineSuggestionCommitHandler() { ); // Send feedback for accepted suggestion - await inlineSuggestionUserActionHandler(suggestionId, true); + await inlineSuggestionUserActionHandler(suggestionId, UserAction.ACCEPTED); } -export async function inlineSuggestionHideHandler() { +export async function inlineSuggestionHideHandler(userAction?: UserAction) { if (vscode.window.activeTextEditor?.document.languageId !== "ansible") { return; } - + const action = userAction || UserAction.REJECTED; + if (action === UserAction.REJECTED) { + console.log("[inline-suggestions] User rejected the inline suggestion."); + } else if (action === UserAction.IGNORED) { + console.log("[inline-suggestions] User ignored the inline suggestion."); + } else { + console.log( + "[inline-suggestions] User didn't accept the inline suggestion." + ); + } // Hide the suggestion console.log("[inline-suggestions] User ignored the inline suggestion."); vscode.commands.executeCommand("editor.action.inlineSuggest.hide"); // Send feedback for accepted suggestion - await inlineSuggestionUserActionHandler(suggestionId, false); + await inlineSuggestionUserActionHandler(suggestionId, action); } export async function inlineSuggestionUserActionHandler( suggestionId: string, - isSuggestionAccepted = false + isSuggestionAccepted: UserAction = UserAction.REJECTED ) { inlineSuggestionData["userActionTime"] = getCurrentUTCDateTime().getTime() - inlineSuggestionDisplayTime.getTime(); @@ -558,11 +573,7 @@ export async function inlineSuggestionUserActionHandler( // inline suggestion is no longer displayed and we can reset the // the flag here resetInlineSuggestionDisplayed(); - if (isSuggestionAccepted) { - inlineSuggestionData["action"] = UserAction.ACCEPT; - } else { - inlineSuggestionData["action"] = UserAction.IGNORE; - } + inlineSuggestionData["action"] = isSuggestionAccepted; inlineSuggestionData["suggestionId"] = suggestionId; const inlineSuggestionFeedbackPayload = { inlineSuggestion: inlineSuggestionData,