Skip to content

Commit 7b161da

Browse files
author
aws-toolkit-automation
committed
Merge release into master
2 parents 44e72a7 + 7f62ee4 commit 7b161da

File tree

4 files changed

+69
-11
lines changed

4 files changed

+69
-11
lines changed
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": "Prompt re-authenticate if auto trigger failed with expired token"
4+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
265265
const prefix = document.getText(new Range(prevStartPosition, position))
266266
const prevItemMatchingPrefix = []
267267
for (const item of this.sessionManager.getActiveRecommendation()) {
268+
// if item is an Edit suggestion, insertText is a diff instead of new code contents, skip the logic to check for prefix.
269+
if (item.isInlineEdit) {
270+
continue
271+
}
268272
const text = typeof item.insertText === 'string' ? item.insertText : item.insertText.value
269273
if (text.startsWith(prefix) && position.isAfterOrEqual(prevStartPosition)) {
270274
item.command = {
@@ -319,6 +323,7 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
319323
position,
320324
context,
321325
token,
326+
isAutoTrigger,
322327
getAllRecommendationsOptions
323328
)
324329
// get active item from session for displaying

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { CancellationToken, InlineCompletionContext, Position, TextDocument } fr
1212
import { LanguageClient } from 'vscode-languageclient'
1313
import { SessionManager } from './sessionManager'
1414
import { InlineGeneratingMessage } from './inlineGeneratingMessage'
15-
import { CodeWhispererStatusBarManager } from 'aws-core-vscode/codewhisperer'
15+
import { AuthUtil, CodeWhispererStatusBarManager } from 'aws-core-vscode/codewhisperer'
1616
import { TelemetryHelper } from './telemetryHelper'
1717
import { ICursorUpdateRecorder } from './cursorUpdateManager'
1818
import { globals, getLogger } from 'aws-core-vscode/shared'
@@ -28,7 +28,6 @@ export class RecommendationService {
2828
private readonly inlineGeneratingMessage: InlineGeneratingMessage,
2929
private cursorUpdateRecorder?: ICursorUpdateRecorder
3030
) {}
31-
3231
/**
3332
* Set the recommendation service
3433
*/
@@ -42,6 +41,7 @@ export class RecommendationService {
4241
position: Position,
4342
context: InlineCompletionContext,
4443
token: CancellationToken,
44+
isAutoTrigger: boolean,
4545
options: GetAllRecommendationsOptions = { emitTelemetry: true, showUi: true }
4646
) {
4747
// Record that a regular request is being made
@@ -131,8 +131,20 @@ export class RecommendationService {
131131
this.sessionManager.closeSession()
132132
TelemetryHelper.instance.setAllPaginationEndTime()
133133
options.emitTelemetry && TelemetryHelper.instance.tryRecordClientComponentLatency()
134-
} catch (error) {
134+
} catch (error: any) {
135135
getLogger().error('Error getting recommendations: %O', error)
136+
// bearer token expired
137+
if (error.data && error.data.awsErrorCode === 'E_AMAZON_Q_CONNECTION_EXPIRED') {
138+
// ref: https://github.com/aws/aws-toolkit-vscode/blob/amazonq/v1.74.0/packages/core/src/codewhisperer/service/inlineCompletionService.ts#L104
139+
// show re-auth once if connection expired
140+
if (AuthUtil.instance.isConnectionExpired()) {
141+
await AuthUtil.instance.notifyReauthenticate(isAutoTrigger)
142+
} else {
143+
// get a new bearer token, if this failed, the connection will be marked as expired.
144+
// new tokens will be synced per 10 seconds in auth.startTokenRefreshInterval
145+
await AuthUtil.instance.getBearerToken()
146+
}
147+
}
136148
return []
137149
} finally {
138150
// Remove all UI indicators if UI is enabled

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

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,14 @@ describe('RecommendationService', () => {
138138

139139
sendRequestStub.resolves(mockFirstResult)
140140

141-
await service.getAllRecommendations(languageClient, mockDocument, mockPosition, mockContext, mockToken)
141+
await service.getAllRecommendations(
142+
languageClient,
143+
mockDocument,
144+
mockPosition,
145+
mockContext,
146+
mockToken,
147+
true
148+
)
142149

143150
// Verify sendRequest was called with correct parameters
144151
assert(sendRequestStub.calledOnce)
@@ -172,7 +179,14 @@ describe('RecommendationService', () => {
172179
sendRequestStub.onFirstCall().resolves(mockFirstResult)
173180
sendRequestStub.onSecondCall().resolves(mockSecondResult)
174181

175-
await service.getAllRecommendations(languageClient, mockDocument, mockPosition, mockContext, mockToken)
182+
await service.getAllRecommendations(
183+
languageClient,
184+
mockDocument,
185+
mockPosition,
186+
mockContext,
187+
mockToken,
188+
true
189+
)
176190

177191
// Verify sendRequest was called with correct parameters
178192
assert(sendRequestStub.calledTwice)
@@ -204,7 +218,14 @@ describe('RecommendationService', () => {
204218

205219
sendRequestStub.resolves(mockFirstResult)
206220

207-
await service.getAllRecommendations(languageClient, mockDocument, mockPosition, mockContext, mockToken)
221+
await service.getAllRecommendations(
222+
languageClient,
223+
mockDocument,
224+
mockPosition,
225+
mockContext,
226+
mockToken,
227+
true
228+
)
208229

209230
// Verify recordCompletionRequest was called
210231
// eslint-disable-next-line @typescript-eslint/unbound-method
@@ -232,10 +253,18 @@ describe('RecommendationService', () => {
232253
const { showGeneratingStub, hideGeneratingStub } = setupUITest()
233254

234255
// Call with showUi: false option
235-
await service.getAllRecommendations(languageClient, mockDocument, mockPosition, mockContext, mockToken, {
236-
showUi: false,
237-
emitTelemetry: true,
238-
})
256+
await service.getAllRecommendations(
257+
languageClient,
258+
mockDocument,
259+
mockPosition,
260+
mockContext,
261+
mockToken,
262+
true,
263+
{
264+
showUi: false,
265+
emitTelemetry: true,
266+
}
267+
)
239268

240269
// Verify UI methods were not called
241270
sinon.assert.notCalled(showGeneratingStub)
@@ -248,7 +277,14 @@ describe('RecommendationService', () => {
248277
const { showGeneratingStub, hideGeneratingStub } = setupUITest()
249278

250279
// Call with default options (showUi: true)
251-
await service.getAllRecommendations(languageClient, mockDocument, mockPosition, mockContext, mockToken)
280+
await service.getAllRecommendations(
281+
languageClient,
282+
mockDocument,
283+
mockPosition,
284+
mockContext,
285+
mockToken,
286+
true
287+
)
252288

253289
// Verify UI methods were called
254290
sinon.assert.calledOnce(showGeneratingStub)
@@ -284,6 +320,7 @@ describe('RecommendationService', () => {
284320
mockPosition,
285321
mockContext,
286322
mockToken,
323+
true,
287324
options
288325
)
289326

0 commit comments

Comments
 (0)