Skip to content

Commit 01432e9

Browse files
authored
Merge branch 'aws:master' into fixUTG
2 parents 3bb0d28 + d6be742 commit 01432e9

File tree

15 files changed

+184
-59
lines changed

15 files changed

+184
-59
lines changed

packages/amazonq/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
142142
// Give time for the extension to finish initializing.
143143
globals.clock.setTimeout(async () => {
144144
CommonAuthWebview.authSource = ExtStartUpSources.firstStartUp
145-
void focusAmazonQPanel.execute(placeholder, 'firstStartUp')
145+
void focusAmazonQPanel.execute(placeholder, ExtStartUpSources.firstStartUp)
146146
}, 1000)
147147
}
148148
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ export const createMynahUI = (
609609
mynahUI.addChatItem(tabID, {
610610
type: ChatItemType.ANSWER_STREAM,
611611
})
612-
} else if (tabType === 'gumby' || tabType === 'testgen') {
612+
} else if (tabType === 'gumby') {
613613
connector.requestAnswer(tabID, {
614614
chatMessage: prompt.prompt ?? '',
615615
})

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

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ import {
6363
} from '../../../codewhisperer/models/constants'
6464
import { UserWrittenCodeTracker } from '../../../codewhisperer/tracker/userWrittenCodeTracker'
6565
import { ReferenceLogViewProvider } from '../../../codewhisperer/service/referenceLogViewProvider'
66-
import { Auth } from '../../../auth/auth'
6766

6867
export interface TestChatControllerEventEmitters {
6968
readonly tabOpened: vscode.EventEmitter<any>
@@ -801,10 +800,8 @@ export class TestController {
801800
session.linesOfCodeGenerated
802801
)
803802

804-
if (!Auth.instance.isInternalAmazonUser()) {
805-
await this.endSession(message, FollowUpTypes.SkipBuildAndFinish)
806-
return
807-
}
803+
await this.endSession(message, FollowUpTypes.SkipBuildAndFinish)
804+
return
808805

809806
if (session.listOfTestGenerationJobId.length === 1) {
810807
this.startInitialBuild(message)
@@ -944,17 +941,12 @@ export class TestController {
944941

945942
private startInitialBuild(data: any) {
946943
// TODO: Remove the fallback build command after stable version of backend build command.
947-
const userMessage = `Would you like me to help build and execute the test? I’ll run following commands.\n\`\`\`sh\n${this.sessionStorage.getSession().shortAnswer?.buildCommand}\n`
944+
const userMessage = `Would you like me to help build and execute the test? I will need you to let me know what build command to run if you do.`
948945
const followUps: FollowUps = {
949946
text: '',
950947
options: [
951948
{
952-
pillText: `Build and execute`,
953-
type: FollowUpTypes.BuildAndExecute,
954-
status: 'primary',
955-
},
956-
{
957-
pillText: `Modify command`,
949+
pillText: `Specify command then build and execute`,
958950
type: FollowUpTypes.ModifyCommands,
959951
status: 'primary',
960952
},
@@ -984,6 +976,7 @@ export class TestController {
984976
const listOfInstallationDependencies = ['']
985977
const installationDependencies = listOfInstallationDependencies.join('\n')
986978

979+
this.messenger.sendMessage('Build and execute', data.tabID, 'prompt')
987980
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_buildAndExecute' })
988981

989982
if (installationDependencies.length > 0) {
@@ -1032,6 +1025,11 @@ export class TestController {
10321025
// const installationDependencies = session.shortAnswer?.installationDependencies ?? []
10331026
// MOCK: ignoring the installation case until backend send response
10341027
const installationDependencies: string[] = []
1028+
const buildCommands = session.updatedBuildCommands
1029+
if (!buildCommands) {
1030+
throw new Error('Build command not found')
1031+
return
1032+
}
10351033

10361034
this.messenger.sendBuildProgressMessage({
10371035
tabID: data.tabID,
@@ -1103,7 +1101,7 @@ export class TestController {
11031101
messageId: TestNamedMessages.TEST_GENERATION_BUILD_STATUS_MESSAGE,
11041102
})
11051103

1106-
const buildStatus = await runBuildCommand(this.getBuildCommands())
1104+
const buildStatus = await runBuildCommand(buildCommands)
11071105
session.buildStatus = buildStatus
11081106

11091107
if (buildStatus === BuildStatus.FAILURE) {
@@ -1231,17 +1229,10 @@ export class TestController {
12311229
fileList: this.checkCodeDiffLengthAndBuildStatus({ codeDiffLength, buildStatus: session.buildStatus })
12321230
? {
12331231
fileTreeTitle: 'READY FOR REVIEW',
1234-
rootFolderTitle: path.basename(session.projectRootPath),
1232+
rootFolderTitle: 'tests',
12351233
filePaths: [session.generatedFilePath],
12361234
}
12371235
: undefined,
1238-
codeReference: session.references.map(
1239-
(ref: ShortAnswerReference) =>
1240-
({
1241-
...ref,
1242-
information: `${ref.licenseName} - <a href="${ref.url}">${ref.repository}</a>`,
1243-
}) as CodeReference
1244-
),
12451236
})
12461237
this.messenger.sendBuildProgressMessage({
12471238
tabID: data.tabID,
@@ -1270,7 +1261,7 @@ export class TestController {
12701261

12711262
private modifyBuildCommand(data: any) {
12721263
this.sessionStorage.getSession().conversationState = ConversationState.WAITING_FOR_BUILD_COMMMAND_INPUT
1273-
this.messenger.sendMessage('Modify Command', data.tabID, 'prompt')
1264+
this.messenger.sendMessage('Specify commands then build', data.tabID, 'prompt')
12741265
telemetry.ui_click.emit({ elementId: 'unitTestGeneration_modifyCommand' })
12751266
this.messenger.sendMessage(
12761267
'Sure, provide all command lines you’d like me to run to build.',
@@ -1383,16 +1374,21 @@ export class TestController {
13831374
}
13841375

13851376
// TODO: return build command when product approves
1386-
private getBuildCommands = (): string[] => {
1387-
const session = this.sessionStorage.getSession()
1388-
if (session.updatedBuildCommands?.length) {
1389-
return [...session.updatedBuildCommands]
1390-
}
1391-
1392-
if (session.shortAnswer && session.shortAnswer?.buildCommand) {
1393-
return [session.shortAnswer.buildCommand]
1394-
}
1395-
// TODO: Add a generic command here for external launch according to the build system.
1396-
return ['brazil-build release']
1397-
}
1377+
// private getBuildCommands = (): string[] => {
1378+
// const session = this.sessionStorage.getSession()
1379+
// if (session.updatedBuildCommands?.length) {
1380+
// return [...session.updatedBuildCommands]
1381+
// }
1382+
1383+
// // For Internal amazon users only
1384+
// if (Auth.instance.isInternalAmazonUser()) {
1385+
// return ['brazil-build release']
1386+
// }
1387+
1388+
// if (session.shortAnswer && Array.isArray(session.shortAnswer?.buildCommands)) {
1389+
// return [...session.shortAnswer.buildCommands]
1390+
// }
1391+
1392+
// return ['source qdev-wbr/.venv/bin/activate && pytest --continue-on-collection-errors']
1393+
// }
13981394
}

packages/core/src/auth/utils.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import { EcsCredentialsProvider } from './providers/ecsCredentialsProvider'
5858
import { EnvVarsCredentialsProvider } from './providers/envVarsCredentialsProvider'
5959
import { showMessageWithUrl } from '../shared/utilities/messages'
6060
import { credentialHelpUrl } from '../shared/constants'
61-
import { ExtStartUpSources, ExtStartUpSource } from '../shared/telemetry/util'
61+
import { ExtStartUpSources, ExtStartUpSource, hadClientIdOnStartup } from '../shared/telemetry/util'
6262

6363
// iam-only excludes Builder ID and IAM Identity Center from the list of valid connections
6464
// TODO: Understand if "iam" should include these from the list at all
@@ -688,17 +688,43 @@ export class ExtensionUse {
688688
return this.isFirstUseCurrentSession
689689
}
690690

691-
this.isFirstUseCurrentSession = globals.globalState.get('isExtensionFirstUse')
692-
if (this.isFirstUseCurrentSession === undefined) {
691+
// This is for sure not their first use
692+
const isFirstUse = globals.globalState.tryGet('isExtensionFirstUse', Boolean)
693+
if (isFirstUse === false) {
694+
this.isFirstUseCurrentSession = isFirstUse
695+
return this.isFirstUseCurrentSession
696+
}
697+
698+
/**
699+
* SANITY CHECK: If the clientId already existed on startup, then isFirstUse MUST be false. So
700+
* there is a bug in the state.
701+
*/
702+
if (hadClientIdOnStartup(globals.globalState)) {
703+
telemetry.function_call.emit({
704+
result: 'Failed',
705+
functionName: 'isFirstUse',
706+
reason: 'ClientIdAlreadyExisted',
707+
})
708+
}
709+
710+
if (isAmazonQ()) {
711+
this.isFirstUseCurrentSession = true
712+
if (hasExistingConnections()) {
713+
telemetry.function_call.emit({
714+
result: 'Failed',
715+
functionName: 'isFirstUse',
716+
reason: 'UnexpectedConnections',
717+
})
718+
}
719+
} else {
693720
// The variable in the store is not defined yet, fallback to checking if they have existing connections.
694721
this.isFirstUseCurrentSession = !hasExistingConnections()
695-
696-
getLogger().debug(
697-
`isFirstUse: State not found, marking user as '${
698-
this.isFirstUseCurrentSession ? '' : 'NOT '
699-
}first use' since they 'did ${this.isFirstUseCurrentSession ? 'NOT ' : ''}have existing connections'.`
700-
)
701722
}
723+
getLogger().debug(
724+
`isFirstUse: State not found, marking user as '${
725+
this.isFirstUseCurrentSession ? '' : 'NOT '
726+
}first use' since they 'did ${this.isFirstUseCurrentSession ? 'NOT ' : ''}have existing connections'.`
727+
)
702728

703729
// Update state, so next time it is not first use
704730
this.updateMemento('isExtensionFirstUse', false)

packages/core/src/codewhisperer/commands/startTestGeneration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ function runLocalBuild(
212212
if (spawnResult.stderr) {
213213
spawnResult.stderr.on('data', async (data) => {
214214
const output = data.toString().trim()
215-
getLogger().warn(`${output}`)
215+
getLogger().warn(`BUILD ERROR: ${output}`)
216216
buildLogs += output
217217
})
218218
}

packages/core/src/codewhisperer/models/model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ export interface ShortAnswerReference {
11771177

11781178
export interface ShortAnswer {
11791179
testFilePath: string
1180-
buildCommand: string
1180+
buildCommands: string[]
11811181
planSummary: string
11821182
sourceFilePath?: string
11831183
testFramework?: string

packages/core/src/login/webview/commonAuthViewProvider.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { AuthSources } from './util'
4646
import { AuthFlowStates } from './vue/types'
4747
import { getTelemetryMetadataForConn } from '../../auth/connection'
4848
import { AuthUtil } from '../../codewhisperer/util/authUtil'
49+
import { ExtensionUse } from '../../auth/utils'
4950

5051
export class CommonAuthViewProvider implements WebviewViewProvider {
5152
public readonly viewType: string
@@ -83,14 +84,22 @@ export class CommonAuthViewProvider implements WebviewViewProvider {
8384
) {
8485
// Our callback won't fire on the first view.
8586
if (webviewView.visible) {
86-
telemetry.auth_signInPageOpened.emit({ result: 'Succeeded', passive: true })
87+
telemetry.auth_signInPageOpened.emit({
88+
result: 'Succeeded',
89+
passive: true,
90+
source: ExtensionUse.instance.sourceForTelemetry(),
91+
})
8792
}
8893

8994
// This will fire whenever the user opens or closes the login page from 'somewhere else'
9095
// i.e. NOT when switching from/to the chat window, which uses the same view area.
9196
webviewView.onDidChangeVisibility(async () => {
9297
if (webviewView.visible) {
93-
telemetry.auth_signInPageOpened.emit({ result: 'Succeeded', passive: true })
98+
telemetry.auth_signInPageOpened.emit({
99+
result: 'Succeeded',
100+
passive: true,
101+
source: ExtensionUse.instance.sourceForTelemetry(),
102+
})
94103
} else {
95104
telemetry.auth_signInPageClosed.emit({ result: 'Succeeded', passive: true })
96105

packages/core/src/login/webview/vue/backend.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,22 @@ export abstract class CommonAuthWebview extends VueWebview {
6161
return globals.regionProvider.getRegions().reverse()
6262
}
6363

64+
private didCall: { login: boolean; reauth: boolean } = { login: false, reauth: false }
65+
public setUiReady(state: 'login' | 'reauth') {
66+
// Prevent telemetry spam, since showing/hiding chat triggers this each time.
67+
// So only emit once.
68+
if (this.didCall[state]) {
69+
return
70+
}
71+
72+
telemetry.webview_load.emit({
73+
passive: true,
74+
webviewName: state,
75+
result: 'Succeeded',
76+
})
77+
this.didCall[state] = true
78+
}
79+
6480
/**
6581
* This wraps the execution of the given setupFunc() and handles common errors from the SSO setup process.
6682
*

packages/core/src/login/webview/vue/login.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ export default defineComponent({
368368
// Pre-select the first available login option
369369
await this.preselectLoginOption()
370370
await this.handleUrlInput() // validate the default startUrl
371+
372+
await client.setUiReady('login')
371373
},
372374
methods: {
373375
toggleItemSelection(itemId: number) {

packages/core/src/login/webview/vue/reauthenticate.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ export default defineComponent({
127127
128128
this.doShow = true
129129
},
130+
async mounted() {
131+
await client.setUiReady('reauth')
132+
},
130133
methods: {
131134
async reauthenticate() {
132135
client.emitUiClick('auth_reauthenticate')

0 commit comments

Comments
 (0)