Skip to content

Commit

Permalink
Add user action to track suggestion ignore scenarios (#1004)
Browse files Browse the repository at this point in the history
* Add user action to track suggestion ignore scenarios

If user continues to type after lightspeed inline suggestion
completion request is in progress identify it as suggestion
ignored in the telemetry data.

* minor update

---------

Co-authored-by: Ansible-lightspeed-Bot <[email protected]>
  • Loading branch information
ganeshrn and Ansible-lightspeed-Bot authored Nov 13, 2023
1 parent 7798082 commit 67b7cc7
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
5 changes: 3 additions & 2 deletions src/definitions/lightspeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 8 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -202,7 +202,13 @@ export async function activate(context: ExtensionContext): Promise<void> {
context.subscriptions.push(
vscode.commands.registerTextEditorCommand(
LightSpeedCommands.LIGHTSPEED_SUGGESTION_HIDE,
inlineSuggestionHideHandler
async (
textEditor: vscode.TextEditor,
edit: vscode.TextEditorEdit,
userAction?: UserAction
) => {
await inlineSuggestionHideHandler(userAction);
}
)
);

Expand Down
8 changes: 7 additions & 1 deletion src/features/lightspeed/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ export class LightSpeedAPI {
private axiosInstance: AxiosInstance | undefined;
private settingsManager: SettingsManager;
private lightSpeedAuthProvider: LightSpeedAuthenticationProvider;
public _completionRequestInProgress: boolean;

constructor(
settingsManager: SettingsManager,
lightSpeedAuthProvider: LightSpeedAuthenticationProvider
) {
this.settingsManager = settingsManager;
this.lightSpeedAuthProvider = lightSpeedAuthProvider;
this._completionRequestInProgress = false;
}

private async getApiInstance(): Promise<AxiosInstance | undefined> {
Expand Down Expand Up @@ -82,14 +84,15 @@ export class LightSpeedAPI {
)}`
);
try {
this._completionRequestInProgress = true;
const response = await axiosInstance.post(
LIGHTSPEED_SUGGESTION_COMPLETION_URL,
inputData,
{
timeout: ANSIBLE_LIGHTSPEED_API_TIMEOUT,
}
);

this._completionRequestInProgress = false;
if (
response.status === 204 ||
response.data.predictions.length === 0 ||
Expand Down Expand Up @@ -165,7 +168,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;
}
}

Expand Down
32 changes: 21 additions & 11 deletions src/features/lightspeed/inlineSuggestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ export class LightSpeedInlineSuggestionProvider
context: vscode.InlineCompletionContext,
token: vscode.CancellationToken
): vscode.ProviderResult<vscode.InlineCompletionItem[]> {
if (lightSpeedManager.apiInstance._completionRequestInProgress) {
vscode.commands.executeCommand(
LightSpeedCommands.LIGHTSPEED_SUGGESTION_HIDE,
UserAction.IGNORED
);
}
const activeTextEditor = vscode.window.activeTextEditor;
if (!activeTextEditor) {
resetInlineSuggestionDisplayed();
Expand Down Expand Up @@ -402,7 +408,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.`
);
Expand Down Expand Up @@ -531,25 +536,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();
Expand All @@ -558,11 +572,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,
Expand Down

0 comments on commit 67b7cc7

Please sign in to comment.