Skip to content

Commit 6171315

Browse files
committed
Merge remote-tracking branch 'origin/master' into implement_rules
2 parents c03c6f4 + 4d56741 commit 6171315

36 files changed

+1204
-70
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/amazonq/.changes/1.88.0.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"date": "2025-08-06",
3+
"version": "1.88.0",
4+
"entries": [
5+
{
6+
"type": "Feature",
7+
"description": "Amazon Q Chat provides error explanations and fixes when hovering or right-clicking on error indicators and messages"
8+
},
9+
{
10+
"type": "Feature",
11+
"description": "/transform: Show transformation history in Transformation Hub and allow users to resume jobs"
12+
}
13+
]
14+
}

packages/amazonq/.changes/next-release/Feature-dffec708-ae10-45d7-bcfd-b1c07a84de12.json

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

packages/amazonq/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.88.0 2025-08-06
2+
3+
- **Feature** Amazon Q Chat provides error explanations and fixes when hovering or right-clicking on error indicators and messages
4+
- **Feature** /transform: Show transformation history in Transformation Hub and allow users to resume jobs
5+
16
## 1.87.0 2025-07-31
27

38
- Miscellaneous non-user-facing changes

packages/amazonq/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "amazon-q-vscode",
33
"displayName": "Amazon Q",
44
"description": "The most capable generative AI–powered assistant for software development.",
5-
"version": "1.88.0-SNAPSHOT",
5+
"version": "1.89.0-SNAPSHOT",
66
"extensionKind": [
77
"workspace"
88
],

packages/amazonq/src/app/inline/EditRendering/displayImage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,8 @@ export async function displaySvgDecoration(
352352
discarded: false,
353353
},
354354
},
355+
totalSessionDisplayTime: Date.now() - session.requestStartTime,
356+
firstCompletionDisplayLatency: session.firstCompletionDisplayLatency,
355357
isInlineEdit: true,
356358
}
357359
languageClient.sendNotification('aws/logInlineCompletionSessionResults', params)

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

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,11 @@ export class InlineCompletionManager implements Disposable {
170170
const onInlineRejection = async () => {
171171
try {
172172
vsCodeState.isCodeWhispererEditing = true
173-
if (this.sessionManager.getActiveSession() === undefined) {
173+
const session = this.sessionManager.getActiveSession()
174+
if (session === undefined) {
174175
return
175176
}
176-
const requestStartTime = this.sessionManager.getActiveSession()!.requestStartTime
177+
const requestStartTime = session.requestStartTime
177178
const totalSessionDisplayTime = performance.now() - requestStartTime
178179
await commands.executeCommand('editor.action.inlineSuggest.hide')
179180
// TODO: also log the seen state for other suggestions in session
@@ -182,9 +183,9 @@ export class InlineCompletionManager implements Disposable {
182183
CodeWhispererConstants.platformLanguageIds,
183184
this.inlineCompletionProvider
184185
)
185-
const sessionId = this.sessionManager.getActiveSession()?.sessionId
186+
const sessionId = session.sessionId
186187
const itemId = this.sessionManager.getActiveRecommendation()[0]?.itemId
187-
if (!sessionId || !itemId) {
188+
if (!itemId) {
188189
return
189190
}
190191
const params: LogInlineCompletionSessionResultsParams = {
@@ -196,6 +197,7 @@ export class InlineCompletionManager implements Disposable {
196197
discarded: false,
197198
},
198199
},
200+
firstCompletionDisplayLatency: session.firstCompletionDisplayLatency,
199201
totalSessionDisplayTime: totalSessionDisplayTime,
200202
}
201203
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
@@ -274,12 +276,6 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
274276

275277
// yield event loop to let the document listen catch updates
276278
await sleep(1)
277-
// prevent user deletion invoking auto trigger
278-
// this is a best effort estimate of deletion
279-
if (this.documentEventListener.isLastEventDeletion(document.uri.fsPath)) {
280-
getLogger().debug('Skip auto trigger when deleting code')
281-
return []
282-
}
283279

284280
let logstr = `GenerateCompletion metadata:\\n`
285281
try {
@@ -343,6 +339,7 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
343339
discarded: !prevSession.displayed,
344340
},
345341
},
342+
firstCompletionDisplayLatency: prevSession.firstCompletionDisplayLatency,
346343
totalSessionDisplayTime: performance.now() - prevSession.requestStartTime,
347344
}
348345
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
@@ -367,8 +364,8 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
367364
},
368365
token,
369366
isAutoTrigger,
370-
getAllRecommendationsOptions,
371-
this.documentEventListener.getLastDocumentChangeEvent(document.uri.fsPath)?.event
367+
this.documentEventListener,
368+
getAllRecommendationsOptions
372369
)
373370
// get active item from session for displaying
374371
const items = this.sessionManager.getActiveRecommendation()
@@ -401,21 +398,24 @@ ${itemLog}
401398

402399
const cursorPosition = document.validatePosition(position)
403400

404-
if (position.isAfter(editor.selection.active)) {
405-
const params: LogInlineCompletionSessionResultsParams = {
406-
sessionId: session.sessionId,
407-
completionSessionResult: {
408-
[itemId]: {
409-
seen: false,
410-
accepted: false,
411-
discarded: true,
401+
// Completion will not be rendered if users cursor moves to a position which is before the position when the service is invoked
402+
if (items.length > 0 && !items[0].isInlineEdit) {
403+
if (position.isAfter(editor.selection.active)) {
404+
const params: LogInlineCompletionSessionResultsParams = {
405+
sessionId: session.sessionId,
406+
completionSessionResult: {
407+
[itemId]: {
408+
seen: false,
409+
accepted: false,
410+
discarded: true,
411+
},
412412
},
413-
},
413+
}
414+
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
415+
this.sessionManager.clear()
416+
logstr += `- cursor moved behind trigger position. Discarding completion suggestion...`
417+
return []
414418
}
415-
this.languageClient.sendNotification(this.logSessionResultMessageName, params)
416-
this.sessionManager.clear()
417-
logstr += `- cursor moved behind trigger position. Discarding suggestion...`
418-
return []
419419
}
420420

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

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

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import * as vscode from 'vscode'
65
import {
76
InlineCompletionListWithReferences,
87
InlineCompletionWithReferencesParams,
98
inlineCompletionWithReferencesRequestType,
109
TextDocumentContentChangeEvent,
10+
editCompletionRequestType,
1111
} from '@aws/language-server-runtimes/protocol'
1212
import { CancellationToken, InlineCompletionContext, Position, TextDocument } from 'vscode'
1313
import { LanguageClient } from 'vscode-languageclient'
@@ -21,6 +21,7 @@ import {
2121
import { TelemetryHelper } from './telemetryHelper'
2222
import { ICursorUpdateRecorder } from './cursorUpdateManager'
2323
import { getLogger } from 'aws-core-vscode/shared'
24+
import { DocumentEventListener } from './documentEventListener'
2425
import { getOpenFilesInWindow } from 'aws-core-vscode/utils'
2526
import { asyncCallWithTimeout } from '../../util/timeoutUtil'
2627

@@ -66,9 +67,11 @@ export class RecommendationService {
6667
context: InlineCompletionContext,
6768
token: CancellationToken,
6869
isAutoTrigger: boolean,
69-
options: GetAllRecommendationsOptions = { emitTelemetry: true, showUi: true },
70-
documentChangeEvent?: vscode.TextDocumentChangeEvent
70+
documentEventListener: DocumentEventListener,
71+
options: GetAllRecommendationsOptions = { emitTelemetry: true, showUi: true }
7172
) {
73+
const documentChangeEvent = documentEventListener?.getLastDocumentChangeEvent(document.uri.fsPath)?.event
74+
7275
// Record that a regular request is being made
7376
this.cursorUpdateRecorder?.recordCompletionRequest()
7477
const documentChangeParams = documentChangeEvent
@@ -119,7 +122,51 @@ export class RecommendationService {
119122
})
120123
const t0 = performance.now()
121124

122-
const result = await this.getRecommendationsWithTimeout(languageClient, request, token)
125+
// Best effort estimate of deletion
126+
const isTriggerByDeletion = documentEventListener.isLastEventDeletion(document.uri.fsPath)
127+
128+
const ps: Promise<InlineCompletionListWithReferences>[] = []
129+
/**
130+
* IsTriggerByDeletion is to prevent user deletion invoking Completions.
131+
* PartialResultToken is not a hack for now since only Edits suggestion use partialResultToken across different calls of [getAllRecommendations],
132+
* Completions use PartialResultToken with single 1 call of [getAllRecommendations].
133+
* Edits leverage partialResultToken to achieve EditStreak such that clients can pull all continuous suggestions generated by the model within 1 EOS block.
134+
*/
135+
if (!isTriggerByDeletion && !request.partialResultToken) {
136+
const completionPromise: Promise<InlineCompletionListWithReferences> = languageClient.sendRequest(
137+
inlineCompletionWithReferencesRequestType.method,
138+
request,
139+
token
140+
)
141+
ps.push(completionPromise)
142+
}
143+
144+
/**
145+
* 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.
146+
*/
147+
const editPromise: Promise<InlineCompletionListWithReferences> = languageClient.sendRequest(
148+
editCompletionRequestType.method,
149+
request,
150+
token
151+
)
152+
ps.push(editPromise)
153+
154+
/**
155+
* First come first serve, ideally we should simply return the first response returned. However there are some caviar here because either
156+
* (1) promise might be returned early without going through service
157+
* (2) some users are not enabled with edits suggestion, therefore service will return empty result without passing through the model
158+
* 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.
159+
* This is the hack to return first "NON-EMPTY" response
160+
*/
161+
let result = await Promise.race(ps)
162+
if (ps.length > 1 && result.items.length === 0) {
163+
for (const p of ps) {
164+
const r = await p
165+
if (r.items.length > 0) {
166+
result = r
167+
}
168+
}
169+
}
123170

124171
getLogger().info('Received inline completion response from LSP: %O', {
125172
sessionId: result.sessionId,

packages/amazonq/src/extension.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { registerCommands } from './commands'
4545
import { focusAmazonQPanel } from 'aws-core-vscode/codewhispererChat'
4646
import { activate as activateAmazonqLsp } from './lsp/activation'
4747
import { hasGlibcPatch } from './lsp/client'
48+
import { activateAutoDebug } from './lsp/chat/autoDebug/activation'
4849

4950
export const amazonQContextPrefix = 'amazonq'
5051

@@ -131,6 +132,14 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
131132
await activateAmazonqLsp(context)
132133
}
133134

135+
// Activate AutoDebug feature at extension level
136+
try {
137+
const autoDebugFeature = await activateAutoDebug(context)
138+
context.subscriptions.push(autoDebugFeature)
139+
} catch (error) {
140+
getLogger().error('Failed to activate AutoDebug feature at extension level: %s', error)
141+
}
142+
134143
// Generic extension commands
135144
registerGenericCommands(context, amazonQContextPrefix)
136145

packages/amazonq/src/lsp/chat/activation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ import { activate as registerLegacyChatListeners } from '../../app/chat/activati
1717
import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq'
1818
import { AuthUtil, getSelectedCustomization } from 'aws-core-vscode/codewhisperer'
1919
import { pushConfigUpdate } from '../config'
20+
import { AutoDebugLspClient } from './autoDebug/lsp/autoDebugLspClient'
2021

2122
export async function activate(languageClient: LanguageClient, encryptionKey: Buffer, mynahUIPath: string) {
2223
const disposables = globals.context.subscriptions
2324

2425
const provider = new AmazonQChatViewProvider(mynahUIPath, languageClient)
2526

27+
// Set the chat view provider for AutoDebug to use
28+
AutoDebugLspClient.setChatViewProvider(provider)
29+
2630
disposables.push(
2731
window.registerWebviewViewProvider(AmazonQChatViewProvider.viewType, provider, {
2832
webviewOptions: {

0 commit comments

Comments
 (0)