-
Notifications
You must be signed in to change notification settings - Fork 730
fix(amazonq): block completion before active edit is accepted/rejected #8141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -136,10 +136,11 @@ export class EditDecorationManager { | |
| newCode: string, | ||
| originalCodeHighlightRanges: Array<{ line: number; start: number; end: number }> | ||
| ): Promise<void> { | ||
| await this.clearDecorations(editor) | ||
|
|
||
| await setContext('aws.amazonq.editSuggestionActive' as any, true) | ||
| EditSuggestionState.setEditSuggestionActive(true) | ||
| // Clear old decorations but don't reset state (state is already set in displaySvgDecoration) | ||
| editor.setDecorations(this.imageDecorationType, []) | ||
| editor.setDecorations(this.removedCodeDecorationType, []) | ||
| this.currentImageDecoration = undefined | ||
| this.currentRemovedCodeDecorations = [] | ||
|
|
||
| this.acceptHandler = onAccept | ||
| this.rejectHandler = onReject | ||
|
|
@@ -313,8 +314,16 @@ export async function displaySvgDecoration( | |
| ) { | ||
| const originalCode = editor.document.getText() | ||
|
|
||
| // Set edit state immediately to prevent race condition with completion requests | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what if the state is set to false later and we already skip completion request?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting state to TRUE early and then potentially setting it to FALSE later (if edit fails) is the correct behavior. When we set state to TRUE, we're indicating "an edit operation is in progress" - completion should be skipped during this time regardless of whether the edit ultimately succeeds or fails. If the edit fails, we clean up the state, and future completion requests will work normally. The alternative (not setting state early) is what causes the bug where both suggestions appear simultaneously. |
||
| await setContext('aws.amazonq.editSuggestionActive' as any, true) | ||
| EditSuggestionState.setEditSuggestionActive(true) | ||
|
|
||
| // Check if a completion suggestion is currently active - if so, discard edit suggestion | ||
| if (inlineCompletionProvider && (await inlineCompletionProvider.isCompletionActive())) { | ||
| // Clean up state since we're not showing the edit | ||
| await setContext('aws.amazonq.editSuggestionActive' as any, false) | ||
| EditSuggestionState.setEditSuggestionActive(false) | ||
|
|
||
| // Emit DISCARD telemetry for edit suggestion that can't be shown due to active completion | ||
| const params = createDiscardTelemetryParams(session, item) | ||
| languageClient.sendNotification('aws/logInlineCompletionSessionResults', params) | ||
|
|
@@ -326,6 +335,10 @@ export async function displaySvgDecoration( | |
|
|
||
| const isPatchValid = applyPatch(editor.document.getText(), item.insertText as string) | ||
| if (!isPatchValid) { | ||
| // Clean up state since we're not showing the edit | ||
| await setContext('aws.amazonq.editSuggestionActive' as any, false) | ||
| EditSuggestionState.setEditSuggestionActive(false) | ||
|
|
||
| const params = createDiscardTelemetryParams(session, item) | ||
| // TODO: this session is closed on flare side hence discarded is not emitted in flare | ||
| languageClient.sendNotification('aws/logInlineCompletionSessionResults', params) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to move the logic to displaySvgDecoration? I think we clear decoration after making sure that all condition passes which is in displayEditSuggestion? should we just need the condition in recommendationService.ts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check in recommendationService.ts alone isn't sufficient. Without setting the state early in displaySvgDecoration(), there's a race condition window between when the edit flow starts and when the state is finally set. During this window (which includes async operations like isCompletionActive() and applyPatch()), completion requests can check the state, see it as false, and proceed. Both changes are needed for proper mutual exclusion.