Skip to content

Commit 4c190f4

Browse files
authored
feat(amazonq): feedback system for internal users for /test aws#6748
## Problem - The unit test generation team lacks sufficient feedback to enhance the quality of their produced tests. ## Solution - Implementing the feedback system for internal users to evaluate and enhance unit test generation quality.
1 parent d337928 commit 4c190f4

File tree

5 files changed

+75
-19
lines changed

5 files changed

+75
-19
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export class Connector extends BaseConnector {
162162
body: messageData.message,
163163
canBeVoted: false,
164164
informationCard: messageData.informationCard,
165+
buttons: messageData.buttons ?? [],
165166
}
166167
this.onChatAnswerReceived(messageData.tabID, answer, messageData)
167168
}

packages/core/src/amazonqTest/chat/controller/controller.ts

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
import MessengerUtils, { ButtonActions } from './messenger/messengerUtils'
2727
import { getTelemetryReasonDesc, isAwsError } from '../../../shared/errors'
2828
import { ChatItemType } from '../../../amazonq/commons/model'
29-
import { ProgressField } from '@aws/mynah-ui'
29+
import { ChatItemButton, MynahIcons, ProgressField } from '@aws/mynah-ui'
3030
import { FollowUpTypes } from '../../../amazonq/commons/types'
3131
import {
3232
cancelBuild,
@@ -63,6 +63,9 @@ import {
6363
} from '../../../codewhisperer/models/constants'
6464
import { UserWrittenCodeTracker } from '../../../codewhisperer/tracker/userWrittenCodeTracker'
6565
import { ReferenceLogViewProvider } from '../../../codewhisperer/service/referenceLogViewProvider'
66+
import { submitFeedback } from '../../../feedback/vue/submitFeedback'
67+
import { placeholder } from '../../../shared/vscode/commands2'
68+
import { Auth } from '../../../auth/auth'
6669

6770
export interface TestChatControllerEventEmitters {
6871
readonly tabOpened: vscode.EventEmitter<any>
@@ -307,10 +310,22 @@ export class TestController {
307310
)
308311
if (session.stopIteration) {
309312
// Error from Science
310-
this.messenger.sendMessage(data.error.uiMessage.replaceAll('```', ''), data.tabID, 'answer')
313+
this.messenger.sendMessage(
314+
data.error.uiMessage.replaceAll('```', ''),
315+
data.tabID,
316+
'answer',
317+
'testGenErrorMessage',
318+
this.getFeedbackButtons()
319+
)
311320
} else {
312321
isCancel
313-
? this.messenger.sendMessage(data.error.uiMessage, data.tabID, 'answer')
322+
? this.messenger.sendMessage(
323+
data.error.uiMessage,
324+
data.tabID,
325+
'answer',
326+
'testGenErrorMessage',
327+
this.getFeedbackButtons()
328+
)
314329
: this.sendErrorMessage(data)
315330
}
316331
await this.sessionCleanUp()
@@ -330,7 +345,9 @@ export class TestController {
330345
return this.messenger.sendMessage(
331346
i18n('AWS.amazonq.featureDev.error.monthlyLimitReached'),
332347
tabID,
333-
'answer'
348+
'answer',
349+
'testGenErrorMessage',
350+
this.getFeedbackButtons()
334351
)
335352
}
336353
if (error.message.includes('Too many requests')) {
@@ -362,6 +379,7 @@ export class TestController {
362379
// This function handles actions if user clicked on any Button one of these cases will be executed
363380
private async handleFormActionClicked(data: any) {
364381
const typedAction = MessengerUtils.stringToEnumValue(ButtonActions, data.action as any)
382+
let getFeedbackCommentData = ''
365383
switch (typedAction) {
366384
case ButtonActions.STOP_TEST_GEN:
367385
testGenState.setToCancelling()
@@ -374,6 +392,16 @@ export class TestController {
374392
this.messenger.sendChatInputEnabled(data.tabID, true)
375393
await this.sessionCleanUp()
376394
break
395+
case ButtonActions.PROVIDE_FEEDBACK:
396+
getFeedbackCommentData = `Q Test Generation: RequestId: ${this.sessionStorage.getSession().startTestGenerationRequestId}, TestGenerationJobId: ${this.sessionStorage.getSession().testGenerationJob?.testGenerationJobId}`
397+
void submitFeedback(placeholder, 'Amazon Q', getFeedbackCommentData)
398+
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_provideFeedback' })
399+
this.messenger.sendMessage(
400+
'Unit test generation completed. Thanks for providing feedback.',
401+
data.tabID,
402+
'answer'
403+
)
404+
break
377405
}
378406
}
379407
// This function handles actions if user gives any input from the chatInput box
@@ -403,12 +431,31 @@ export class TestController {
403431
}
404432
}
405433

434+
private getFeedbackButtons(): ChatItemButton[] {
435+
const buttons: ChatItemButton[] = []
436+
if (Auth.instance.isInternalAmazonUser()) {
437+
buttons.push({
438+
keepCardAfterClick: false,
439+
text: 'How can we make /test better?',
440+
id: ButtonActions.PROVIDE_FEEDBACK,
441+
disabled: false, // allow button to be re-clicked
442+
position: 'outside',
443+
icon: 'comment' as MynahIcons,
444+
})
445+
}
446+
return buttons
447+
}
448+
406449
/**
407450
* Start Test Generation and show the code results
408451
*/
409452

410453
private async startTestGen(message: any, regenerateTests: boolean) {
411454
const session: Session = this.sessionStorage.getSession()
455+
// Perform session cleanup before start of unit test generation workflow unless there is an existing job in progress.
456+
if (!ChatSessionManager.Instance.getIsInProgress()) {
457+
await this.sessionCleanUp()
458+
}
412459
const tabID = this.sessionStorage.setActiveTab(message.tabID)
413460
getLogger().debug('startTestGen message: %O', message)
414461
getLogger().debug('startTestGen tabId: %O', message.tabID)
@@ -909,7 +956,13 @@ export class TestController {
909956

910957
// TODO: Check if there are more cases to endSession if yes create a enum or type for step
911958
private async endSession(data: any, step: FollowUpTypes) {
912-
this.messenger.sendMessage('Unit test generation completed.', data.tabID, 'answer')
959+
this.messenger.sendMessage(
960+
'Unit test generation completed.',
961+
data.tabID,
962+
'answer',
963+
'testGenEndSessionMessage',
964+
this.getFeedbackButtons()
965+
)
913966

914967
const session = this.sessionStorage.getSession()
915968
if (step === FollowUpTypes.RejectCode) {
@@ -1342,7 +1395,7 @@ export class TestController {
13421395
}
13431396
session.listOfTestGenerationJobId = []
13441397
session.testGenerationJobGroupName = undefined
1345-
session.testGenerationJob = undefined
1398+
// session.testGenerationJob = undefined
13461399
session.updatedBuildCommands = undefined
13471400
session.shortAnswer = undefined
13481401
session.testCoveragePercentage = 0

packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
UpdatePromptProgressMessage,
2525
} from '../../views/connector/connector'
2626
import { ChatItemType } from '../../../../amazonq/commons/model'
27-
import { ChatItemAction, ProgressField } from '@aws/mynah-ui'
27+
import { ChatItemAction, ChatItemButton, ProgressField } from '@aws/mynah-ui'
2828
import * as CodeWhispererConstants from '../../../../codewhisperer/models/constants'
2929
import { TriggerPayload } from '../../../../codewhispererChat/controllers/chat/model'
3030
import {
@@ -76,8 +76,16 @@ export class Messenger {
7676
this.dispatcher.sendChatMessage(new CapabilityCardMessage(params.tabID))
7777
}
7878

79-
public sendMessage(message: string, tabID: string, messageType: ChatItemType) {
80-
this.dispatcher.sendChatMessage(new ChatMessage({ message, messageType }, tabID))
79+
public sendMessage(
80+
message: string,
81+
tabID: string,
82+
messageType: ChatItemType,
83+
messageId?: string,
84+
buttons?: ChatItemButton[]
85+
) {
86+
this.dispatcher.sendChatMessage(
87+
new ChatMessage({ message, messageType, messageId: messageId, buttons: buttons }, tabID)
88+
)
8189
}
8290

8391
public sendShortSummary(params: {
@@ -159,16 +167,7 @@ export class Messenger {
159167
message = CodeWhispererConstants.invalidFileTypeChatMessage
160168
break
161169
}
162-
163-
this.dispatcher.sendChatMessage(
164-
new ChatMessage(
165-
{
166-
message,
167-
messageType: 'answer-stream',
168-
},
169-
tabID
170-
)
171-
)
170+
this.sendMessage(message, tabID, 'answer-stream')
172171
}
173172

174173
public sendErrorMessage(errorMessage: string, tabID: string) {

packages/core/src/amazonqTest/chat/controller/messenger/messengerUtils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export enum ButtonActions {
1212
VIEW_DIFF = 'View-Diff',
1313
STOP_TEST_GEN = 'Stop-Test-Generation',
1414
STOP_BUILD = 'Stop-Build-Process',
15+
PROVIDE_FEEDBACK = 'Provide-Feedback',
1516
}
1617

1718
// TODO: Refactor the common functionality between Transform, FeatureDev, CWSPRChat, Scan and UTG to a new Folder.

packages/core/src/amazonqTest/chat/views/connector/connector.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export class ChatMessage extends UiMessage {
8080
readonly messageId?: string | undefined
8181
readonly messageType: ChatItemType
8282
readonly canBeVoted?: boolean
83+
readonly buttons?: ChatItemButton[]
8384
readonly informationCard: ChatItemContent['informationCard']
8485
override type: TestMessageType = 'chatMessage'
8586

@@ -90,6 +91,7 @@ export class ChatMessage extends UiMessage {
9091
this.messageId = props.messageId || undefined
9192
this.canBeVoted = props.canBeVoted || undefined
9293
this.informationCard = props.informationCard || undefined
94+
this.buttons = props.buttons || undefined
9395
}
9496
}
9597

0 commit comments

Comments
 (0)