Skip to content

Commit ce88bd9

Browse files
aws-toolkit-automationroger-zhanggfloralphrhamiltlaileni-aws
authored andcommitted
Merge master into feature/ui-e2e-tests (#7767)
- Resolve conflicts and push to this PR branch. - **Do not squash-merge** this PR. Use the "Create a merge commit" option to do a regular merge. To perform the merge from the command line, you could do something like the following (where "origin" is the name of the remote in your local git repo): ``` git stash git fetch --all git checkout origin/feature/ui-e2e-tests git merge origin/master git commit git push origin HEAD:refs/heads/autoMerge/feature/ui-e2e-tests ``` --------- Co-authored-by: Roger Zhang <[email protected]> Co-authored-by: 🥩 Flora <[email protected]> Co-authored-by: Reed Hamilton <[email protected]> Co-authored-by: Laxman Reddy <[email protected]> Co-authored-by: Roger Zhang <[email protected]> Co-authored-by: Jacob Chung <[email protected]> Co-authored-by: aws-asolidu <[email protected]> Co-authored-by: Newton Der <[email protected]> Co-authored-by: Newton Der <[email protected]> Co-authored-by: aws-toolkit-automation <> Co-authored-by: Tyrone Smith <[email protected]> Co-authored-by: Aidan Ton <[email protected]> Co-authored-by: abhraina-aws <[email protected]> Co-authored-by: atontb <[email protected]> Co-authored-by: Nitish <[email protected]> Co-authored-by: Nitish Kumar Singh <[email protected]> Co-authored-by: Blake Lazarine <[email protected]> Co-authored-by: mkovelam <[email protected]> Co-authored-by: BlakeLazarine <[email protected]> Co-authored-by: Will Lo <[email protected]> Co-authored-by: Na Yue <[email protected]> Co-authored-by: Lei Gao <[email protected]> Co-authored-by: tsmithsz <[email protected]> Co-authored-by: Reed Hamilton <[email protected]> Co-authored-by: Boyu <[email protected]> Co-authored-by: Dung Dong <[email protected]> Co-authored-by: Bryce Ito <[email protected]> Co-authored-by: Suraj Reddy <[email protected]>
1 parent e397620 commit ce88bd9

File tree

12 files changed

+44
-328
lines changed

12 files changed

+44
-328
lines changed

package-lock.json

Lines changed: 1 addition & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Faster and more responsive inline completion UX"
4+
}

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ export class InlineCompletionManager implements Disposable {
164164
const onInlineRejection = async () => {
165165
try {
166166
vsCodeState.isCodeWhispererEditing = true
167+
if (this.sessionManager.getActiveSession() === undefined) {
168+
return
169+
}
170+
const requestStartTime = this.sessionManager.getActiveSession()!.requestStartTime
171+
const totalSessionDisplayTime = performance.now() - requestStartTime
167172
await commands.executeCommand('editor.action.inlineSuggest.hide')
168173
// TODO: also log the seen state for other suggestions in session
169174
this.disposable.dispose()
@@ -185,6 +190,7 @@ export class InlineCompletionManager implements Disposable {
185190
discarded: false,
186191
},
187192
},
193+
totalSessionDisplayTime: totalSessionDisplayTime,
188194
}
189195
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
190196
// clear session manager states once rejected
@@ -330,7 +336,6 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
330336
discarded: !prevSession.displayed,
331337
},
332338
},
333-
firstCompletionDisplayLatency: prevSession.firstCompletionDisplayLatency,
334339
totalSessionDisplayTime: performance.now() - prevSession.requestStartTime,
335340
}
336341
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
@@ -389,24 +394,25 @@ ${itemLog}
389394

390395
const cursorPosition = document.validatePosition(position)
391396

392-
// Completion will not be rendered if users cursor moves to a position which is before the position when the service is invoked
393-
if (items.length > 0 && !items[0].isInlineEdit) {
394-
if (position.isAfter(editor.selection.active)) {
395-
const params: LogInlineCompletionSessionResultsParams = {
396-
sessionId: session.sessionId,
397-
completionSessionResult: {
398-
[itemId]: {
399-
seen: false,
400-
accepted: false,
401-
discarded: true,
402-
},
397+
if (position.isAfter(editor.selection.active)) {
398+
const params: LogInlineCompletionSessionResultsParams = {
399+
sessionId: session.sessionId,
400+
completionSessionResult: {
401+
[itemId]: {
402+
seen: false,
403+
accepted: false,
404+
discarded: true,
403405
},
404406
}
405407
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
406408
this.sessionManager.clear()
407409
logstr += `- cursor moved behind trigger position. Discarding completion suggestion...`
408410
return []
409411
}
412+
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
413+
this.sessionManager.clear()
414+
logstr += `- cursor moved behind trigger position. Discarding suggestion...`
415+
return []
410416
}
411417

412418
// delay the suggestion rendeing if user is actively typing

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

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,10 @@ import {
1212
import { CancellationToken, InlineCompletionContext, Position, TextDocument } from 'vscode'
1313
import { LanguageClient } from 'vscode-languageclient'
1414
import { SessionManager } from './sessionManager'
15-
import {
16-
AuthUtil,
17-
CodeWhispererConstants,
18-
CodeWhispererStatusBarManager,
19-
vsCodeState,
20-
} from 'aws-core-vscode/codewhisperer'
15+
import { AuthUtil, CodeWhispererStatusBarManager, vsCodeState } from 'aws-core-vscode/codewhisperer'
2116
import { TelemetryHelper } from './telemetryHelper'
2217
import { ICursorUpdateRecorder } from './cursorUpdateManager'
2318
import { getLogger } from 'aws-core-vscode/shared'
24-
import { DocumentEventListener } from './documentEventListener'
25-
import { getOpenFilesInWindow } from 'aws-core-vscode/utils'
26-
import { asyncCallWithTimeout } from '../../util/timeoutUtil'
2719

2820
export interface GetAllRecommendationsOptions {
2921
emitTelemetry?: boolean
@@ -119,53 +111,11 @@ export class RecommendationService {
119111
},
120112
})
121113
const t0 = performance.now()
122-
123-
// Best effort estimate of deletion
124-
const isTriggerByDeletion = documentEventListener.isLastEventDeletion(document.uri.fsPath)
125-
126-
const ps: Promise<InlineCompletionListWithReferences>[] = []
127-
/**
128-
* IsTriggerByDeletion is to prevent user deletion invoking Completions.
129-
* PartialResultToken is not a hack for now since only Edits suggestion use partialResultToken across different calls of [getAllRecommendations],
130-
* Completions use PartialResultToken with single 1 call of [getAllRecommendations].
131-
* Edits leverage partialResultToken to achieve EditStreak such that clients can pull all continuous suggestions generated by the model within 1 EOS block.
132-
*/
133-
if (!isTriggerByDeletion && !request.partialResultToken) {
134-
const completionPromise: Promise<InlineCompletionListWithReferences> = languageClient.sendRequest(
135-
inlineCompletionWithReferencesRequestType.method,
136-
request,
137-
token
138-
)
139-
ps.push(completionPromise)
140-
}
141-
142-
/**
143-
* Though Edit request is sent on keystrokes everytime, the language server will execute the request in a debounced manner so that it won't be immediately executed.
144-
*/
145-
const editPromise: Promise<InlineCompletionListWithReferences> = languageClient.sendRequest(
146-
editCompletionRequestType.method,
114+
const result: InlineCompletionListWithReferences = await languageClient.sendRequest(
115+
inlineCompletionWithReferencesRequestType.method,
147116
request,
148117
token
149118
)
150-
ps.push(editPromise)
151-
152-
/**
153-
* First come first serve, ideally we should simply return the first response returned. However there are some caviar here because either
154-
* (1) promise might be returned early without going through service
155-
* (2) some users are not enabled with edits suggestion, therefore service will return empty result without passing through the model
156-
* With the scenarios listed above or others, it's possible that 1 promise will ALWAYS win the race and users will NOT get any suggestion back.
157-
* This is the hack to return first "NON-EMPTY" response
158-
*/
159-
let result = await Promise.race(ps)
160-
if (ps.length > 1 && result.items.length === 0) {
161-
for (const p of ps) {
162-
const r = await p
163-
if (r.items.length > 0) {
164-
result = r
165-
}
166-
}
167-
}
168-
169119
getLogger().info('Received inline completion response from LSP: %O', {
170120
sessionId: result.sessionId,
171121
latency: performance.now() - t0,
@@ -198,6 +148,7 @@ export class RecommendationService {
198148

199149
const isInlineEdit = result.items.some((item) => item.isInlineEdit)
200150

151+
// TODO: question, is it possible that the first request returns empty suggestion but has non-empty next token?
201152
if (result.partialResultToken) {
202153
if (!isInlineEdit) {
203154
// If the suggestion is COMPLETIONS and there are more results to fetch, handle them in the background
@@ -248,7 +199,11 @@ export class RecommendationService {
248199
while (nextToken) {
249200
const request = { ...initialRequest, partialResultToken: nextToken }
250201

251-
const result = await this.getRecommendationsWithTimeout(languageClient, request, token)
202+
const result: InlineCompletionListWithReferences = await languageClient.sendRequest(
203+
inlineCompletionWithReferencesRequestType.method,
204+
request,
205+
token
206+
)
252207
// when pagination is in progress, but user has already accepted or rejected an inline completion
253208
// then stop pagination
254209
if (this.sessionManager.getActiveSession() === undefined || vsCodeState.isCodeWhispererEditing) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,12 @@ export class SessionManager {
131131
}
132132
}
133133

134+
public checkInlineSuggestionVisibility() {
135+
if (this.activeSession) {
136+
this.activeSession.displayed = true
137+
}
138+
}
139+
134140
private clearReferenceInlineHintsAndImportHints() {
135141
ReferenceInlineProvider.instance.removeInlineReference()
136142
ImportAdderProvider.instance.clear()

packages/amazonq/src/lsp/client.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export async function startLanguageServer(
187187
window: {
188188
notifications: true,
189189
showSaveFileDialog: true,
190-
showLogs: true,
190+
showLogs: isSageMaker() ? false : true,
191191
},
192192
textDocument: {
193193
inlineCompletionWithReferences: textDocSection,
@@ -363,6 +363,10 @@ async function onLanguageServerReady(
363363
await vscode.commands.executeCommand('editor.action.inlineSuggest.showNext')
364364
sessionManager.onNextSuggestion()
365365
}),
366+
// this is a workaround since handleDidShowCompletionItem is not public API
367+
Commands.register('aws.amazonq.checkInlineSuggestionVisibility', async () => {
368+
sessionManager.checkInlineSuggestionVisibility()
369+
}),
366370
Commands.register({ id: 'aws.amazonq.invokeInlineCompletion', autoconnect: true }, async () => {
367371
vsCodeState.lastManualTriggerTime = performance.now()
368372
await vscode.commands.executeCommand('editor.action.inlineSuggest.trigger')

packages/core/src/amazonq/indexNode.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,4 @@
77
* These agents have underlying requirements on node dependencies (e.g. jsdom, admzip)
88
*/
99
export { init as cwChatAppInit } from '../codewhispererChat/app'
10-
export { init as featureDevChatAppInit } from '../amazonqFeatureDev/app' // TODO: Remove this
1110
export { init as gumbyChatAppInit } from '../amazonqGumby/app'
12-
export { init as docChatAppInit } from '../amazonqDoc/app' // TODO: Remove this

packages/core/src/amazonq/webview/ui/storages/tabsStorage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
export type TabStatus = 'free' | 'busy' | 'dead'
7-
const TabTypes = ['cwc', 'gumby', 'review', 'agentWalkthrough', 'welcome', 'unknown'] as const
7+
const TabTypes = ['cwc', 'gumby', 'review', 'welcome', 'unknown'] as const
88
export type TabType = (typeof TabTypes)[number]
99
export function isTabType(value: string): value is TabType {
1010
return (TabTypes as readonly string[]).includes(value)

packages/core/src/amazonqDoc/app.ts

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)