Skip to content

Commit 3b0f88d

Browse files
authored
feat(amazonq inline suggest): customization A/B aws#5099
Use the customization Arn value if and only if: - user is an IdC user - arn is in the list of available ones JB PR: aws/aws-toolkit-jetbrains#4543
1 parent 03da93a commit 3b0f88d

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

packages/core/src/codewhisperer/service/featureConfigProvider.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,27 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import { FeatureValue } from '../client/codewhispereruserclient'
6+
import { Customization, FeatureValue } from '../client/codewhispereruserclient'
77
import { codeWhispererClient as client } from '../client/codewhisperer'
88
import { AuthUtil } from '../util/authUtil'
99
import { getLogger } from '../../shared/logger'
10+
import { isBuilderIdConnection, isIdcSsoConnection } from '../../auth/connection'
1011

1112
export class FeatureContext {
1213
constructor(public name: string, public variation: string, public value: FeatureValue) {}
1314
}
1415

1516
const testFeatureName = 'testFeature'
17+
const customizationArnOverrideName = 'customizationArnOverride'
1618
const featureConfigPollIntervalInMs = 30 * 60 * 1000 // 30 mins
1719

1820
// TODO: add real feature later
1921
export const featureDefinitions = new Map([
2022
[testFeatureName, new FeatureContext(testFeatureName, 'CONTROL', { stringValue: 'testValue' })],
23+
[
24+
customizationArnOverrideName,
25+
new FeatureContext(customizationArnOverrideName, 'customizationARN', { stringValue: '' }),
26+
],
2127
])
2228

2329
export class FeatureConfigProvider {
@@ -53,6 +59,39 @@ export class FeatureConfigProvider {
5359
new FeatureContext(evaluation.feature, evaluation.variation, evaluation.value)
5460
)
5561
})
62+
63+
const customizationArnOverride = this.featureConfigs.get(customizationArnOverrideName)?.value?.stringValue
64+
if (customizationArnOverride !== undefined) {
65+
// Double check if server-side wrongly returns a customizationArn to BID users
66+
if (isBuilderIdConnection(AuthUtil.instance.conn)) {
67+
this.featureConfigs.delete(customizationArnOverrideName)
68+
} else if (isIdcSsoConnection(AuthUtil.instance.conn)) {
69+
let availableCustomizations = undefined
70+
try {
71+
const items: Customization[] = []
72+
const response = await client.listAvailableCustomizations()
73+
response
74+
.map(
75+
listAvailableCustomizationsResponse =>
76+
listAvailableCustomizationsResponse.customizations
77+
)
78+
.forEach(customizations => {
79+
items.push(...customizations)
80+
})
81+
availableCustomizations = items.map(c => c.arn)
82+
} catch (e) {
83+
getLogger().debug('amazonq: Failed to list available customizations')
84+
}
85+
86+
// If customizationArn from A/B is not available in listAvailableCustomizations response, don't use this value
87+
if (!availableCustomizations?.includes(customizationArnOverride)) {
88+
getLogger().debug(
89+
`Customization arn ${customizationArnOverride} not available in listAvailableCustomizations, not using`
90+
)
91+
this.featureConfigs.delete(customizationArnOverrideName)
92+
}
93+
}
94+
}
5695
} catch (e) {
5796
getLogger().error(`CodeWhisperer: Error when fetching feature configs ${e}`, e)
5897
}
@@ -82,6 +121,10 @@ export class FeatureConfigProvider {
82121
return this.getFeatureValueForKey(testFeatureName).stringValue
83122
}
84123

124+
getCustomizationArnOverride(): string | undefined {
125+
return this.getFeatureValueForKey(customizationArnOverrideName).stringValue
126+
}
127+
85128
// Get the feature value for the given key.
86129
// In case of a misconfiguration, it will return a default feature value of Boolean true.
87130
private getFeatureValueForKey(name: string): FeatureValue {

packages/core/src/codewhisperer/util/customizationUtil.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { showMessageWithUrl } from '../../shared/utilities/messages'
2525
import { parse } from '@aws-sdk/util-arn-parser'
2626
import { Commands } from '../../shared/vscode/commands2'
2727
import { vsCodeState } from '../models/model'
28+
import { FeatureConfigProvider } from '../service/featureConfigProvider'
2829

2930
/**
3031
*
@@ -108,7 +109,21 @@ export const getSelectedCustomization = (): Customization => {
108109

109110
const selectedCustomizationArr =
110111
globals.context.globalState.get<{ [label: string]: Customization }>(selectedCustomizationKey) || {}
111-
return selectedCustomizationArr[AuthUtil.instance.conn.label] || baseCustomization
112+
const result = selectedCustomizationArr[AuthUtil.instance.conn.label] || baseCustomization
113+
114+
// A/B case
115+
const arnOverride = FeatureConfigProvider.instance.getCustomizationArnOverride()
116+
if (arnOverride === undefined || arnOverride === '') {
117+
return result
118+
} else {
119+
// A trick to prioritize arn from A/B over user's currently selected(for request and telemetry)
120+
// but still shows customization info of user's currently selected.
121+
return {
122+
arn: arnOverride,
123+
name: result.name,
124+
description: result.description,
125+
}
126+
}
112127
}
113128

114129
export const setSelectedCustomization = async (customization: Customization) => {

0 commit comments

Comments
 (0)