@@ -8,14 +8,15 @@ import {
88 InlineCompletionContext ,
99 InlineCompletionItem ,
1010 InlineCompletionItemProvider ,
11- InlineCompletionList ,
1211 Position ,
1312 TextDocument ,
1413 commands ,
1514 languages ,
1615 Disposable ,
1716 window ,
1817 TextEditor ,
18+ InlineCompletionTriggerKind ,
19+ Range ,
1920} from 'vscode'
2021import { LanguageClient } from 'vscode-languageclient'
2122import {
@@ -30,34 +31,60 @@ import {
3031 ReferenceInlineProvider ,
3132 ReferenceLogViewProvider ,
3233 ImportAdderProvider ,
34+ CodeSuggestionsState ,
35+ vsCodeState ,
36+ inlineCompletionsDebounceDelay ,
37+ noInlineSuggestionsMsg ,
3338} from 'aws-core-vscode/codewhisperer'
39+ import { InlineGeneratingMessage } from './inlineGeneratingMessage'
40+ import { LineTracker } from './stateTracker/lineTracker'
41+ import { InlineTutorialAnnotation } from './tutorials/inlineTutorialAnnotation'
42+ import { TelemetryHelper } from './telemetryHelper'
43+ import { getLogger } from 'aws-core-vscode/shared'
44+ import { debounce , messageUtils } from 'aws-core-vscode/utils'
3445
3546export class InlineCompletionManager implements Disposable {
3647 private disposable : Disposable
3748 private inlineCompletionProvider : AmazonQInlineCompletionItemProvider
3849 private languageClient : LanguageClient
3950 private sessionManager : SessionManager
4051 private recommendationService : RecommendationService
52+ private lineTracker : LineTracker
53+ private incomingGeneratingMessage : InlineGeneratingMessage
54+ private inlineTutorialAnnotation : InlineTutorialAnnotation
4155 private readonly logSessionResultMessageName = 'aws/logInlineCompletionSessionResults'
4256
43- constructor ( languageClient : LanguageClient ) {
57+ constructor (
58+ languageClient : LanguageClient ,
59+ sessionManager : SessionManager ,
60+ lineTracker : LineTracker ,
61+ inlineTutorialAnnotation : InlineTutorialAnnotation
62+ ) {
4463 this . languageClient = languageClient
45- this . sessionManager = new SessionManager ( )
46- this . recommendationService = new RecommendationService ( this . sessionManager )
64+ this . sessionManager = sessionManager
65+ this . lineTracker = lineTracker
66+ this . incomingGeneratingMessage = new InlineGeneratingMessage ( this . lineTracker )
67+ this . recommendationService = new RecommendationService ( this . sessionManager , this . incomingGeneratingMessage )
68+ this . inlineTutorialAnnotation = inlineTutorialAnnotation
4769 this . inlineCompletionProvider = new AmazonQInlineCompletionItemProvider (
4870 languageClient ,
4971 this . recommendationService ,
50- this . sessionManager
72+ this . sessionManager ,
73+ this . inlineTutorialAnnotation
5174 )
5275 this . disposable = languages . registerInlineCompletionItemProvider (
5376 CodeWhispererConstants . platformLanguageIds ,
5477 this . inlineCompletionProvider
5578 )
79+
80+ this . lineTracker . ready ( )
5681 }
5782
5883 public dispose ( ) : void {
5984 if ( this . disposable ) {
6085 this . disposable . dispose ( )
86+ this . incomingGeneratingMessage . dispose ( )
87+ this . lineTracker . dispose ( )
6188 }
6289 }
6390
@@ -101,6 +128,7 @@ export class InlineCompletionManager implements Disposable {
101128 if ( item . mostRelevantMissingImports ?. length ) {
102129 await ImportAdderProvider . instance . onAcceptRecommendation ( editor , item , startLine )
103130 }
131+ this . sessionManager . incrementSuggestionCount ( )
104132 }
105133 commands . registerCommand ( 'aws.amazonq.acceptInline' , onInlineAcceptance )
106134
@@ -145,6 +173,7 @@ export class InlineCompletionManager implements Disposable {
145173 this . languageClient ,
146174 this . recommendationService ,
147175 this . sessionManager ,
176+ this . inlineTutorialAnnotation ,
148177 false
149178 )
150179 )
@@ -170,52 +199,91 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
170199 private readonly languageClient : LanguageClient ,
171200 private readonly recommendationService : RecommendationService ,
172201 private readonly sessionManager : SessionManager ,
202+ private readonly inlineTutorialAnnotation : InlineTutorialAnnotation ,
173203 private readonly isNewSession : boolean = true
174204 ) { }
175205
176- async provideInlineCompletionItems (
206+ provideInlineCompletionItems = debounce (
207+ this . _provideInlineCompletionItems . bind ( this ) ,
208+ inlineCompletionsDebounceDelay ,
209+ true
210+ )
211+
212+ private async _provideInlineCompletionItems (
177213 document : TextDocument ,
178214 position : Position ,
179215 context : InlineCompletionContext ,
180216 token : CancellationToken
181- ) : Promise < InlineCompletionItem [ ] | InlineCompletionList > {
182- if ( this . isNewSession ) {
183- // make service requests if it's a new session
184- await this . recommendationService . getAllRecommendations (
185- this . languageClient ,
186- document ,
187- position ,
188- context ,
189- token
190- )
191- }
192- // get active item from session for displaying
193- const items = this . sessionManager . getActiveRecommendation ( )
194- const session = this . sessionManager . getActiveSession ( )
195- if ( ! session || ! items . length ) {
196- return [ ]
197- }
198- const editor = window . activeTextEditor
199- for ( const item of items ) {
200- item . command = {
201- command : 'aws.amazonq.acceptInline' ,
202- title : 'On acceptance' ,
203- arguments : [
204- session . sessionId ,
205- item ,
206- editor ,
207- session . requestStartTime ,
208- position . line ,
209- session . firstCompletionDisplayLatency ,
210- ] ,
217+ ) : Promise < InlineCompletionItem [ ] > {
218+ try {
219+ vsCodeState . isRecommendationsActive = true
220+ if ( this . isNewSession ) {
221+ const isAutoTrigger = context . triggerKind === InlineCompletionTriggerKind . Automatic
222+ if ( isAutoTrigger && ! CodeSuggestionsState . instance . isSuggestionsEnabled ( ) ) {
223+ // return early when suggestions are disabled with auto trigger
224+ return [ ]
225+ }
226+
227+ // tell the tutorial that completions has been triggered
228+ await this . inlineTutorialAnnotation . triggered ( context . triggerKind )
229+ TelemetryHelper . instance . setInvokeSuggestionStartTime ( )
230+ TelemetryHelper . instance . setTriggerType ( context . triggerKind )
231+
232+ // make service requests if it's a new session
233+ await this . recommendationService . getAllRecommendations (
234+ this . languageClient ,
235+ document ,
236+ position ,
237+ context ,
238+ token
239+ )
211240 }
212- ReferenceInlineProvider . instance . setInlineReference (
213- position . line ,
214- item . insertText as string ,
215- item . references
216- )
217- ImportAdderProvider . instance . onShowRecommendation ( document , position . line , item )
241+ // get active item from session for displaying
242+ const items = this . sessionManager . getActiveRecommendation ( )
243+ const session = this . sessionManager . getActiveSession ( )
244+ 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+
251+ if ( ! session || ! items . length || ! editor ) {
252+ getLogger ( ) . debug (
253+ `Failed to produce inline suggestion results. Received ${ items . length } items from service`
254+ )
255+ return [ ]
256+ }
257+
258+ const cursorPosition = document . validatePosition ( position )
259+ for ( const item of items ) {
260+ item . command = {
261+ command : 'aws.amazonq.acceptInline' ,
262+ title : 'On acceptance' ,
263+ arguments : [
264+ session . sessionId ,
265+ item ,
266+ editor ,
267+ session . requestStartTime ,
268+ cursorPosition . line ,
269+ session . firstCompletionDisplayLatency ,
270+ ] ,
271+ }
272+ item . range = new Range ( cursorPosition , cursorPosition )
273+ item . insertText = typeof item . insertText === 'string' ? item . insertText : item . insertText . value
274+ ReferenceInlineProvider . instance . setInlineReference (
275+ cursorPosition . line ,
276+ item . insertText ,
277+ item . references
278+ )
279+ ImportAdderProvider . instance . onShowRecommendation ( document , cursorPosition . line , item )
280+ }
281+ return items as InlineCompletionItem [ ]
282+ } catch ( e ) {
283+ getLogger ( 'amazonqLsp' ) . error ( 'Failed to provide completion items: %O' , e )
284+ return [ ]
285+ } finally {
286+ vsCodeState . isRecommendationsActive = false
218287 }
219- return items as InlineCompletionItem [ ]
220288 }
221289}
0 commit comments