Skip to content

Commit b5540e2

Browse files
feat(amazonq): show a message when no suggestions are found on manual invoke (aws#7318)
## Problem When manually invoking inline suggestions, it is possible for the backend to still not reply with results. Since the user took an action to invoke this, we should let them know when it fails. ## Solution - add a message with same timeout as original implementation. ## Testing and Verification - added unit test. - E2E flow demo (notice it doesn't trigger on automatic failures, but does on manual invoke failures): https://github.com/user-attachments/assets/7cf34178-e91e-4d38-8875-1259c5552a53 --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: Josh Pinkney <[email protected]>
1 parent ffb6ec1 commit b5540e2

File tree

4 files changed

+85
-51
lines changed

4 files changed

+85
-51
lines changed

packages/amazonq/src/app/inline/completion.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ import {
3434
CodeSuggestionsState,
3535
vsCodeState,
3636
inlineCompletionsDebounceDelay,
37+
noInlineSuggestionsMsg,
3738
} from 'aws-core-vscode/codewhisperer'
3839
import { InlineGeneratingMessage } from './inlineGeneratingMessage'
3940
import { LineTracker } from './stateTracker/lineTracker'
4041
import { InlineTutorialAnnotation } from './tutorials/inlineTutorialAnnotation'
4142
import { TelemetryHelper } from './telemetryHelper'
4243
import { getLogger } from 'aws-core-vscode/shared'
43-
import { debounce } from 'aws-core-vscode/utils'
44+
import { debounce, messageUtils } from 'aws-core-vscode/utils'
4445

4546
export class InlineCompletionManager implements Disposable {
4647
private disposable: Disposable
@@ -241,7 +242,16 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
241242
const items = this.sessionManager.getActiveRecommendation()
242243
const session = this.sessionManager.getActiveSession()
243244
const editor = window.activeTextEditor
245+
246+
// Show message to user when manual invoke fails to produce results.
247+
if (items.length === 0 && context.triggerKind === InlineCompletionTriggerKind.Invoke) {
248+
void messageUtils.showTimedMessage(noInlineSuggestionsMsg, 2000)
249+
}
250+
244251
if (!session || !items.length || !editor) {
252+
getLogger().debug(
253+
`Failed to produce inline suggestion results. Received ${items.length} items from service`
254+
)
245255
return []
246256
}
247257

packages/amazonq/test/unit/amazonq/apps/inline/completion.test.ts

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,25 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import sinon from 'sinon'
6-
import { CancellationToken, commands, InlineCompletionItem, languages, Position, window, Range } from 'vscode'
6+
import {
7+
CancellationToken,
8+
commands,
9+
InlineCompletionItem,
10+
languages,
11+
Position,
12+
window,
13+
Range,
14+
InlineCompletionTriggerKind,
15+
} from 'vscode'
716
import assert from 'assert'
817
import { LanguageClient } from 'vscode-languageclient'
918
import { StringValue } from 'vscode-languageserver-types'
1019
import { AmazonQInlineCompletionItemProvider, InlineCompletionManager } from '../../../../../src/app/inline/completion'
1120
import { RecommendationService } from '../../../../../src/app/inline/recommendationService'
1221
import { SessionManager } from '../../../../../src/app/inline/sessionManager'
13-
import { createMockDocument, createMockTextEditor, installFakeClock } from 'aws-core-vscode/test'
22+
import { createMockDocument, createMockTextEditor, getTestWindow, installFakeClock } from 'aws-core-vscode/test'
1423
import {
24+
noInlineSuggestionsMsg,
1525
ReferenceHoverProvider,
1626
ReferenceInlineProvider,
1727
ReferenceLogViewProvider,
@@ -400,57 +410,70 @@ describe('InlineCompletionManager', () => {
400410

401411
assert.strictEqual(result[0].insertText, expectedText)
402412
}),
403-
describe('debounce behavior', function () {
404-
let clock: ReturnType<typeof installFakeClock>
405-
406-
beforeEach(function () {
407-
clock = installFakeClock()
408-
})
409-
410-
after(function () {
411-
clock.uninstall()
412-
})
413-
414-
it('should only trigger once on rapid events', async () => {
415-
provider = new AmazonQInlineCompletionItemProvider(
416-
languageClient,
417-
recommendationService,
418-
mockSessionManager,
419-
inlineTutorialAnnotation,
420-
false
421-
)
422-
const p1 = provider.provideInlineCompletionItems(
423-
mockDocument,
424-
mockPosition,
425-
mockContext,
426-
mockToken
427-
)
428-
const p2 = provider.provideInlineCompletionItems(
429-
mockDocument,
430-
mockPosition,
431-
mockContext,
432-
mockToken
433-
)
434-
const p3 = provider.provideInlineCompletionItems(
435-
mockDocument,
436-
new Position(2, 2),
437-
mockContext,
438-
mockToken
439-
)
413+
it('shows message to user when manual invoke fails to produce results', async function () {
414+
provider = new AmazonQInlineCompletionItemProvider(
415+
languageClient,
416+
recommendationService,
417+
mockSessionManager,
418+
inlineTutorialAnnotation,
419+
true
420+
)
421+
getActiveRecommendationStub.returns([])
422+
const messageShown = new Promise((resolve) =>
423+
getTestWindow().onDidShowMessage((e) => {
424+
assert.strictEqual(e.message, noInlineSuggestionsMsg)
425+
resolve(true)
426+
})
427+
)
428+
await provider.provideInlineCompletionItems(
429+
mockDocument,
430+
mockPosition,
431+
{ triggerKind: InlineCompletionTriggerKind.Invoke, selectedCompletionInfo: undefined },
432+
mockToken
433+
)
434+
await messageShown
435+
})
436+
describe('debounce behavior', function () {
437+
let clock: ReturnType<typeof installFakeClock>
438+
439+
beforeEach(function () {
440+
clock = installFakeClock()
441+
})
442+
443+
after(function () {
444+
clock.uninstall()
445+
})
446+
447+
it('should only trigger once on rapid events', async () => {
448+
provider = new AmazonQInlineCompletionItemProvider(
449+
languageClient,
450+
recommendationService,
451+
mockSessionManager,
452+
inlineTutorialAnnotation,
453+
false
454+
)
455+
const p1 = provider.provideInlineCompletionItems(mockDocument, mockPosition, mockContext, mockToken)
456+
const p2 = provider.provideInlineCompletionItems(mockDocument, mockPosition, mockContext, mockToken)
457+
const p3 = provider.provideInlineCompletionItems(
458+
mockDocument,
459+
new Position(2, 2),
460+
mockContext,
461+
mockToken
462+
)
440463

441-
await clock.tickAsync(1000)
464+
await clock.tickAsync(1000)
442465

443-
// All promises should be the same object when debounced properly.
444-
assert.strictEqual(p1, p2)
445-
assert.strictEqual(p1, p3)
446-
await p1
447-
await p2
448-
const r3 = await p3
466+
// All promises should be the same object when debounced properly.
467+
assert.strictEqual(p1, p2)
468+
assert.strictEqual(p1, p3)
469+
await p1
470+
await p2
471+
const r3 = await p3
449472

450-
// calls the function with the latest provided args.
451-
assert.deepStrictEqual((r3 as InlineCompletionItem[])[0].range?.end, new Position(2, 2))
452-
})
473+
// calls the function with the latest provided args.
474+
assert.deepStrictEqual((r3 as InlineCompletionItem[])[0].range?.end, new Position(2, 2))
453475
})
476+
})
454477
})
455478
})
456479
})

packages/core/src/codewhisperer/models/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export const runningSecurityScan = 'Reviewing project for code issues...'
155155

156156
export const runningFileScan = 'Reviewing current file for code issues...'
157157

158-
export const noSuggestions = 'No suggestions from Amazon Q'
158+
export const noInlineSuggestionsMsg = 'No suggestions from Amazon Q'
159159

160160
export const licenseFilter = 'Amazon Q suggestions were filtered due to reference settings'
161161

packages/core/src/shared/utilities/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
export { isExtensionInstalled, isExtensionActive } from './vsCodeUtils'
77
export { VSCODE_EXTENSION_ID } from '../extensions'
88
export * from './functionUtils'
9+
export * as messageUtils from './messages'

0 commit comments

Comments
 (0)