From fbe77d7d29335f6b058bdbd065db75108704ca70 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 27 Aug 2024 12:37:10 -0700 Subject: [PATCH 01/28] feat (Amazon Q): Add basic UX and logic for generating unit tests --- .../jetbrains-community/resources/META-INF/plugin-chat.xml | 7 ++++++- .../services/cwc/commands/EditorContextCommand.kt | 4 ++++ .../jetbrains/services/cwc/commands/TestCodeAction.kt | 7 +++++++ .../jetbrains/services/cwc/controller/ChatController.kt | 6 +++++- .../cwc/controller/chat/userIntent/UserIntentRecognizer.kt | 1 + .../services/codewhisperer/util/CodeWhispererConstants.kt | 2 +- .../aws/toolkits/resources/MessagesBundle.properties | 2 ++ 7 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt diff --git a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml index 7e29e78705..7710298f5b 100644 --- a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml +++ b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml @@ -7,7 +7,7 @@ + topic="com.intellij.openapi.wm.ex.ToolWindowManagerListener"/> @@ -70,6 +70,11 @@ + + + + diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt index e08aab928c..4e2103903a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt @@ -26,6 +26,10 @@ enum class EditorContextCommand( verb = "Optimize", actionId = "aws.amazonq.optimizeCode", ), + Test( + verb = "Generate unit tests for", + actionId = "aws.amazonq.testCode", + ), SendToPrompt( verb = "SendToPrompt", actionId = "aws.amazonq.sendToPrompt", diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt new file mode 100644 index 0000000000..b7696a2e42 --- /dev/null +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -0,0 +1,7 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.cwc.commands + +class TestCodeAction : CustomAction(EditorContextCommand.Test) + diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 03c2e0b8d4..8c9494096e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.ide.BrowserUtil +import com.intellij.lang.Language import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.runInEdt import com.intellij.openapi.command.WriteCommandAction @@ -20,6 +21,7 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.options.ShowSettingsUtil import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiFileFactory import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filter @@ -332,7 +334,9 @@ class ChatController private constructor( } // Create prompt - val prompt = "${message.command} the following part of my code for me: $codeSelection" + val prompt = if (EditorContextCommand.Test == message.command) + "${message.command.verb} the following part of my code for me: $codeSelection" else + "${message.command} the following part of my code for me: $codeSelection"; processPromptActions(prompt, message, triggerId, fileContext) } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index a0637b10ac..3abfcbd1ff 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -16,6 +16,7 @@ class UserIntentRecognizer { EditorContextCommand.Fix -> UserIntent.APPLY_COMMON_BEST_PRACTICES EditorContextCommand.Optimize -> UserIntent.IMPROVE_CODE EditorContextCommand.ExplainCodeScanIssue -> UserIntent.EXPLAIN_CODE_SELECTION + EditorContextCommand.Test -> null EditorContextCommand.SendToPrompt -> null } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt index 4eb9980e21..3f505feea8 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt @@ -105,7 +105,7 @@ object CodeWhispererConstants { } object Config { - const val CODEWHISPERER_ENDPOINT = "https://codewhisperer.us-east-1.amazonaws.com/" // PROD + const val CODEWHISPERER_ENDPOINT = "https://rts.gamma-us-east-1.codewhisperer.ai.aws.dev/" // GAMMA const val CODEWHISPERER_IDPOOL_ID = "us-east-1:70717e99-906f-4add-908c-bd9074a2f5b9" val Sigv4ClientRegion = Region.US_EAST_1 val BearerClientRegion = Region.US_EAST_1 diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index c79a744a57..43a6259e35 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -25,6 +25,8 @@ action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.descr action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.text = Optimize Code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.description = Refactors the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.text = Refactor Code +action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.description = Generates unit tests for the selected code +action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.text = Test Code action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.description = Sends selected code to chat action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.text = Send to Prompt action.aws.toolkit.open.arn.browser.text=Open ARN in AWS Console From a2003469a5f648b042d868d916900048b8c8b5e1 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 3 Sep 2024 18:01:56 -0700 Subject: [PATCH 02/28] Update cwspr model with GENERATE_UNIT_TESTS user intent --- .../services/cwc/clients/chat/v1/ChatSessionV1.kt | 1 + .../services/cwc/commands/TestCodeAction.kt | 13 ++++++++++++- .../services/cwc/controller/ChatController.kt | 2 -- .../controller/chat/telemetry/TelemetryHelper.kt | 1 + .../chat/userIntent/UserIntentRecognizer.kt | 3 ++- .../codewhisperer/util/CodeWhispererConstants.kt | 2 +- .../resources/telemetryOverride.json | 9 +++++++-- .../codewhispererruntime/service-2.json | 3 ++- .../codewhispererstreaming/service-2.json | 3 ++- 9 files changed, 28 insertions(+), 9 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt index 77446326f0..a5057f797c 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt @@ -297,6 +297,7 @@ class ChatSessionV1( UserIntent.EXPLAIN_LINE_BY_LINE -> FollowUpType.LineByLine UserIntent.EXPLAIN_CODE_SELECTION -> FollowUpType.ExplainInDetail UserIntent.UNKNOWN_TO_SDK_VERSION -> FollowUpType.Generated + UserIntent.GENERATE_UNIT_TESTS -> FollowUpType.Generated null -> FollowUpType.Generated } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt index b7696a2e42..cc79abdc36 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -3,5 +3,16 @@ package software.aws.toolkits.jetbrains.services.cwc.commands -class TestCodeAction : CustomAction(EditorContextCommand.Test) +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection +class TestCodeAction : CustomAction(EditorContextCommand.Test) { + override fun update(e: AnActionEvent) { + val project = e.getData(CommonDataKeys.PROJECT) ?: return + val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection + e.presentation.isVisible = (connection != null && connection.startUrl == "https://amzn.awsapps.com/start") + } +} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 8c9494096e..8c9b9b1566 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -12,7 +12,6 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.ide.BrowserUtil -import com.intellij.lang.Language import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.runInEdt import com.intellij.openapi.command.WriteCommandAction @@ -21,7 +20,6 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.options.ShowSettingsUtil import com.intellij.psi.PsiDocumentManager -import com.intellij.psi.PsiFileFactory import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.filter diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt index 5b0989fc59..ebeba08b88 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt @@ -57,6 +57,7 @@ class TelemetryHelper(private val context: AmazonQAppInitContext, private val se UserIntent.CITE_SOURCES -> CwsprChatUserIntent.CiteSources UserIntent.EXPLAIN_LINE_BY_LINE -> CwsprChatUserIntent.ExplainLineByLine UserIntent.EXPLAIN_CODE_SELECTION -> CwsprChatUserIntent.ExplainCodeSelection + UserIntent.GENERATE_UNIT_TESTS -> CwsprChatUserIntent.GenerateUnitTests UserIntent.UNKNOWN_TO_SDK_VERSION -> CwsprChatUserIntent.Unknown } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index 3abfcbd1ff..aea721ab0a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -16,7 +16,7 @@ class UserIntentRecognizer { EditorContextCommand.Fix -> UserIntent.APPLY_COMMON_BEST_PRACTICES EditorContextCommand.Optimize -> UserIntent.IMPROVE_CODE EditorContextCommand.ExplainCodeScanIssue -> UserIntent.EXPLAIN_CODE_SELECTION - EditorContextCommand.Test -> null + EditorContextCommand.Test -> UserIntent.GENERATE_UNIT_TESTS EditorContextCommand.SendToPrompt -> null } @@ -25,6 +25,7 @@ class UserIntentRecognizer { prompt.startsWith("Refactor") -> UserIntent.SUGGEST_ALTERNATE_IMPLEMENTATION prompt.startsWith("Fix") -> UserIntent.APPLY_COMMON_BEST_PRACTICES prompt.startsWith("Optimize") -> UserIntent.IMPROVE_CODE + prompt.startsWith("Generate tests") || prompt.startsWith("Generate unit tests") -> UserIntent.GENERATE_UNIT_TESTS else -> null } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt index 3f505feea8..fc9f2ee7a3 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt @@ -105,7 +105,7 @@ object CodeWhispererConstants { } object Config { - const val CODEWHISPERER_ENDPOINT = "https://rts.gamma-us-east-1.codewhisperer.ai.aws.dev/" // GAMMA + const val CODEWHISPERER_ENDPOINT = "https://rts.gamma-us-east-1.codewhisperer.ai.aws.dev/" // gamma const val CODEWHISPERER_IDPOOL_ID = "us-east-1:70717e99-906f-4add-908c-bd9074a2f5b9" val Sigv4ClientRegion = Region.US_EAST_1 val BearerClientRegion = Region.US_EAST_1 diff --git a/plugins/core/jetbrains-community/resources/telemetryOverride.json b/plugins/core/jetbrains-community/resources/telemetryOverride.json index 59ba1063c3..5bb130e2ad 100644 --- a/plugins/core/jetbrains-community/resources/telemetryOverride.json +++ b/plugins/core/jetbrains-community/resources/telemetryOverride.json @@ -59,7 +59,8 @@ "showExample", "citeSources", "explainLineByLine", - "explainCodeSelection" + "explainCodeSelection", + "generateUnitTests" ], "description": "Explict user intent associated with a chat message" }, @@ -678,6 +679,10 @@ { "type": "cwsprChatHasProjectContext", "required": false + }, + { + "type": "cwsprChatUserIntent", + "required": false } ] }, @@ -839,4 +844,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/plugins/core/sdk-codegen/codegen-resources/codewhispererruntime/service-2.json b/plugins/core/sdk-codegen/codegen-resources/codewhispererruntime/service-2.json index 219b319d55..f8f4a99f5d 100644 --- a/plugins/core/sdk-codegen/codegen-resources/codewhispererruntime/service-2.json +++ b/plugins/core/sdk-codegen/codegen-resources/codewhispererruntime/service-2.json @@ -1952,7 +1952,8 @@ "SHOW_EXAMPLES", "CITE_SOURCES", "EXPLAIN_LINE_BY_LINE", - "EXPLAIN_CODE_SELECTION" + "EXPLAIN_CODE_SELECTION", + "GENERATE_UNIT_TESTS" ] }, "UserModificationEvent":{ diff --git a/plugins/core/sdk-codegen/codegen-resources/codewhispererstreaming/service-2.json b/plugins/core/sdk-codegen/codegen-resources/codewhispererstreaming/service-2.json index 72ed91db3f..863326fcb6 100644 --- a/plugins/core/sdk-codegen/codegen-resources/codewhispererstreaming/service-2.json +++ b/plugins/core/sdk-codegen/codegen-resources/codewhispererstreaming/service-2.json @@ -741,7 +741,8 @@ "SHOW_EXAMPLES", "CITE_SOURCES", "EXPLAIN_LINE_BY_LINE", - "EXPLAIN_CODE_SELECTION" + "EXPLAIN_CODE_SELECTION", + "GENERATE_UNIT_TESTS" ] }, "ValidationException":{ From 2050c2856f9044c8ae0b4dd943ebfeebc32332a9 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 28 Aug 2024 14:49:14 -0700 Subject: [PATCH 03/28] fix (Amazon Q): Pass context specific intent and trigger type to chat (#4842) --- .../jetbrains/services/cwc/controller/ChatController.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 8c9b9b1566..912c144fe6 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -369,8 +369,8 @@ class ChatController private constructor( triggerId = triggerId, message = inputPrompt, activeFileContext = fileContext, - userIntent = intentRecognizer.getUserIntentFromContextMenuCommand(EditorContextCommand.ExplainCodeScanIssue), - TriggerType.CodeScanButton, + userIntent = intentRecognizer.getUserIntentFromContextMenuCommand(message.command), + triggerType = message.command.triggerType, projectContextQueryResult = emptyList() ) } From 665a7c49042f2d0d0770780750ce930994391e24 Mon Sep 17 00:00:00 2001 From: manodnyab <66754471+manodnyab@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:06:24 -0700 Subject: [PATCH 04/28] Added authType to loginWithBrowser metric (#4843) * Added authType to loginWithBrowser metric * Add open and close sign in metrics * detekt * addressed feedback * feedback * moved the util function --- .../chat/telemetry/TelemetryHelper.kt | 12 ++++++ .../resources/telemetryOverride.json | 12 ++++++ .../credentials/sso/SsoAccessTokenProvider.kt | 38 ++++++++++++------- .../sso/SsoLoginCallbackProvider.kt | 23 ++++++++--- .../sso/bearer/BearerTokenProvider.kt | 2 +- .../sso/bearer/ConfirmUserCodeLoginDialog.kt | 3 +- .../jetbrains/core/webview/LoginBrowser.kt | 32 ++++++++++------ .../core/webview/WebviewTelemetryUtils.kt | 16 ++++++++ 8 files changed, 106 insertions(+), 32 deletions(-) create mode 100644 plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/WebviewTelemetryUtils.kt diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt index ebeba08b88..5ae7e40acd 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt @@ -12,6 +12,9 @@ import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization @@ -29,6 +32,7 @@ import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService import software.aws.toolkits.jetbrains.utils.notifyError import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.AmazonqTelemetry +import software.aws.toolkits.telemetry.AuthTelemetry import software.aws.toolkits.telemetry.CwsprChatCommandType import software.aws.toolkits.telemetry.CwsprChatConversationType import software.aws.toolkits.telemetry.CwsprChatInteractionType @@ -387,12 +391,20 @@ class TelemetryHelper(private val context: AmazonQAppInitContext, private val se companion object { private val logger = getLogger() + fun getQConnection(): ToolkitConnection? = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(QConnection.getInstance()) + fun recordOpenChat() { AmazonqTelemetry.openChat(passive = true) + if (getQConnection() == null) { + AuthTelemetry.signInPageOpened() + } } fun recordCloseChat() { AmazonqTelemetry.closeChat(passive = true) + if (getQConnection() == null) { + AuthTelemetry.signInPageClosed() + } } fun recordTelemetryChatRunCommand(type: CwsprChatCommandType, name: String? = null, startUrl: String? = null) { diff --git a/plugins/core/jetbrains-community/resources/telemetryOverride.json b/plugins/core/jetbrains-community/resources/telemetryOverride.json index 5bb130e2ad..7ec40cfcda 100644 --- a/plugins/core/jetbrains-community/resources/telemetryOverride.json +++ b/plugins/core/jetbrains-community/resources/telemetryOverride.json @@ -309,6 +309,15 @@ "reloaded" ], "description": "Toolkit run state." + }, + { + "name": "authType", + "allowedValues": [ + "PKCE", + "DeviceCode", + "IAM" + ], + "description": "Login is with Legacy device code or newer PKCE flow" } ], "metrics": [ @@ -796,6 +805,9 @@ }, { "type": "result" + }, + { + "type": "authType" } ] }, diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt index 190e458c1e..e5df17455d 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt @@ -22,9 +22,11 @@ import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_URL import software.aws.toolkits.jetbrains.core.credentials.sso.pkce.PKCE_CLIENT_NAME import software.aws.toolkits.jetbrains.core.credentials.sso.pkce.ToolkitOAuthService +import software.aws.toolkits.jetbrains.core.webview.getAuthType import software.aws.toolkits.jetbrains.utils.assertIsNonDispatchThread import software.aws.toolkits.jetbrains.utils.sleepWithCancellation import software.aws.toolkits.resources.AwsCoreBundle +import software.aws.toolkits.telemetry.AuthType import software.aws.toolkits.telemetry.AwsTelemetry import software.aws.toolkits.telemetry.CredentialSourceId import software.aws.toolkits.telemetry.Result @@ -159,8 +161,7 @@ class SsoAccessTokenProvider( return it } - val isCommercialRegion = !ssoRegion.startsWith("us-gov") && !ssoRegion.startsWith("us-iso") && !ssoRegion.startsWith("cn") - val token = if (isCommercialRegion && isNewAuthPkce) { + val token = if (getAuthType(ssoRegion) == AuthType.PKCE) { pollForPkceToken() } else { pollForDAGToken() @@ -336,11 +337,12 @@ class SsoAccessTokenProvider( } } - private fun sendFailedRefreshCredentialsMetricIfNeeded( + private fun sendRefreshCredentialsMetric( currentToken: AccessToken, - reason: String, - reasonDesc: String, - requestId: String? = null + reason: String?, + reasonDesc: String?, + requestId: String? = null, + result: Result ) { val tokenCreationTime = currentToken.createdAt val sessionDuration = Duration.between(Instant.now(clock), tokenCreationTime) @@ -349,7 +351,7 @@ class SsoAccessTokenProvider( if (tokenCreationTime != Instant.EPOCH) { AwsTelemetry.refreshCredentials( project = null, - result = Result.Failed, + result = result, sessionDuration = sessionDuration.toHours().toInt(), credentialSourceId = credentialSourceId, reason = reason, @@ -362,10 +364,11 @@ class SsoAccessTokenProvider( fun refreshToken(currentToken: AccessToken): AccessToken { if (currentToken.refreshToken == null) { val message = "Requested token refresh, but refresh token was null" - sendFailedRefreshCredentialsMetricIfNeeded( + sendRefreshCredentialsMetric( currentToken, reason = "Null refresh token", - reasonDesc = message + reasonDesc = message, + result = Result.Failed ) throw InvalidRequestException.builder().message(message).build() } @@ -376,10 +379,11 @@ class SsoAccessTokenProvider( } if (registration == null) { val message = "Unable to load client registration" - sendFailedRefreshCredentialsMetricIfNeeded( + sendRefreshCredentialsMetric( currentToken, reason = "Null client registration", - reasonDesc = message + reasonDesc = message, + result = Result.Failed ) throw InvalidClientException.builder().message(message).build() } @@ -399,6 +403,13 @@ class SsoAccessTokenProvider( saveAccessToken(token) + sendRefreshCredentialsMetric( + currentToken, + result = Result.Succeeded, + reason = null, + reasonDesc = null + ) + return token } catch (e: Exception) { val requestId = when (e) { @@ -409,11 +420,12 @@ class SsoAccessTokenProvider( is AwsServiceException -> e.awsErrorDetails()?.errorMessage() ?: "Unknown error" else -> e.message ?: "Unknown error" } - sendFailedRefreshCredentialsMetricIfNeeded( + sendRefreshCredentialsMetric( currentToken, reason = "Refresh access token request failed", reasonDesc = message, - requestId = requestId + requestId = requestId, + result = Result.Failed ) throw e } diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt index c8de9e0586..1a568bc32a 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoLoginCallbackProvider.kt @@ -11,6 +11,7 @@ import software.aws.toolkits.jetbrains.core.credentials.sso.bearer.ConfirmUserCo import software.aws.toolkits.jetbrains.utils.computeOnEdt import software.aws.toolkits.jetbrains.utils.notifyError import software.aws.toolkits.resources.AwsCoreBundle +import software.aws.toolkits.telemetry.AuthType import software.aws.toolkits.telemetry.AwsTelemetry import software.aws.toolkits.telemetry.CredentialType import software.aws.toolkits.telemetry.Result @@ -38,12 +39,12 @@ class DefaultSsoLoginCallbackProvider : SsoLoginCallbackProvider { interface SsoPrompt : SsoLoginCallback { override fun tokenRetrieved() { - AwsTelemetry.loginWithBrowser(project = null, result = Result.Succeeded, credentialType = CredentialType.SsoProfile) + AwsTelemetry.loginWithBrowser(project = null, result = Result.Succeeded, credentialType = CredentialType.SsoProfile, authType = AuthType.DeviceCode) } override fun tokenRetrievalFailure(e: Exception) { e.notifyError(AwsCoreBundle.message("credentials.sso.login.failed")) - AwsTelemetry.loginWithBrowser(project = null, result = Result.Failed, credentialType = CredentialType.SsoProfile) + AwsTelemetry.loginWithBrowser(project = null, result = Result.Failed, credentialType = CredentialType.SsoProfile, authType = AuthType.DeviceCode) } } @@ -59,7 +60,12 @@ object DefaultSsoPrompt : SsoPrompt { if (result) { BrowserUtil.browse(authorization.verificationUriComplete) } else { - AwsTelemetry.loginWithBrowser(project = null, result = Result.Cancelled, credentialType = CredentialType.SsoProfile) + AwsTelemetry.loginWithBrowser( + project = null, + result = Result.Cancelled, + credentialType = CredentialType.SsoProfile, + authType = AuthType.DeviceCode + ) throw ProcessCanceledException(IllegalStateException(AwsCoreBundle.message("credentials.sso.login.cancelled"))) } } @@ -76,11 +82,11 @@ object SsoPromptWithBrowserSupport : SsoPrompt { interface BearerTokenPrompt : SsoLoginCallback { override fun tokenRetrieved() { - AwsTelemetry.loginWithBrowser(project = null, result = Result.Succeeded, credentialType = CredentialType.BearerToken) + AwsTelemetry.loginWithBrowser(project = null, result = Result.Succeeded, credentialType = CredentialType.BearerToken, authType = AuthType.DeviceCode) } override fun tokenRetrievalFailure(e: Exception) { - AwsTelemetry.loginWithBrowser(project = null, result = Result.Failed, credentialType = CredentialType.BearerToken) + AwsTelemetry.loginWithBrowser(project = null, result = Result.Failed, credentialType = CredentialType.BearerToken, authType = AuthType.DeviceCode) } } @@ -96,7 +102,12 @@ object DefaultBearerTokenPrompt : BearerTokenPrompt { if (codeCopied) { BrowserUtil.browse(authorization.verificationUriComplete) } else { - AwsTelemetry.loginWithBrowser(project = null, result = Result.Cancelled, credentialType = CredentialType.BearerToken) + AwsTelemetry.loginWithBrowser( + project = null, + result = Result.Cancelled, + credentialType = CredentialType.BearerToken, + authType = AuthType.DeviceCode + ) } } } diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/BearerTokenProvider.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/BearerTokenProvider.kt index 07e60ad0c1..32261065c8 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/BearerTokenProvider.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/BearerTokenProvider.kt @@ -88,7 +88,7 @@ interface BearerTokenProvider : SdkTokenProvider, SdkAutoCloseable, ToolkitBeare class InteractiveBearerTokenProvider( val startUrl: String, - region: String, + val region: String, val scopes: List, id: String, cache: DiskCache = diskCache diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt index 5c92d0c274..369bcf52e2 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/bearer/ConfirmUserCodeLoginDialog.kt @@ -19,6 +19,7 @@ import com.intellij.util.ui.JBFont import com.intellij.util.ui.components.BorderLayoutPanel import software.aws.toolkits.core.utils.tryOrNull import software.aws.toolkits.resources.AwsCoreBundle +import software.aws.toolkits.telemetry.AuthType import software.aws.toolkits.telemetry.AwsTelemetry import software.aws.toolkits.telemetry.CredentialType import software.aws.toolkits.telemetry.Result @@ -66,7 +67,7 @@ class ConfirmUserCodeLoginDialog( override fun doCancelAction() { super.doCancelAction() - AwsTelemetry.loginWithBrowser(project = null, result = Result.Cancelled, credentialType = credentialType) + AwsTelemetry.loginWithBrowser(project = null, result = Result.Cancelled, credentialType = credentialType, authType = AuthType.DeviceCode) } } diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/LoginBrowser.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/LoginBrowser.kt index 3184d2c073..53507380d0 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/LoginBrowser.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/LoginBrowser.kt @@ -43,6 +43,7 @@ import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread import software.aws.toolkits.jetbrains.utils.pollFor import software.aws.toolkits.resources.AwsCoreBundle import software.aws.toolkits.telemetry.AuthTelemetry +import software.aws.toolkits.telemetry.AuthType import software.aws.toolkits.telemetry.AwsTelemetry import software.aws.toolkits.telemetry.CredentialSourceId import software.aws.toolkits.telemetry.CredentialType @@ -85,22 +86,23 @@ abstract class LoginBrowser( private var browserOpenTimer: Timer? = null - private fun startBrowserOpenTimer(credentialSourceId: CredentialSourceId) { + private fun startBrowserOpenTimer(startUrl: String, ssoRegion: String) { browserOpenTimer = Timer() browserOpenTimer?.schedule( object : TimerTask() { override fun run() { AwsTelemetry.loginWithBrowser( project = null, - credentialStartUrl = SONO_URL, + credentialStartUrl = startUrl, result = Result.Failed, reason = "Browser authentication idle for more than 15min", - credentialSourceId = credentialSourceId + credentialSourceId = if (startUrl == SONO_URL) CredentialSourceId.AwsId else CredentialSourceId.IamIdentityCenter, + authType = getAuthType(ssoRegion) ) AuthTelemetry.addConnection( result = Result.Failed, reason = "Browser authentication idle for more than 15min", - credentialSourceId = credentialSourceId + credentialSourceId = if (startUrl == SONO_URL) CredentialSourceId.AwsId else CredentialSourceId.IamIdentityCenter ) stopAndClearBrowserOpenTimer() } @@ -118,7 +120,7 @@ abstract class LoginBrowser( } protected val onPendingToken: (InteractiveBearerTokenProvider) -> Unit = { provider -> - startBrowserOpenTimer(if (provider.startUrl == SONO_URL) CredentialSourceId.AwsId else CredentialSourceId.IamIdentityCenter) + startBrowserOpenTimer(provider.startUrl, provider.region) projectCoroutineScope(project).launch { val authorization = pollForAuthorization(provider) if (authorization != null) { @@ -186,7 +188,8 @@ abstract class LoginBrowser( result = Result.Failed, reason = e.message, credentialSourceId = CredentialSourceId.AwsId, - isReAuth = isReauth + isReAuth = isReauth, + authType = getAuthType() ) AuthTelemetry.addConnection( result = Result.Failed, @@ -202,7 +205,8 @@ abstract class LoginBrowser( credentialStartUrl = SONO_URL, result = Result.Succeeded, credentialSourceId = CredentialSourceId.AwsId, - isReAuth = isReauth + isReAuth = isReauth, + authType = getAuthType() ) AuthTelemetry.addConnection( result = Result.Succeeded, @@ -256,7 +260,8 @@ abstract class LoginBrowser( isReAuth = isReAuth, result = result, reason = message, - credentialSourceId = CredentialSourceId.IamIdentityCenter + credentialSourceId = CredentialSourceId.IamIdentityCenter, + authType = getAuthType(region.name) ) AuthTelemetry.addConnection( result = result, @@ -273,7 +278,8 @@ abstract class LoginBrowser( isReAuth = isReAuth, credentialType = CredentialType.BearerToken, credentialStartUrl = url, - credentialSourceId = CredentialSourceId.IamIdentityCenter + credentialSourceId = CredentialSourceId.IamIdentityCenter, + authType = getAuthType(region.name) ) AuthTelemetry.addConnection( project = null, @@ -296,7 +302,8 @@ abstract class LoginBrowser( project = null, result = Result.Failed, reason = error.message, - credentialType = CredentialType.StaticProfile + credentialType = CredentialType.StaticProfile, + authType = AuthType.IAM ) LOG.error(error) { "Profile file error" } Messages.showErrorDialog(jcefBrowser.component, error.message, AwsCoreBundle.message("gettingstarted.auth.failed")) @@ -306,6 +313,7 @@ abstract class LoginBrowser( project = null, result = Result.Failed, reason = "Profile already exists", + authType = AuthType.IAM ) }, { error -> @@ -314,6 +322,7 @@ abstract class LoginBrowser( project = null, result = Result.Failed, reason = reason, + authType = AuthType.IAM ) LOG.error(error) { reason } Messages.showErrorDialog(jcefBrowser.component, error.message, AwsCoreBundle.message("gettingstarted.auth.failed")) @@ -325,7 +334,8 @@ abstract class LoginBrowser( AwsTelemetry.loginWithBrowser( project = null, result = Result.Succeeded, - credentialType = CredentialType.StaticProfile + credentialType = CredentialType.StaticProfile, + authType = AuthType.IAM ) } } diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/WebviewTelemetryUtils.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/WebviewTelemetryUtils.kt new file mode 100644 index 0000000000..628a887afe --- /dev/null +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/WebviewTelemetryUtils.kt @@ -0,0 +1,16 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.core.webview + +import com.intellij.openapi.util.registry.Registry +import software.aws.toolkits.telemetry.AuthType + +fun getAuthType(region: String = "us-east-1"): AuthType { + val isCommercialRegion = !region.startsWith("us-gov") && !region.startsWith("us-iso") && !region.startsWith("cn") + if (!Registry.`is`("aws.dev.useDAG") && isCommercialRegion) { + return AuthType.PKCE + } else { + return AuthType.DeviceCode + } +} From 9a88b0fcaff12d2469bdcd4621cf01f6a62d71ba Mon Sep 17 00:00:00 2001 From: manodnyab <66754471+manodnyab@users.noreply.github.com> Date: Thu, 29 Aug 2024 11:39:31 -0700 Subject: [PATCH 05/28] Added UI click metrics on all login options (#4838) * Added UI click metrics on all login options * Combined calls for continue and back button --- .../services/amazonq/QLoginWebview.kt | 4 +-- .../jetbrains/core/webview/BrowserMessage.kt | 4 +-- .../webview/src/q-ui/components/login.vue | 25 +++++++++++++++---- .../src/q-ui/components/loginOptions.vue | 7 ++++-- .../webview/src/q-ui/components/qOptions.vue | 6 +++++ .../src/q-ui/components/selectableItem.vue | 6 ++++- .../src/q-ui/components/toolkitOptions.vue | 7 ++++++ .../explorer/webview/ToolkitLoginWebview.kt | 4 +-- 8 files changed, 49 insertions(+), 14 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt index d837df01d0..88efdac871 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QLoginWebview.kt @@ -195,8 +195,8 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos error("QBrowser doesn't support the provided command ${message::class.simpleName}") } - is BrowserMessage.SendTelemetry -> { - UiTelemetry.click(project, "auth_continueButton") + is BrowserMessage.SendUiClickTelemetry -> { + UiTelemetry.click(project, message.signInOptionClicked) } } } diff --git a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/BrowserMessage.kt b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/BrowserMessage.kt index 120f544f73..6ef09af487 100644 --- a/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/BrowserMessage.kt +++ b/plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/webview/BrowserMessage.kt @@ -25,7 +25,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo JsonSubTypes.Type(value = BrowserMessage.CancelLogin::class, name = "cancelLogin"), JsonSubTypes.Type(value = BrowserMessage.Signout::class, name = "signout"), JsonSubTypes.Type(value = BrowserMessage.Reauth::class, name = "reauth"), - JsonSubTypes.Type(value = BrowserMessage.SendTelemetry::class, name = "sendTelemetry") + JsonSubTypes.Type(value = BrowserMessage.SendUiClickTelemetry::class, name = "sendUiClickTelemetry") ) sealed interface BrowserMessage { @@ -57,5 +57,5 @@ sealed interface BrowserMessage { object Reauth : BrowserMessage - object SendTelemetry : BrowserMessage + data class SendUiClickTelemetry(val signInOptionClicked: String) : BrowserMessage } diff --git a/plugins/core/webview/src/q-ui/components/login.vue b/plugins/core/webview/src/q-ui/components/login.vue index 634e4f05ab..d578eb4e60 100644 --- a/plugins/core/webview/src/q-ui/components/login.vue +++ b/plugins/core/webview/src/q-ui/components/login.vue @@ -13,9 +13,9 @@ - - - + + + @@ -27,7 +27,18 @@ import SsoLoginForm from "./ssoLoginForm.vue"; import LoginOptions from "./loginOptions.vue"; import AwsProfileForm from "./awsProfileForm.vue"; import Authenticating from "./authenticating.vue"; -import {BuilderId, ExistConnection, Feature, IdC, LoginOption, LongLivedIAM, Stage} from "../../model"; +import {BuilderId, ExistConnection, Feature, IdC, LoginIdentifier, LoginOption, LongLivedIAM, Stage} from "../../model"; + +const authUiClickOptionMap = { + [LoginIdentifier.BUILDER_ID]: 'auth_builderIdOption', + [LoginIdentifier.ENTERPRISE_SSO]: 'auth_idcOption', + [LoginIdentifier.IAM_CREDENTIAL]: 'auth_credentialsOption', + [LoginIdentifier.EXISTING_LOGINS]: 'auth_existingAuthOption', +} + +function getUiClickEvent(loginIdentifier: LoginIdentifier) { + return (authUiClickOptionMap as any)[loginIdentifier] +} export default defineComponent({ name: 'Login', @@ -71,6 +82,7 @@ export default defineComponent({ this.$store.commit('setStage', stage) }, handleBackButtonClick() { + window.ideApi.postMessage({command: 'sendUiClickTelemetry', signInOptionClicked: "auth_backButton"}) if (this.cancellable) { window.ideApi.postMessage({command: 'toggleBrowser'}) } @@ -81,7 +93,7 @@ export default defineComponent({ this.mutateStage('START') }, login(type: LoginOption) { - window.ideApi.postMessage({command: 'sendTelemetry'}) + window.ideApi.postMessage({command: 'sendUiClickTelemetry', signInOptionClicked: "auth_continueButton"}) this.selectedLoginOption = type this.mutateStage('AUTHENTICATING') if (type instanceof IdC) { @@ -103,6 +115,9 @@ export default defineComponent({ } else if (type instanceof ExistConnection) { window.ideApi.postMessage({ command: 'selectConnection', connectionId: type.pluginConnectionId}) } + }, + sendUiClickTelemetry(element: LoginIdentifier) { + window.ideApi.postMessage({command: 'sendUiClickTelemetry', signInOptionClicked: getUiClickEvent(element)}) } }, mounted() {}, diff --git a/plugins/core/webview/src/q-ui/components/loginOptions.vue b/plugins/core/webview/src/q-ui/components/loginOptions.vue index 394ac5fc27..9d55100d22 100644 --- a/plugins/core/webview/src/q-ui/components/loginOptions.vue +++ b/plugins/core/webview/src/q-ui/components/loginOptions.vue @@ -2,8 +2,8 @@ diff --git a/plugins/core/webview/src/q-ui/components/toolkitOptions.vue b/plugins/core/webview/src/q-ui/components/toolkitOptions.vue index a900803cef..b95a9e5188 100644 --- a/plugins/core/webview/src/q-ui/components/toolkitOptions.vue +++ b/plugins/core/webview/src/q-ui/components/toolkitOptions.vue @@ -8,6 +8,7 @@
{ - UiTelemetry.click(project, "auth_continueButton") + is BrowserMessage.SendUiClickTelemetry -> { + UiTelemetry.click(project, message.signInOptionClicked) } } } From b6e4e7b9ea44bffe4f4d21be3755cde4625fe803 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Thu, 29 Aug 2024 19:12:35 +0000 Subject: [PATCH 06/28] Updating version to 3.25 --- .changes/3.25.json | 11 +++++++++++ .../bugfix-0ccdf63e-6477-4f50-a0cb-c3bc10fce622.json | 4 ---- .../bugfix-3cb3570e-fd8f-4423-91cc-bc5513b7196f.json | 4 ---- CHANGELOG.md | 4 ++++ gradle.properties | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 .changes/3.25.json delete mode 100644 .changes/next-release/bugfix-0ccdf63e-6477-4f50-a0cb-c3bc10fce622.json delete mode 100644 .changes/next-release/bugfix-3cb3570e-fd8f-4423-91cc-bc5513b7196f.json diff --git a/.changes/3.25.json b/.changes/3.25.json new file mode 100644 index 0000000000..be422e5d5a --- /dev/null +++ b/.changes/3.25.json @@ -0,0 +1,11 @@ +{ + "date" : "2024-08-29", + "version" : "3.25", + "entries" : [ { + "type" : "bugfix", + "description" : "Fix bug where text with inline code copied from Amazon Q Chat had new line breaks around the inline code text" + }, { + "type" : "bugfix", + "description" : "Fix bug when disabled commands does not get filtered in quick actions" + } ] +} \ No newline at end of file diff --git a/.changes/next-release/bugfix-0ccdf63e-6477-4f50-a0cb-c3bc10fce622.json b/.changes/next-release/bugfix-0ccdf63e-6477-4f50-a0cb-c3bc10fce622.json deleted file mode 100644 index 635e7bf886..0000000000 --- a/.changes/next-release/bugfix-0ccdf63e-6477-4f50-a0cb-c3bc10fce622.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type" : "bugfix", - "description" : "Fix bug where text with inline code copied from Amazon Q Chat had new line breaks around the inline code text" -} \ No newline at end of file diff --git a/.changes/next-release/bugfix-3cb3570e-fd8f-4423-91cc-bc5513b7196f.json b/.changes/next-release/bugfix-3cb3570e-fd8f-4423-91cc-bc5513b7196f.json deleted file mode 100644 index ec947ffd3c..0000000000 --- a/.changes/next-release/bugfix-3cb3570e-fd8f-4423-91cc-bc5513b7196f.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type" : "bugfix", - "description" : "Fix bug when disabled commands does not get filtered in quick actions" -} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 10e92e8517..9e6848a06e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# _3.25_ (2024-08-29) +- **(Bug Fix)** Fix bug where text with inline code copied from Amazon Q Chat had new line breaks around the inline code text +- **(Bug Fix)** Fix bug when disabled commands does not get filtered in quick actions + # _3.24_ (2024-08-22) - **(Feature)** Add notification for IdC users on extended session - **(Bug Fix)** Amazon Q: update login logo styling diff --git a/gradle.properties b/gradle.properties index 946dc1650c..758ed81778 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Toolkit Version -toolkitVersion=3.25-SNAPSHOT +toolkitVersion=3.25 # Publish Settings publishToken= From b8841096e57f8a656b3cf5fc1e647345acf7f072 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Thu, 29 Aug 2024 22:53:35 +0000 Subject: [PATCH 07/28] Updating SNAPSHOT version to 3.26-SNAPSHOT --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 758ed81778..79b6c5bfcb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Toolkit Version -toolkitVersion=3.25 +toolkitVersion=3.26-SNAPSHOT # Publish Settings publishToken= From edbde532c701951b640760451cfc1abdb25bc630 Mon Sep 17 00:00:00 2001 From: manodnyab <66754471+manodnyab@users.noreply.github.com> Date: Fri, 30 Aug 2024 11:38:46 -0700 Subject: [PATCH 08/28] Revert open and close sign in webview telemetry (#4850) * Revert open and close sign in webview telemetry * add changelog * added issue in changelog * Update bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json --------- Co-authored-by: Richard Li <742829+rli@users.noreply.github.com> --- .../bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json | 4 ++++ .../cwc/controller/chat/telemetry/TelemetryHelper.kt | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) create mode 100644 .changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json diff --git a/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json b/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json new file mode 100644 index 0000000000..e3eca9015c --- /dev/null +++ b/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json @@ -0,0 +1,4 @@ +{ + "type" : "bugfix", + "description" : "Fix Runtime Exception when opening a tool window (#4849)" +} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt index 5ae7e40acd..ebeba08b88 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt @@ -12,9 +12,6 @@ import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn -import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection -import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager -import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization @@ -32,7 +29,6 @@ import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService import software.aws.toolkits.jetbrains.utils.notifyError import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.AmazonqTelemetry -import software.aws.toolkits.telemetry.AuthTelemetry import software.aws.toolkits.telemetry.CwsprChatCommandType import software.aws.toolkits.telemetry.CwsprChatConversationType import software.aws.toolkits.telemetry.CwsprChatInteractionType @@ -391,20 +387,12 @@ class TelemetryHelper(private val context: AmazonQAppInitContext, private val se companion object { private val logger = getLogger() - fun getQConnection(): ToolkitConnection? = ToolkitConnectionManager.getInstance(null).activeConnectionForFeature(QConnection.getInstance()) - fun recordOpenChat() { AmazonqTelemetry.openChat(passive = true) - if (getQConnection() == null) { - AuthTelemetry.signInPageOpened() - } } fun recordCloseChat() { AmazonqTelemetry.closeChat(passive = true) - if (getQConnection() == null) { - AuthTelemetry.signInPageClosed() - } } fun recordTelemetryChatRunCommand(type: CwsprChatCommandType, name: String? = null, startUrl: String? = null) { From 3cdb18e6703ab8017d58e0ed096cf8062a8c12c2 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Fri, 30 Aug 2024 19:01:36 +0000 Subject: [PATCH 09/28] Updating version to 3.26 --- .changes/3.26.json | 8 ++++++++ .../bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json | 4 ---- CHANGELOG.md | 3 +++ gradle.properties | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 .changes/3.26.json delete mode 100644 .changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json diff --git a/.changes/3.26.json b/.changes/3.26.json new file mode 100644 index 0000000000..7d9ccae8b6 --- /dev/null +++ b/.changes/3.26.json @@ -0,0 +1,8 @@ +{ + "date" : "2024-08-30", + "version" : "3.26", + "entries" : [ { + "type" : "bugfix", + "description" : "Fix Runtime Exception when opening a tool window (#4849)" + } ] +} \ No newline at end of file diff --git a/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json b/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json deleted file mode 100644 index e3eca9015c..0000000000 --- a/.changes/next-release/bugfix-64bb0c4b-8d3b-45b0-b615-8722bb3e9e4a.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type" : "bugfix", - "description" : "Fix Runtime Exception when opening a tool window (#4849)" -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e6848a06e..f3ee6af23f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +# _3.26_ (2024-08-30) +- **(Bug Fix)** Fix Runtime Exception when opening a tool window ([#4849](https://github.com/aws/aws-toolkit-jetbrains/issues/4849)) + # _3.25_ (2024-08-29) - **(Bug Fix)** Fix bug where text with inline code copied from Amazon Q Chat had new line breaks around the inline code text - **(Bug Fix)** Fix bug when disabled commands does not get filtered in quick actions diff --git a/gradle.properties b/gradle.properties index 79b6c5bfcb..ea0a525479 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Toolkit Version -toolkitVersion=3.26-SNAPSHOT +toolkitVersion=3.26 # Publish Settings publishToken= From 4a206c18f9c0728a1451087ab0ac78663bd138e8 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Fri, 30 Aug 2024 20:27:46 +0000 Subject: [PATCH 10/28] Updating SNAPSHOT version to 3.27-SNAPSHOT --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index ea0a525479..f40262567c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # Toolkit Version -toolkitVersion=3.26 +toolkitVersion=3.27-SNAPSHOT # Publish Settings publishToken= From a478c5aac80e076efa25eb9019b09cc5faad0800 Mon Sep 17 00:00:00 2001 From: David <60020664+dhasani23@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:32:19 -0700 Subject: [PATCH 11/28] telemetry(amazonq): update telemetry (#4847) * telemetry(amazonq): update telemetry * remove unused import --------- Co-authored-by: David Hasani --- gradle/libs.versions.toml | 2 +- .../codemodernizer/CodeModernizerManager.kt | 2 +- .../CodeTransformTelemetryManager.kt | 25 ------------------- 3 files changed, 2 insertions(+), 27 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f3222952c6..348c1c9ed0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ mockitoKotlin = "5.4.0" mockk = "1.13.10" nimbus-jose-jwt = "9.40" node-gradle = "7.0.2" -telemetryGenerator = "1.0.247" +telemetryGenerator = "1.0.250" testLogger = "4.0.0" testRetry = "1.5.10" # test-only; platform provides slf4j transitively at runtime diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt index 6bf95cf7bd..026dab1952 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeModernizerManager.kt @@ -191,7 +191,7 @@ class CodeModernizerManager(private val project: Project) : PersistentStateCompo supportedBuildFileNames.joinToString() ), invalidTelemetryReason = InvalidTelemetryReason( - CodeTransformPreValidationError.NonMavenProject, + CodeTransformPreValidationError.UnsupportedBuildSystem, if (isGradleProject(project)) "Gradle build" else "other build" ), buildSystem = if (isGradleProject(project)) CodeTransformBuildSystem.Gradle else CodeTransformBuildSystem.Unknown diff --git a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformTelemetryManager.kt b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformTelemetryManager.kt index ad5a4be72f..dc8f0c8cfd 100644 --- a/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformTelemetryManager.kt +++ b/plugins/amazonq/codetransform/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codemodernizer/CodeTransformTelemetryManager.kt @@ -18,7 +18,6 @@ import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getAuthType import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getJavaVersionFromProjectSetting import software.aws.toolkits.jetbrains.services.codemodernizer.utils.getMavenVersion import software.aws.toolkits.jetbrains.services.codemodernizer.utils.tryGetJdk -import software.aws.toolkits.telemetry.CodeTransformApiNames import software.aws.toolkits.telemetry.CodeTransformArtifactType import software.aws.toolkits.telemetry.CodeTransformBuildCommand import software.aws.toolkits.telemetry.CodeTransformCancelSrcComponents @@ -84,30 +83,6 @@ class CodeTransformTelemetryManager(private val project: Project) { codeTransformRunTimeLatency = calculateTotalLatency(startTime, Instant.now()), ) - @Suppress("UNUSED_PARAMETER") - fun apiError(errorMessage: String, apiName: CodeTransformApiNames, jobId: String?) = CodetransformTelemetry.logApiError( - reason = errorMessage, - codeTransformSessionId = sessionId, - codeTransformJobId = jobId, - ) - - fun logApiLatency( - apiName: CodeTransformApiNames, - startTime: Instant, - codeTransformTotalByteSize: Int? = null, - codeTransformUploadId: String? = null, - codeTransformJobId: String? = null, - codeTransformRequestId: String? = null - ) = CodetransformTelemetry.logApiLatency( - codeTransformApiNames = apiName, - codeTransformSessionId = sessionId, - codeTransformRunTimeLatency = calculateTotalLatency(startTime, Instant.now()), - codeTransformUploadId = codeTransformUploadId, - codeTransformJobId = codeTransformJobId, - codeTransformTotalByteSize = codeTransformTotalByteSize, - codeTransformRequestId = codeTransformRequestId - ) - fun vcsDiffViewerVisible(jobId: JobId) = CodetransformTelemetry.vcsDiffViewerVisible( codeTransformSessionId = sessionId, codeTransformJobId = jobId.id, From 930e70641f1f3f34388ff843b2ab4f3c749cd1de Mon Sep 17 00:00:00 2001 From: Lei Gao <97199248+leigaol@users.noreply.github.com> Date: Tue, 3 Sep 2024 15:26:21 -0700 Subject: [PATCH 12/28] feat(amazonq): Reduce @workspace indexing time by 50% (#4846) --- .../feature-6d2b6ef8-8200-438d-9ba6-4932066d0af3.json | 4 ++++ .../cwc/editor/context/project/manifest/ManifestManager.kt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changes/next-release/feature-6d2b6ef8-8200-438d-9ba6-4932066d0af3.json diff --git a/.changes/next-release/feature-6d2b6ef8-8200-438d-9ba6-4932066d0af3.json b/.changes/next-release/feature-6d2b6ef8-8200-438d-9ba6-4932066d0af3.json new file mode 100644 index 0000000000..8954edd988 --- /dev/null +++ b/.changes/next-release/feature-6d2b6ef8-8200-438d-9ba6-4932066d0af3.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Reduce `@workspace` indexing time by 50%" +} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt index e58dc51621..78ab39ad9e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt @@ -15,7 +15,7 @@ import software.aws.toolkits.jetbrains.core.getTextFromUrl class ManifestManager { private val cloudFrontUrl = "https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json" - val currentVersion = "0.1.3" + val currentVersion = "0.1.5" val currentOs = getOs() private val arch = CpuArch.CURRENT private val mapper = jacksonObjectMapper() From 334e8e193f89e30535f4560e77bc0f02d432016a Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 4 Sep 2024 13:42:19 -0700 Subject: [PATCH 13/28] Hash startUrl --- .../jetbrains/services/cwc/commands/TestCodeAction.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt index cc79abdc36..3479d03474 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -13,6 +13,9 @@ class TestCodeAction : CustomAction(EditorContextCommand.Test) { override fun update(e: AnActionEvent) { val project = e.getData(CommonDataKeys.PROJECT) ?: return val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection - e.presentation.isVisible = (connection != null && connection.startUrl == "https://amzn.awsapps.com/start") + val hashedStartUrl = hashStartUrl(connection.startUrl, "MD5") + e.presentation.isVisible = (connection != null && connection.startUrl == "[B@4ccabbaa") } + + fun hashStartUrl(str: String, algorithm: String): ByteArray = MessageDigest.getInstance(algorithm).digest(str.toByteArray(UTF_8)) } From edaecdb7f20cc7afc4779e711b77a63155026abb Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Fri, 6 Sep 2024 11:44:33 -0700 Subject: [PATCH 14/28] Revert CodeWhisperer endpoint back gamma endpoint --- .../services/codewhisperer/util/CodeWhispererConstants.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt index fc9f2ee7a3..4eb9980e21 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererConstants.kt @@ -105,7 +105,7 @@ object CodeWhispererConstants { } object Config { - const val CODEWHISPERER_ENDPOINT = "https://rts.gamma-us-east-1.codewhisperer.ai.aws.dev/" // gamma + const val CODEWHISPERER_ENDPOINT = "https://codewhisperer.us-east-1.amazonaws.com/" // PROD const val CODEWHISPERER_IDPOOL_ID = "us-east-1:70717e99-906f-4add-908c-bd9074a2f5b9" val Sigv4ClientRegion = Region.US_EAST_1 val BearerClientRegion = Region.US_EAST_1 From 54816fbc349461f9fb2e4bac4c6663deccc7a2e3 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Fri, 6 Sep 2024 11:48:05 -0700 Subject: [PATCH 15/28] Revert adding user intent to interact with message metadata --- .../core/jetbrains-community/resources/telemetryOverride.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugins/core/jetbrains-community/resources/telemetryOverride.json b/plugins/core/jetbrains-community/resources/telemetryOverride.json index 7ec40cfcda..7a5b977194 100644 --- a/plugins/core/jetbrains-community/resources/telemetryOverride.json +++ b/plugins/core/jetbrains-community/resources/telemetryOverride.json @@ -688,10 +688,6 @@ { "type": "cwsprChatHasProjectContext", "required": false - }, - { - "type": "cwsprChatUserIntent", - "required": false } ] }, From c25dbe516e0c7d5228389df47bbb6078bf3ea04c Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Fri, 6 Sep 2024 12:06:44 -0700 Subject: [PATCH 16/28] Add changelog --- .../feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json diff --git a/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json b/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json new file mode 100644 index 0000000000..43c93c715d --- /dev/null +++ b/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Amazon Q: Add command to generate unit tests for selected code" +} \ No newline at end of file From c8ed6168ed6ecaf7e85303e2b46848fae335f5d2 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Fri, 6 Sep 2024 13:11:05 -0700 Subject: [PATCH 17/28] Refactor for consistent hashing of startUrl --- .../services/cwc/commands/TestCodeAction.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt index 3479d03474..eb2b2b8db1 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -8,14 +8,23 @@ import com.intellij.openapi.actionSystem.CommonDataKeys import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection +import java.security.MessageDigest +import kotlin.text.Charsets.UTF_8 class TestCodeAction : CustomAction(EditorContextCommand.Test) { override fun update(e: AnActionEvent) { val project = e.getData(CommonDataKeys.PROJECT) ?: return val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection - val hashedStartUrl = hashStartUrl(connection.startUrl, "MD5") - e.presentation.isVisible = (connection != null && connection.startUrl == "[B@4ccabbaa") + if (connection == null) { + // Hide the action by default if no connection found. + e.presentation.isEnabledAndVisible = false + return + } + + e.presentation.isEnabledAndVisible = hashStartUrl(connection.startUrl) == "222dc4c61f7b8d08cdaf133a0a29f994" } - fun hashStartUrl(str: String, algorithm: String): ByteArray = MessageDigest.getInstance(algorithm).digest(str.toByteArray(UTF_8)) + private fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) } + + private fun hashStartUrl(startUrl: String, algorithm: String = "MD5"): String = MessageDigest.getInstance(algorithm).digest(startUrl.toByteArray(UTF_8)).toHex() } From 673c6e1d95378d44e27b6b53d67aac3f3a6dd249 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 10 Sep 2024 11:19:20 -0700 Subject: [PATCH 18/28] Remove hashing logic on startUrl and changelog entry --- .../feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json | 4 ---- .../jetbrains/services/cwc/commands/TestCodeAction.kt | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 .changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json diff --git a/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json b/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json deleted file mode 100644 index 43c93c715d..0000000000 --- a/.changes/next-release/feature-6597c5eb-9bb5-4f22-a555-7cd9b14be7be.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type" : "feature", - "description" : "Amazon Q: Add command to generate unit tests for selected code" -} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt index eb2b2b8db1..b0a6cb3933 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -20,11 +20,6 @@ class TestCodeAction : CustomAction(EditorContextCommand.Test) { e.presentation.isEnabledAndVisible = false return } - - e.presentation.isEnabledAndVisible = hashStartUrl(connection.startUrl) == "222dc4c61f7b8d08cdaf133a0a29f994" + e.presentation.isEnabledAndVisible = connection.startUrl == "https://amzn.awsapps.com/start" } - - private fun ByteArray.toHex() = joinToString(separator = "") { byte -> "%02x".format(byte) } - - private fun hashStartUrl(startUrl: String, algorithm: String = "MD5"): String = MessageDigest.getInstance(algorithm).digest(startUrl.toByteArray(UTF_8)).toHex() } From d589b604521f8df181a5f23a77a16e422e0cda85 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 11 Sep 2024 14:09:22 -0700 Subject: [PATCH 19/28] Add (Beta) suffix to generate unit tests command --- .../software/aws/toolkits/resources/MessagesBundle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 43a6259e35..bb4f32028f 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -26,7 +26,7 @@ action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.text action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.description = Refactors the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.text = Refactor Code action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.description = Generates unit tests for the selected code -action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.text = Test Code +action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.text = Test Code (Beta) action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.description = Sends selected code to chat action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.text = Send to Prompt action.aws.toolkit.open.arn.browser.text=Open ARN in AWS Console From 0d52a230cc892bf603861c7a78c415592b8db21d Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 11 Sep 2024 14:31:51 -0700 Subject: [PATCH 20/28] Add check for startUrl when getting user intent from prompt --- .../services/cwc/controller/ChatController.kt | 4 +++- .../chat/userIntent/UserIntentRecognizer.kt | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 912c144fe6..fa181fe4ce 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -130,6 +130,8 @@ class ChatController private constructor( var shouldAddIndexInProgressMessage: Boolean = false var shouldUseWorkspaceContext: Boolean = false val isDataCollectionGroup = CodeWhispererFeatureConfigService.getInstance().getIsDataCollectionEnabled() + val startUrl = getStartUrl(context.project) + if (prompt.contains("@workspace")) { if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { shouldUseWorkspaceContext = true @@ -151,7 +153,7 @@ class ChatController private constructor( triggerId = triggerId, message = prompt, activeFileContext = contextExtractor.extractContextForTrigger(ExtractionTriggerType.ChatMessage), - userIntent = intentRecognizer.getUserIntentFromPromptChatMessage(message.chatMessage), + userIntent = intentRecognizer.getUserIntentFromPromptChatMessage(message.chatMessage, startUrl), TriggerType.Click, projectContextQueryResult = queryResult, shouldAddIndexInProgressMessage = shouldAddIndexInProgressMessage, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index aea721ab0a..eccf44e78a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -3,7 +3,11 @@ package software.aws.toolkits.jetbrains.services.cwc.controller.chat.userIntent +import com.intellij.openapi.actionSystem.CommonDataKeys import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent +import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteraction import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteractionType import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.FollowUpType @@ -20,12 +24,12 @@ class UserIntentRecognizer { EditorContextCommand.SendToPrompt -> null } - fun getUserIntentFromPromptChatMessage(prompt: String) = when { + fun getUserIntentFromPromptChatMessage(prompt: String, startUrl: String?) = when { prompt.startsWith("Explain") -> UserIntent.EXPLAIN_CODE_SELECTION prompt.startsWith("Refactor") -> UserIntent.SUGGEST_ALTERNATE_IMPLEMENTATION prompt.startsWith("Fix") -> UserIntent.APPLY_COMMON_BEST_PRACTICES prompt.startsWith("Optimize") -> UserIntent.IMPROVE_CODE - prompt.startsWith("Generate tests") || prompt.startsWith("Generate unit tests") -> UserIntent.GENERATE_UNIT_TESTS + prompt.startsWith("Generate unit tests") && isInternalAmazonUser(startUrl) -> UserIntent.GENERATE_UNIT_TESTS else -> null } @@ -45,4 +49,8 @@ class UserIntentRecognizer { fun getUserIntentFromOnboardingPageInteraction(interaction: OnboardingPageInteraction) = when (interaction.type) { OnboardingPageInteractionType.CwcButtonClick -> null } + + private fun isInternalAmazonUser(startUrl: String?): Boolean { + return startUrl == "https://amzn.awsapps.com/start" + } } From 8b5f6728d0ca50c8f16155b3d9c15ff02cb7303e Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 17 Sep 2024 12:01:28 -0700 Subject: [PATCH 21/28] Update TestCodeAction to resolve lint failure Co-authored-by: Richard Li <742829+rli@users.noreply.github.com> --- .../jetbrains/services/cwc/commands/TestCodeAction.kt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt index b0a6cb3933..8d892bd298 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt @@ -15,11 +15,6 @@ class TestCodeAction : CustomAction(EditorContextCommand.Test) { override fun update(e: AnActionEvent) { val project = e.getData(CommonDataKeys.PROJECT) ?: return val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection - if (connection == null) { - // Hide the action by default if no connection found. - e.presentation.isEnabledAndVisible = false - return - } - e.presentation.isEnabledAndVisible = connection.startUrl == "https://amzn.awsapps.com/start" + e.presentation.isEnabledAndVisible = connection?.startUrl == "https://amzn.awsapps.com/start" } } From 3c3d9f33ea1c804e48e205364dded0748023226f Mon Sep 17 00:00:00 2001 From: David Lin Date: Wed, 18 Sep 2024 13:40:24 -0700 Subject: [PATCH 22/28] address comments: Better GenerateUnitTest Action naming --- .../jetbrains-community/resources/META-INF/plugin-chat.xml | 4 ++-- .../commands/{TestCodeAction.kt => GenerateUnitTestAction.kt} | 4 +--- .../jetbrains/services/cwc/controller/ChatController.kt | 2 +- .../cwc/controller/chat/userIntent/UserIntentRecognizer.kt | 2 +- .../software/aws/toolkits/resources/MessagesBundle.properties | 4 ++-- 5 files changed, 7 insertions(+), 9 deletions(-) rename plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/{TestCodeAction.kt => GenerateUnitTestAction.kt} (87%) diff --git a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml index 7710298f5b..2948f11951 100644 --- a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml +++ b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml @@ -70,8 +70,8 @@ - + diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt similarity index 87% rename from plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt rename to plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt index 8d892bd298..48f68f7410 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/TestCodeAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt @@ -8,10 +8,8 @@ import com.intellij.openapi.actionSystem.CommonDataKeys import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection -import java.security.MessageDigest -import kotlin.text.Charsets.UTF_8 -class TestCodeAction : CustomAction(EditorContextCommand.Test) { +class GenerateUnitTestAction : CustomAction(EditorContextCommand.GenerateUnitTest) { override fun update(e: AnActionEvent) { val project = e.getData(CommonDataKeys.PROJECT) ?: return val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index fa181fe4ce..e2a47e4c7d 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -334,7 +334,7 @@ class ChatController private constructor( } // Create prompt - val prompt = if (EditorContextCommand.Test == message.command) + val prompt = if (EditorContextCommand.GenerateUnitTest == message.command) "${message.command.verb} the following part of my code for me: $codeSelection" else "${message.command} the following part of my code for me: $codeSelection"; diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index eccf44e78a..fcd78285b1 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -20,7 +20,7 @@ class UserIntentRecognizer { EditorContextCommand.Fix -> UserIntent.APPLY_COMMON_BEST_PRACTICES EditorContextCommand.Optimize -> UserIntent.IMPROVE_CODE EditorContextCommand.ExplainCodeScanIssue -> UserIntent.EXPLAIN_CODE_SELECTION - EditorContextCommand.Test -> UserIntent.GENERATE_UNIT_TESTS + EditorContextCommand.GenerateUnitTest -> UserIntent.GENERATE_UNIT_TESTS EditorContextCommand.SendToPrompt -> null } diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index 4aa0b1e9fc..c8d7842cbb 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -25,8 +25,8 @@ action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.descr action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.text = Optimize Code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.description = Refactors the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.text = Refactor Code -action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.description = Generates unit tests for the selected code -action.aws.toolkit.jetbrains.core.services.cwc.commands.TestCodeAction.text = Test Code (Beta) +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestAction.description = Generates unit tests for the selected code +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestAction.text = Generate Tests (Beta) action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.description = Sends selected code to chat action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.text = Send to Prompt action.aws.toolkit.open.arn.browser.text=Open ARN in AWS Console From 3124e9ad36891516ab8c5eae53ea53d773d2747e Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Fri, 20 Sep 2024 11:08:05 -0700 Subject: [PATCH 23/28] Refactor to use more specific command for UTG --- .../resources/META-INF/plugin-chat.xml | 4 ++-- .../cwc/commands/EditorContextCommand.kt | 4 ++-- .../cwc/commands/GenerateUnitTestAction.kt | 18 ------------------ .../services/cwc/controller/ChatController.kt | 2 +- .../chat/messenger/ChatPromptHandler.kt | 2 ++ .../chat/userIntent/UserIntentRecognizer.kt | 2 +- .../resources/MessagesBundle.properties | 4 ++-- 7 files changed, 10 insertions(+), 26 deletions(-) delete mode 100644 plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt diff --git a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml index 2948f11951..daec47d109 100644 --- a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml +++ b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml @@ -70,8 +70,8 @@ - + diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt index 4e2103903a..e75a7d584f 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/EditorContextCommand.kt @@ -26,9 +26,9 @@ enum class EditorContextCommand( verb = "Optimize", actionId = "aws.amazonq.optimizeCode", ), - Test( + GenerateUnitTests( verb = "Generate unit tests for", - actionId = "aws.amazonq.testCode", + actionId = "aws.amazonq.generateUnitTests", ), SendToPrompt( verb = "SendToPrompt", diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt deleted file mode 100644 index 48f68f7410..0000000000 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestAction.kt +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.services.cwc.commands - -import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.actionSystem.CommonDataKeys -import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection -import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager -import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection - -class GenerateUnitTestAction : CustomAction(EditorContextCommand.GenerateUnitTest) { - override fun update(e: AnActionEvent) { - val project = e.getData(CommonDataKeys.PROJECT) ?: return - val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection - e.presentation.isEnabledAndVisible = connection?.startUrl == "https://amzn.awsapps.com/start" - } -} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index e2a47e4c7d..30ec17dfbf 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -334,7 +334,7 @@ class ChatController private constructor( } // Create prompt - val prompt = if (EditorContextCommand.GenerateUnitTest == message.command) + val prompt = if (EditorContextCommand.GenerateUnitTests == message.command) "${message.command.verb} the following part of my code for me: $codeSelection" else "${message.command} the following part of my code for me: $codeSelection"; diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt index 0f3754f6c2..cab720802e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt @@ -10,6 +10,8 @@ import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onStart import software.amazon.awssdk.awscore.exception.AwsServiceException import software.amazon.awssdk.services.codewhispererstreaming.model.CodeWhispererStreamingException +import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent +import software.amazon.awssdk.services.codewhispererstreaming.model.ValidationException import software.aws.toolkits.core.utils.convertMarkdownToHTML import software.aws.toolkits.jetbrains.services.cwc.clients.chat.exceptions.ChatApiException import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.ChatRequestData diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index fcd78285b1..00feef02fe 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -20,7 +20,7 @@ class UserIntentRecognizer { EditorContextCommand.Fix -> UserIntent.APPLY_COMMON_BEST_PRACTICES EditorContextCommand.Optimize -> UserIntent.IMPROVE_CODE EditorContextCommand.ExplainCodeScanIssue -> UserIntent.EXPLAIN_CODE_SELECTION - EditorContextCommand.GenerateUnitTest -> UserIntent.GENERATE_UNIT_TESTS + EditorContextCommand.GenerateUnitTests -> UserIntent.GENERATE_UNIT_TESTS EditorContextCommand.SendToPrompt -> null } diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index c8d7842cbb..c65930e355 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -25,8 +25,8 @@ action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.descr action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.text = Optimize Code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.description = Refactors the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.text = Refactor Code -action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestAction.description = Generates unit tests for the selected code -action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestAction.text = Generate Tests (Beta) +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.description = Generates unit tests for the selected code +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.text = Generate Tests (Beta) action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.description = Sends selected code to chat action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.text = Send to Prompt action.aws.toolkit.open.arn.browser.text=Open ARN in AWS Console From 4808425e6bdbb703f20b17b6d5f42531b92cb6e7 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 24 Sep 2024 14:29:59 -0700 Subject: [PATCH 24/28] Change name of action to GenerateUnitTests --- .../cwc/commands/GenerateUnitTestsAction.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt new file mode 100644 index 0000000000..3513a0c823 --- /dev/null +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt @@ -0,0 +1,18 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.cwc.commands + +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection + +class GenerateUnitTestsAction : CustomAction(EditorContextCommand.GenerateUnitTests) { + override fun update(e: AnActionEvent) { + val project = e.getData(CommonDataKeys.PROJECT) ?: return + val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection + e.presentation.isEnabledAndVisible = connection?.startUrl == "https://amzn.awsapps.com/start" + } +} From 061fd25961fe831da317581cd27d93a1670ad305 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Tue, 24 Sep 2024 14:30:24 -0700 Subject: [PATCH 25/28] Fix linting errors --- .../jetbrains/services/cwc/controller/ChatController.kt | 2 +- .../cwc/controller/chat/messenger/ChatPromptHandler.kt | 2 -- .../cwc/controller/chat/userIntent/UserIntentRecognizer.kt | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 30ec17dfbf..fe4bee30df 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -336,7 +336,7 @@ class ChatController private constructor( // Create prompt val prompt = if (EditorContextCommand.GenerateUnitTests == message.command) "${message.command.verb} the following part of my code for me: $codeSelection" else - "${message.command} the following part of my code for me: $codeSelection"; + "${message.command} the following part of my code for me: $codeSelection" processPromptActions(prompt, message, triggerId, fileContext) } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt index cab720802e..0f3754f6c2 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/messenger/ChatPromptHandler.kt @@ -10,8 +10,6 @@ import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.onStart import software.amazon.awssdk.awscore.exception.AwsServiceException import software.amazon.awssdk.services.codewhispererstreaming.model.CodeWhispererStreamingException -import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent -import software.amazon.awssdk.services.codewhispererstreaming.model.ValidationException import software.aws.toolkits.core.utils.convertMarkdownToHTML import software.aws.toolkits.jetbrains.services.cwc.clients.chat.exceptions.ChatApiException import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.ChatRequestData diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index 00feef02fe..794ae2dd9a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -3,11 +3,7 @@ package software.aws.toolkits.jetbrains.services.cwc.controller.chat.userIntent -import com.intellij.openapi.actionSystem.CommonDataKeys import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent -import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection -import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager -import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteraction import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteractionType import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.FollowUpType From ba4329d2659361cebf025f6ac2b54bf4e4882119 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 25 Sep 2024 10:31:59 -0700 Subject: [PATCH 26/28] Override 'getActionUpdateThread' --- .../jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt index 3513a0c823..2b1592110a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/GenerateUnitTestsAction.kt @@ -3,6 +3,7 @@ package software.aws.toolkits.jetbrains.services.cwc.commands +import com.intellij.openapi.actionSystem.ActionUpdateThread import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.CommonDataKeys import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection @@ -10,6 +11,8 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection class GenerateUnitTestsAction : CustomAction(EditorContextCommand.GenerateUnitTests) { + override fun getActionUpdateThread() = ActionUpdateThread.BGT + override fun update(e: AnActionEvent) { val project = e.getData(CommonDataKeys.PROJECT) ?: return val connection = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection From 5317be318da4597d19388f0b26254878ff42bf9f Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 25 Sep 2024 10:53:34 -0700 Subject: [PATCH 27/28] Reorder MessageBundle.properties --- .../software/aws/toolkits/resources/MessagesBundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties index a52cea6b0a..42ee69394f 100644 --- a/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties +++ b/plugins/core/resources/resources/software/aws/toolkits/resources/MessagesBundle.properties @@ -21,12 +21,12 @@ action.aws.toolkit.jetbrains.core.services.cwc.commands.ExplainCodeAction.descri action.aws.toolkit.jetbrains.core.services.cwc.commands.ExplainCodeAction.text = Explain Code action.aws.toolkit.jetbrains.core.services.cwc.commands.FixCodeAction.description = Fixes the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.FixCodeAction.text = Fix Code +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.description = Generates unit tests for the selected code +action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.text = Generate Tests (Beta) action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.description = Optimizes the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.OptimizeCodeAction.text = Optimize Code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.description = Refactors the selected code action.aws.toolkit.jetbrains.core.services.cwc.commands.RefactorCodeAction.text = Refactor Code -action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.description = Generates unit tests for the selected code -action.aws.toolkit.jetbrains.core.services.cwc.commands.GenerateUnitTestsAction.text = Generate Tests (Beta) action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.description = Sends selected code to chat action.aws.toolkit.jetbrains.core.services.cwc.commands.SendToPromptAction.text = Send to Prompt action.aws.toolkit.open.arn.browser.text=Open ARN in AWS Console From f3f324d220c05bf4dd6725574fc0a1c38e8b3469 Mon Sep 17 00:00:00 2001 From: Bodie Weedop Date: Wed, 25 Sep 2024 11:38:29 -0700 Subject: [PATCH 28/28] Fix syntax error --- .../jetbrains/services/cwc/controller/ChatController.kt | 8 +++++--- .../controller/chat/userIntent/UserIntentRecognizer.kt | 4 +--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index fe4bee30df..cd1ae5da02 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -130,7 +130,7 @@ class ChatController private constructor( var shouldAddIndexInProgressMessage: Boolean = false var shouldUseWorkspaceContext: Boolean = false val isDataCollectionGroup = CodeWhispererFeatureConfigService.getInstance().getIsDataCollectionEnabled() - val startUrl = getStartUrl(context.project) + val startUrl = getStartUrl(context.project) if (prompt.contains("@workspace")) { if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { @@ -334,9 +334,11 @@ class ChatController private constructor( } // Create prompt - val prompt = if (EditorContextCommand.GenerateUnitTests == message.command) - "${message.command.verb} the following part of my code for me: $codeSelection" else + val prompt = if (EditorContextCommand.GenerateUnitTests == message.command) { + "${message.command.verb} the following part of my code for me: $codeSelection" + } else { "${message.command} the following part of my code for me: $codeSelection" + } processPromptActions(prompt, message, triggerId, fileContext) } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt index 794ae2dd9a..f15f0125e9 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/userIntent/UserIntentRecognizer.kt @@ -46,7 +46,5 @@ class UserIntentRecognizer { OnboardingPageInteractionType.CwcButtonClick -> null } - private fun isInternalAmazonUser(startUrl: String?): Boolean { - return startUrl == "https://amzn.awsapps.com/start" - } + private fun isInternalAmazonUser(startUrl: String?): Boolean = startUrl == "https://amzn.awsapps.com/start" }