Skip to content

Commit bd617be

Browse files
Merge branch 'main' into thumb-up-and-down
2 parents f1bb12c + b440147 commit bd617be

File tree

25 files changed

+388
-103
lines changed

25 files changed

+388
-103
lines changed

.github/workflows/prerelease.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
generate_artifact_toolkit_standalone:
1818
strategy:
1919
matrix:
20-
supported_versions: [ '2024.1', '2024.2', '2024.3' ]
20+
supported_versions: [ '2024.1', '2024.2', '2024.3', '2025.1' ]
2121
runs-on: ubuntu-latest
2222
steps:
2323
- uses: actions/checkout@v4

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/CodeTestChatApp.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class CodeTestChatApp(private val scope: CoroutineScope) : AmazonQApp {
4141
"button-click" to IncomingCodeTestMessage.ButtonClicked::class,
4242
"chat-item-voted" to IncomingCodeTestMessage.ChatItemVoted::class,
4343
"chat-item-feedback" to IncomingCodeTestMessage.ChatItemFeedback::class,
44+
"auth-follow-up-was-clicked" to IncomingCodeTestMessage.AuthFollowUpWasClicked::class
4445
)
4546

4647
scope.launch {
@@ -83,6 +84,7 @@ class CodeTestChatApp(private val scope: CoroutineScope) : AmazonQApp {
8384
is IncomingCodeTestMessage.ButtonClicked -> inboundAppMessagesHandler.processButtonClickedMessage(message)
8485
is IncomingCodeTestMessage.ChatItemVoted -> inboundAppMessagesHandler.processChatItemVoted(message)
8586
is IncomingCodeTestMessage.ChatItemFeedback -> inboundAppMessagesHandler.processChatItemFeedBack(message)
87+
is IncomingCodeTestMessage.AuthFollowUpWasClicked -> inboundAppMessagesHandler.processAuthFollowUpClick(message)
8688
}
8789
}
8890

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/InboundAppMessagesHandler.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ interface InboundAppMessagesHandler {
2525
suspend fun processChatItemVoted(message: IncomingCodeTestMessage.ChatItemVoted)
2626

2727
suspend fun processChatItemFeedBack(message: IncomingCodeTestMessage.ChatItemFeedback)
28+
29+
suspend fun processAuthFollowUpClick(message: IncomingCodeTestMessage.AuthFollowUpWasClicked)
30+
2831
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatController.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,14 @@ class CodeTestChatController(
10131013
}
10141014
}
10151015

1016+
override suspend fun processAuthFollowUpClick(message: IncomingCodeTestMessage.AuthFollowUpWasClicked) {
1017+
codeTestChatHelper.sendUpdatePromptProgress(message.tabId, null)
1018+
authController.handleAuth(context.project, message.authType)
1019+
codeTestChatHelper.sendAuthenticationInProgressMessage(message.tabId) // show user that authentication is in progress
1020+
codeTestChatHelper.sendChatInputEnabledMessage(false) // disable the input field while authentication is in progress
1021+
sessionCleanUp(codeTestChatHelper.getActiveSession().tabId)
1022+
}
1023+
10161024
private suspend fun updateBuildAndExecuteProgressCard(
10171025
currentStatus: BuildAndExecuteProgressStatus,
10181026
messageId: String?,
@@ -1269,6 +1277,17 @@ class CodeTestChatController(
12691277
* */
12701278
private suspend fun handleChat(tabId: String, message: String) {
12711279
val session = codeTestChatHelper.getActiveSession()
1280+
session.projectRoot
1281+
val credentialState = authController.getAuthNeededStates(context.project).amazonQ
1282+
if (credentialState != null) {
1283+
messenger.sendAuthNeededException(
1284+
tabId = tabId,
1285+
triggerId = UUID.randomUUID().toString(),
1286+
credentialState = credentialState,
1287+
)
1288+
session.isAuthenticating = true
1289+
return
1290+
}
12721291
LOG.debug {
12731292
"$FEATURE_NAME: " +
12741293
"Processing message: $message " +

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/controller/CodeTestChatHelper.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package software.aws.toolkits.jetbrains.services.amazonqCodeTest.controller
55

66
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher
7+
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.ChatInputEnabledMessage
78
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestAddAnswerMessage
89
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestChatMessage
910
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.CodeTestChatMessageContent
@@ -15,6 +16,8 @@ import software.aws.toolkits.jetbrains.services.amazonqCodeTest.messages.UpdateP
1516
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.session.Session
1617
import software.aws.toolkits.jetbrains.services.amazonqCodeTest.storage.ChatSessionStorage
1718
import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType
19+
import software.aws.toolkits.jetbrains.services.cwc.messages.FollowUp
20+
import software.aws.toolkits.resources.message
1821
import java.util.UUID
1922

2023
class CodeTestChatHelper(
@@ -153,4 +156,27 @@ class CodeTestChatHelper(
153156
)
154157
)
155158
}
159+
160+
suspend fun sendChatInputEnabledMessage(isEnabled: Boolean) {
161+
if (isInvalidSession()) return
162+
messagePublisher.publish(ChatInputEnabledMessage(activeCodeTestTabId as String, enabled = isEnabled))
163+
}
164+
165+
suspend fun sendAuthenticationInProgressMessage(
166+
tabId: String,
167+
messageId: String? = null,
168+
followUp: List<FollowUp>? = null,
169+
canBeVoted: Boolean? = false,
170+
) {
171+
val chatMessage =
172+
CodeTestChatMessage(
173+
tabId = tabId,
174+
messageId = messageId ?: UUID.randomUUID().toString(),
175+
messageType = ChatMessageType.Answer,
176+
message = message("amazonqFeatureDev.follow_instructions_for_authentication"),
177+
followUps = followUp,
178+
canBeVoted = canBeVoted ?: false,
179+
)
180+
messagePublisher.publish(chatMessage)
181+
}
156182
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqCodeTest/messages/CodeTestMessage.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ sealed interface IncomingCodeTestMessage : CodeTestBaseMessage {
104104
@JsonProperty("tabID") val tabId: String,
105105
val selectedOption: String,
106106
val comment: String?,
107+
108+
data class AuthFollowUpWasClicked(
109+
@JsonProperty("tabID") val tabId: String,
110+
val authType: AuthFollowUpType,
111+
107112
) : IncomingCodeTestMessage
108113
}
109114

plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ interface CodeWhispererModelConfigurator {
1818

1919
fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?)
2020

21+
fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?, isOverride: Boolean)
22+
2123
/**
2224
* This method is only used for invalidate a stale customization which was previously active but was removed, it will remove all usage of this customization
2325
* but not limited to the specific connection.

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/codetest/sessionconfig/CodeTestSessionConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codetest.noFileOpe
2929
import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
3030
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage
3131
import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage
32+
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
3233
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.CODE_SCAN_CREATE_PAYLOAD_TIMEOUT_IN_SECONDS
3334
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_CODE_SCAN_TIMEOUT_IN_SECONDS
3435
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.DEFAULT_PAYLOAD_LIMIT_IN_BYTES
@@ -217,7 +218,7 @@ class CodeTestSessionConfig(
217218
for (module in project.modules) {
218219
val changeListManager = ChangeListManager.getInstance(module.project)
219220
module.guessModuleDir()?.let { moduleDir ->
220-
val gitIgnoreFilteringUtil = GitIgnoreFilteringUtil(moduleDir)
221+
val gitIgnoreFilteringUtil = GitIgnoreFilteringUtil(moduleDir, CodeWhispererConstants.FeatureName.TEST_GENERATION)
221222
stack.push(moduleDir)
222223
while (stack.isNotEmpty()) {
223224
val current = stack.pop()

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ class DefaultCodeWhispererModelConfigurator : CodeWhispererModelConfigurator, Pe
7676

7777
private val hasShownNewCustomizationNotification = AtomicBoolean(false)
7878

79+
private var serviceDefaultArn: String? = null
80+
7981
override fun showConfigDialog(project: Project) {
8082
runInEdt {
8183
calculateIfIamIdentityCenterConnection(project) {
@@ -165,20 +167,23 @@ class DefaultCodeWhispererModelConfigurator : CodeWhispererModelConfigurator, Pe
165167
override fun activeCustomization(project: Project): CodeWhispererCustomization? {
166168
val selectedCustomization = calculateIfIamIdentityCenterConnection(project) { connectionIdToActiveCustomizationArn[it.id] }
167169

168-
if (selectedCustomization != null) {
169-
return selectedCustomization
170-
} else {
171-
val customizationOverride = CodeWhispererFeatureConfigService.getInstance().getCustomizationFeature()
172-
if (customizationOverride == null || customizationOverride.value.stringValue().isEmpty()) return null
173-
return CodeWhispererCustomization(
174-
arn = customizationOverride.value.stringValue(),
175-
name = customizationOverride.variation,
176-
)
177-
}
170+
return selectedCustomization
178171
}
179172

180173
override fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?) {
174+
switchCustomization(project, newCustomization, false)
175+
}
176+
177+
/**
178+
* Override happens when ALL following conditions are met
179+
* 1. service returns non-empty override customization arn, refer to [CodeWhispererFeatureConfigService]
180+
* 2. the override customization arn is different from the previous override customization if any. The purpose is to only do override once on users' behalf.
181+
*/
182+
override fun switchCustomization(project: Project, newCustomization: CodeWhispererCustomization?, isOverride: Boolean) {
181183
calculateIfIamIdentityCenterConnection(project) {
184+
if (isOverride && (newCustomization == null || newCustomization.arn.isEmpty() || serviceDefaultArn == newCustomization.arn)) {
185+
return@calculateIfIamIdentityCenterConnection
186+
}
182187
val oldCus = connectionIdToActiveCustomizationArn[it.id]
183188
if (oldCus != newCustomization) {
184189
newCustomization?.let { newCus ->
@@ -191,6 +196,9 @@ class DefaultCodeWhispererModelConfigurator : CodeWhispererModelConfigurator, Pe
191196

192197
CodeWhispererCustomizationListener.notifyCustomUiUpdate()
193198
}
199+
if (isOverride) {
200+
serviceDefaultArn = newCustomization?.arn
201+
}
194202
}
195203
}
196204

@@ -240,6 +248,7 @@ class DefaultCodeWhispererModelConfigurator : CodeWhispererModelConfigurator, Pe
240248
val state = CodeWhispererCustomizationState()
241249
state.connectionIdToActiveCustomizationArn.putAll(this.connectionIdToActiveCustomizationArn)
242250
state.previousAvailableCustomizations.putAll(this.connectionToCustomizationsShownLastTime)
251+
state.serviceDefaultArn = this.serviceDefaultArn
243252

244253
return state
245254
}
@@ -250,6 +259,8 @@ class DefaultCodeWhispererModelConfigurator : CodeWhispererModelConfigurator, Pe
250259

251260
connectionToCustomizationsShownLastTime.clear()
252261
connectionToCustomizationsShownLastTime.putAll(state.previousAvailableCustomizations)
262+
263+
this.serviceDefaultArn = state.serviceDefaultArn
253264
}
254265

255266
override fun dispose() {}
@@ -280,6 +291,9 @@ class CodeWhispererCustomizationState : BaseState() {
280291
@get:Property
281292
@get:MapAnnotation
282293
val previousAvailableCustomizations by map<String, MutableList<String>>()
294+
295+
@get:Property
296+
var serviceDefaultArn by string()
283297
}
284298

285299
data class CustomizationUiItem(

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupActivity.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import software.aws.toolkits.jetbrains.core.coroutines.projectCoroutineScope
1313
import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService
1414
import software.aws.toolkits.jetbrains.services.amazonq.calculateIfIamIdentityCenterConnection
1515
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanManager
16+
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization
1617
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator
1718
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager
1819
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isUserBuilderId
@@ -78,6 +79,14 @@ class CodeWhispererProjectStartupActivity : StartupActivity.DumbAware {
7879
projectCoroutineScope(project).launch {
7980
while (isActive) {
8081
CodeWhispererFeatureConfigService.getInstance().fetchFeatureConfigs(project)
82+
CodeWhispererFeatureConfigService.getInstance().getCustomizationFeature()?.let { customization ->
83+
CodeWhispererModelConfigurator.getInstance().switchCustomization(
84+
project,
85+
CodeWhispererCustomization(arn = customization.value.stringValue(), name = customization.variation),
86+
isOverride = true
87+
)
88+
}
89+
8190
delay(FEATURE_CONFIG_POLL_INTERVAL_IN_MS)
8291
}
8392
}

0 commit comments

Comments
 (0)