From 908bd80b7d909e25f379aa44721aef1e3f9d5028 Mon Sep 17 00:00:00 2001 From: Boyu Wang Date: Tue, 11 Nov 2025 17:25:49 -0800 Subject: [PATCH] fix(amazonq): add reject reason to nep telemetry --- .../app/inline/EditRendering/displayImage.ts | 32 +++++++++++++------ .../inline/EditRendering/displayImage.test.ts | 15 +++++++-- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/amazonq/src/app/inline/EditRendering/displayImage.ts b/packages/amazonq/src/app/inline/EditRendering/displayImage.ts index 035621f0ba4..dfc6799f72e 100644 --- a/packages/amazonq/src/app/inline/EditRendering/displayImage.ts +++ b/packages/amazonq/src/app/inline/EditRendering/displayImage.ts @@ -14,7 +14,7 @@ import path from 'path' import { imageVerticalOffset } from './svgGenerator' import { EditSuggestionState } from '../editSuggestionState' import type { AmazonQInlineCompletionItemProvider } from '../completion' -import { vsCodeState } from 'aws-core-vscode/codewhisperer' +import { vsCodeState, InlineCompletionLoggingReason } from 'aws-core-vscode/codewhisperer' const autoRejectEditCursorDistance = 25 const autoDiscardEditCursorDistance = 10 @@ -25,7 +25,7 @@ export class EditDecorationManager { private currentImageDecoration: vscode.DecorationOptions | undefined private currentRemovedCodeDecorations: vscode.DecorationOptions[] = [] private acceptHandler: (() => void) | undefined - private rejectHandler: ((isDiscard: boolean) => void) | undefined + private rejectHandler: ((isDiscard: boolean, reason?: InlineCompletionLoggingReason) => void) | undefined constructor() { this.registerCommandHandlers() @@ -132,7 +132,7 @@ export class EditDecorationManager { svgImage: vscode.Uri, startLine: number, onAccept: () => Promise, - onReject: (isDiscard: boolean) => Promise, + onReject: (isDiscard: boolean, reason?: InlineCompletionLoggingReason) => Promise, originalCode: string, newCode: string, originalCodeHighlightRanges: Array<{ line: number; start: number; end: number }> @@ -187,11 +187,14 @@ export class EditDecorationManager { }) // Register Esc key handler for rejecting suggestion - vscode.commands.registerCommand('aws.amazonq.inline.rejectEdit', (isDiscard: boolean = false) => { - if (this.rejectHandler) { - this.rejectHandler(isDiscard) + vscode.commands.registerCommand( + 'aws.amazonq.inline.rejectEdit', + (isDiscard: boolean = false, reason?: InlineCompletionLoggingReason) => { + if (this.rejectHandler) { + this.rejectHandler(isDiscard, reason) + } } - }) + ) } /** @@ -376,7 +379,11 @@ export async function displaySvgDecoration( const isPatchValid = applyPatch(e.document.getText(), item.insertText as string) if (!isPatchValid) { logSuggestionFailure('REJECT', 'Invalid patch due to document change', item.insertText as string) - void vscode.commands.executeCommand('aws.amazonq.inline.rejectEdit') + void vscode.commands.executeCommand( + 'aws.amazonq.inline.rejectEdit', + false, + InlineCompletionLoggingReason.IMPLICIT_REJECT + ) } }) const cursorChangeListener = vscode.window.onDidChangeTextEditorSelection((e) => { @@ -394,7 +401,11 @@ export async function displaySvgDecoration( `cursor position move too far away off ${autoRejectEditCursorDistance} lines`, item.insertText as string ) - void vscode.commands.executeCommand('aws.amazonq.inline.rejectEdit') + void vscode.commands.executeCommand( + 'aws.amazonq.inline.rejectEdit', + false, + InlineCompletionLoggingReason.IMPLICIT_REJECT + ) } }) await decorationManager.displayEditSuggestion( @@ -436,7 +447,7 @@ export async function displaySvgDecoration( void languageClient.sendNotification('aws/logInlineCompletionSessionResults', params) session.triggerOnAcceptance = true }, - async (isDiscard: boolean) => { + async (isDiscard: boolean, reason?: InlineCompletionLoggingReason) => { // Handle reject if (isDiscard) { getLogger().info('Edit suggestion discarded') @@ -465,6 +476,7 @@ export async function displaySvgDecoration( totalSessionDisplayTime: Date.now() - session.requestStartTime, firstCompletionDisplayLatency: session.firstCompletionDisplayLatency, isInlineEdit: true, + ...(reason && !isDiscard ? { reason } : {}), } void languageClient.sendNotification('aws/logInlineCompletionSessionResults', params) }, diff --git a/packages/amazonq/test/unit/app/inline/EditRendering/displayImage.test.ts b/packages/amazonq/test/unit/app/inline/EditRendering/displayImage.test.ts index 28155811f50..7e29bd6a560 100644 --- a/packages/amazonq/test/unit/app/inline/EditRendering/displayImage.test.ts +++ b/packages/amazonq/test/unit/app/inline/EditRendering/displayImage.test.ts @@ -8,6 +8,7 @@ import * as sinon from 'sinon' import assert from 'assert' import { EditDecorationManager, displaySvgDecoration } from '../../../../../src/app/inline/EditRendering/displayImage' import { EditSuggestionState } from '../../../../../src/app/inline/editSuggestionState' +import { InlineCompletionLoggingReason } from 'aws-core-vscode/codewhisperer' // Shared helper function to create common stubs function createCommonStubs(sandbox: sinon.SinonSandbox) { @@ -371,7 +372,12 @@ describe('displaySvgDecoration cursor distance auto-reject', function () { selectionChangeListener(createSelectionChangeEvent(startLine + 26)) - sinon.assert.calledOnceWithExactly(commandsStub, 'aws.amazonq.inline.rejectEdit') + sinon.assert.calledOnceWithExactly( + commandsStub, + 'aws.amazonq.inline.rejectEdit', + false, + InlineCompletionLoggingReason.IMPLICIT_REJECT + ) }) it('should reject when cursor moves more than 25 lines before the edit', async function () { @@ -384,7 +390,12 @@ describe('displaySvgDecoration cursor distance auto-reject', function () { selectionChangeListener(createSelectionChangeEvent(startLine - 26)) - sinon.assert.calledOnceWithExactly(commandsStub, 'aws.amazonq.inline.rejectEdit') + sinon.assert.calledOnceWithExactly( + commandsStub, + 'aws.amazonq.inline.rejectEdit', + false, + InlineCompletionLoggingReason.IMPLICIT_REJECT + ) }) it('should not reject when edit is near beginning of file and cursor cannot move far enough', async function () {