Skip to content

Commit 78c448b

Browse files
authored
fix(amazonq dev): user can view diffs of previous /dev iterations aws#5756
## Problem We currently only support accessing the last code generated (by the Tree view). If you try open the diff view in past history, will thrown an error. This happens because when we click on past history Tree we actually send a "newer" uploadId and didn't keep track of all the past ones. ## Solution Cache those uploadIds based on codeGenerationId which can be easily accessible while clicking in past views.
1 parent 4edf175 commit 78c448b

File tree

13 files changed

+78
-21
lines changed

13 files changed

+78
-21
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": "Amazon Q (/dev): view diffs of previous /dev iterations"
4+
}

packages/amazonq/test/unit/amazonqFeatureDev/session/session.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ describe('session', () => {
9696
[],
9797
[],
9898
tabID,
99-
0
99+
0,
100+
{}
100101
)
101102
const session = await createSession({ messenger, sessionState: codeGenState, conversationID })
102103
encodedContent = new TextEncoder().encode(notRejectedFileContent)

packages/core/src/amazonq/webview/ui/apps/featureDevChatConnector.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,13 @@ export class Connector {
9494
})
9595
}
9696

97-
onOpenDiff = (tabID: string, filePath: string, deleted: boolean): void => {
97+
onOpenDiff = (tabID: string, filePath: string, deleted: boolean, messageId?: string): void => {
9898
this.sendMessageToExtension({
9999
command: 'open-diff',
100100
tabID,
101101
filePath,
102102
deleted,
103+
messageId,
103104
tabType: 'featuredev',
104105
})
105106
}
@@ -167,7 +168,11 @@ export class Connector {
167168
canBeVoted: true,
168169
codeReference: messageData.references,
169170
// TODO get the backend to store a message id in addition to conversationID
170-
messageId: messageData.messageID ?? messageData.triggerID ?? messageData.conversationID,
171+
messageId:
172+
messageData.codeGenerationId ??
173+
messageData.messageID ??
174+
messageData.triggerID ??
175+
messageData.conversationID,
171176
fileList: {
172177
rootFolderTitle: 'Changes',
173178
filePaths: messageData.filePaths.map((f: DiffTreeFileInfo) => f.zipFilePath),

packages/core/src/amazonq/webview/ui/connector.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ export interface CodeReference {
2525
}
2626
}
2727

28+
export interface UploadHistory {
29+
[key: string]: {
30+
uploadId: string
31+
timestamp: number
32+
tabId: string
33+
filePaths: DiffTreeFileInfo[]
34+
deletedFiles: DiffTreeFileInfo[]
35+
}
36+
}
37+
2838
export interface ChatPayload {
2939
chatMessage: string
3040
chatCommand?: string
@@ -366,10 +376,10 @@ export class Connector {
366376
}
367377
}
368378

369-
onOpenDiff = (tabID: string, filePath: string, deleted: boolean): void => {
379+
onOpenDiff = (tabID: string, filePath: string, deleted: boolean, messageId?: string): void => {
370380
switch (this.tabsStorage.getTab(tabID)?.type) {
371381
case 'featuredev':
372-
this.featureDevChatConnector.onOpenDiff(tabID, filePath, deleted)
382+
this.featureDevChatConnector.onOpenDiff(tabID, filePath, deleted, messageId)
373383
break
374384
}
375385
}

packages/core/src/amazonqFeatureDev/controllers/chat/controller.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type OpenDiffMessage = {
6868
// currently the zip file path
6969
filePath: string
7070
deleted: boolean
71+
codeGenerationId: string
7172
}
7273

7374
type fileClickedMessage = {
@@ -409,7 +410,8 @@ export class FeatureDevController {
409410
deletedFiles,
410411
session.state.references ?? [],
411412
tabID,
412-
session.uploadId
413+
session.uploadId,
414+
session.state.codeGenerationId ?? ''
413415
)
414416

415417
const remainingIterations = session.state.codeGenerationRemainingIterationCount
@@ -695,6 +697,7 @@ export class FeatureDevController {
695697

696698
private async openDiff(message: OpenDiffMessage) {
697699
const tabId: string = message.tabID
700+
const codeGenerationId: string = message.messageId
698701
const zipFilePath: string = message.filePath
699702
const session = await this.sessionStorage.getSession(tabId)
700703
telemetry.amazonq_isReviewedChanges.emit({
@@ -711,7 +714,11 @@ export class FeatureDevController {
711714
const name = path.basename(pathInfos.relativePath)
712715
await openDeletedDiff(pathInfos.absolutePath, name, tabId)
713716
} else {
714-
const rightPath = path.join(session.uploadId, zipFilePath)
717+
let uploadId = session.uploadId
718+
if (session?.state?.uploadHistory && session.state.uploadHistory[codeGenerationId]) {
719+
uploadId = session?.state?.uploadHistory[codeGenerationId].uploadId
720+
}
721+
const rightPath = path.join(uploadId, zipFilePath)
715722
await openDiff(pathInfos.absolutePath, rightPath, tabId)
716723
}
717724
}

packages/core/src/amazonqFeatureDev/controllers/chat/messenger/messenger.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,12 @@ export class Messenger {
115115
deletedFiles: DeletedFileInfo[],
116116
references: CodeReference[],
117117
tabID: string,
118-
uploadId: string
118+
uploadId: string,
119+
codeGenerationId: string
119120
) {
120-
this.dispatcher.sendCodeResult(new CodeResultMessage(filePaths, deletedFiles, references, tabID, uploadId))
121+
this.dispatcher.sendCodeResult(
122+
new CodeResultMessage(filePaths, deletedFiles, references, tabID, uploadId, codeGenerationId)
123+
)
121124
}
122125

123126
public sendAsyncEventProgress(tabID: string, inProgress: boolean, message: string | undefined) {

packages/core/src/amazonqFeatureDev/session/session.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export class Session {
130130
fs: this.config.fs,
131131
messenger: this.messenger,
132132
telemetry: this.telemetry,
133+
uploadHistory: this.state.uploadHistory,
133134
})
134135

135136
if (resp.nextState) {

packages/core/src/amazonqFeatureDev/session/sessionState.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import {
3636
import { prepareRepoData } from '../util/files'
3737
import { TelemetryHelper } from '../util/telemetryHelper'
3838
import { uploadCode } from '../util/upload'
39-
import { CodeReference } from '../../amazonq/webview/ui/connector'
39+
import { CodeReference, UploadHistory } from '../../amazonq/webview/ui/connector'
4040
import { isPresent } from '../../shared/utilities/collectionUtils'
4141
import { AuthUtil } from '../../codewhisperer/util/authUtil'
4242
import { randomUUID } from '../../shared/crypto'
@@ -261,6 +261,7 @@ export class CodeGenState extends CodeGenBase implements SessionState {
261261
public references: CodeReference[],
262262
tabID: string,
263263
private currentIteration: number,
264+
public uploadHistory: UploadHistory,
264265
public codeGenerationRemainingIterationCount?: number,
265266
public codeGenerationTotalIterationCount?: number
266267
) {
@@ -308,6 +309,16 @@ export class CodeGenState extends CodeGenBase implements SessionState {
308309
this.codeGenerationRemainingIterationCount = codeGeneration.codeGenerationRemainingIterationCount
309310
this.codeGenerationTotalIterationCount = codeGeneration.codeGenerationTotalIterationCount
310311

312+
if (action.uploadHistory && !action.uploadHistory[codeGenerationId] && codeGenerationId) {
313+
action.uploadHistory[codeGenerationId] = {
314+
timestamp: Date.now(),
315+
uploadId: this.config.uploadId,
316+
filePaths: codeGeneration.newFiles,
317+
deletedFiles: codeGeneration.deletedFiles,
318+
tabId: this.tabID,
319+
}
320+
}
321+
311322
action.telemetry.setAmazonqNumberOfReferences(this.references.length)
312323
action.telemetry.recordUserCodeGenerationTelemetry(span, this.conversationId)
313324
const nextState = new PrepareCodeGenState(
@@ -318,7 +329,9 @@ export class CodeGenState extends CodeGenBase implements SessionState {
318329
this.tabID,
319330
this.currentIteration + 1,
320331
this.codeGenerationRemainingIterationCount,
321-
this.codeGenerationTotalIterationCount
332+
this.codeGenerationTotalIterationCount,
333+
action.uploadHistory,
334+
codeGenerationId
322335
)
323336
return {
324337
nextState,
@@ -338,6 +351,7 @@ export class MockCodeGenState implements SessionState {
338351
public filePaths: NewFileInfo[]
339352
public deletedFiles: DeletedFileInfo[]
340353
public readonly conversationId: string
354+
public readonly codeGenerationId?: string
341355
public readonly uploadId: string
342356

343357
constructor(
@@ -384,7 +398,8 @@ export class MockCodeGenState implements SessionState {
384398
},
385399
],
386400
this.tabID,
387-
this.uploadId
401+
this.uploadId,
402+
this.codeGenerationId ?? ''
388403
)
389404
action.messenger.sendAnswer({
390405
message: undefined,
@@ -431,11 +446,15 @@ export class PrepareCodeGenState implements SessionState {
431446
public tabID: string,
432447
private currentIteration: number,
433448
public codeGenerationRemainingIterationCount?: number,
434-
public codeGenerationTotalIterationCount?: number
449+
public codeGenerationTotalIterationCount?: number,
450+
public uploadHistory: UploadHistory = {},
451+
public codeGenerationId?: string
435452
) {
436453
this.tokenSource = new vscode.CancellationTokenSource()
437454
this.uploadId = config.uploadId
438455
this.conversationId = config.conversationId
456+
this.uploadHistory = uploadHistory
457+
this.codeGenerationId = codeGenerationId
439458
}
440459

441460
updateWorkspaceRoot(workspaceRoot: string) {
@@ -490,7 +509,8 @@ export class PrepareCodeGenState implements SessionState {
490509
this.deletedFiles,
491510
this.references,
492511
this.tabID,
493-
this.currentIteration
512+
this.currentIteration,
513+
this.uploadHistory
494514
)
495515
return nextState.interact(action)
496516
}

packages/core/src/amazonqFeatureDev/types.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { CancellationTokenSource } from 'vscode'
99
import { Messenger } from './controllers/chat/messenger/messenger'
1010
import { FeatureDevClient } from './client/featureDev'
1111
import { TelemetryHelper } from './util/telemetryHelper'
12-
import { CodeReference } from '../amazonq/webview/ui/connector'
12+
import { CodeReference, UploadHistory } from '../amazonq/webview/ui/connector'
1313
import { DiffTreeFileInfo } from '../amazonq/webview/ui/diffTree/types'
1414

1515
export type Interaction = {
@@ -61,11 +61,13 @@ export interface SessionState {
6161
readonly phase?: SessionStatePhase
6262
readonly uploadId: string
6363
readonly tokenSource: CancellationTokenSource
64+
readonly codeGenerationId?: string
6465
readonly tabID: string
6566
interact(action: SessionStateAction): Promise<SessionStateInteraction>
6667
updateWorkspaceRoot?: (workspaceRoot: string) => void
6768
codeGenerationRemainingIterationCount?: number
6869
codeGenerationTotalIterationCount?: number
70+
uploadHistory?: UploadHistory
6971
}
7072

7173
export interface SessionStateConfig {
@@ -82,6 +84,7 @@ export interface SessionStateAction {
8284
messenger: Messenger
8385
fs: VirtualFileSystem
8486
telemetry: TelemetryHelper
87+
uploadHistory?: UploadHistory
8588
}
8689

8790
export type NewFileZipContents = { zipFilePath: string; fileContent: string }

packages/core/src/amazonqFeatureDev/views/actions/uiMessageListener.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ export class UIMessageListener {
108108
tabID: msg.tabID,
109109
filePath: msg.filePath,
110110
deleted: msg.deleted,
111+
messageId: msg.messageId,
111112
})
112113
}
113114

0 commit comments

Comments
 (0)