Skip to content

Commit

Permalink
Add user action to track suggestion ignore scenarios
Browse files Browse the repository at this point in the history
If user continues to type after lightspeed inline suggestion
completion request is in progress identify it as suggestion
ignored in the telemetry data.
  • Loading branch information
Ansible-lightspeed-Bot committed Oct 31, 2023
1 parent 4326c93 commit 34dd0f0
Show file tree
Hide file tree
Showing 4 changed files with 40 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 @@ -197,7 +197,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 @@ -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;
}
}

Expand Down
33 changes: 22 additions & 11 deletions src/features/lightspeed/inlineSuggestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ 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
);
return [];
}
const activeTextEditor = vscode.window.activeTextEditor;
if (!activeTextEditor) {
resetInlineSuggestionDisplayed();
Expand Down Expand Up @@ -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.`
);
Expand Down Expand Up @@ -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();
Expand All @@ -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,
Expand Down

0 comments on commit 34dd0f0

Please sign in to comment.