diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocApp.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocApp.kt index 0662b23d498..0e55a655579 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocApp.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/DocApp.kt @@ -83,10 +83,7 @@ class DocApp : AmazonQApp { is IncomingDocMessage.TabRemoved -> inboundAppMessagesHandler.processTabRemovedMessage(message) is IncomingDocMessage.AuthFollowUpWasClicked -> inboundAppMessagesHandler.processAuthFollowUpClick(message) is IncomingDocMessage.FollowupClicked -> inboundAppMessagesHandler.processFollowupClickedMessage(message) - is IncomingDocMessage.ChatItemVotedMessage -> inboundAppMessagesHandler.processChatItemVotedMessage(message) - is IncomingDocMessage.ChatItemFeedbackMessage -> inboundAppMessagesHandler.processChatItemFeedbackMessage(message) is IncomingDocMessage.ClickedLink -> inboundAppMessagesHandler.processLinkClick(message) - is IncomingDocMessage.InsertCodeAtCursorPosition -> inboundAppMessagesHandler.processInsertCodeAtCursorPosition(message) is IncomingDocMessage.OpenDiff -> inboundAppMessagesHandler.processOpenDiff(message) is IncomingDocMessage.FileClicked -> inboundAppMessagesHandler.processFileClicked(message) is IncomingDocMessage.StopDocGeneration -> inboundAppMessagesHandler.processStopDocGeneration(message) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/InboundAppMessagesHandler.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/InboundAppMessagesHandler.kt index 34038a749a3..3227335196a 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/InboundAppMessagesHandler.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/InboundAppMessagesHandler.kt @@ -11,10 +11,7 @@ interface InboundAppMessagesHandler { suspend fun processTabRemovedMessage(message: IncomingDocMessage.TabRemoved) suspend fun processAuthFollowUpClick(message: IncomingDocMessage.AuthFollowUpWasClicked) suspend fun processFollowupClickedMessage(message: IncomingDocMessage.FollowupClicked) - suspend fun processChatItemVotedMessage(message: IncomingDocMessage.ChatItemVotedMessage) - suspend fun processChatItemFeedbackMessage(message: IncomingDocMessage.ChatItemFeedbackMessage) suspend fun processLinkClick(message: IncomingDocMessage.ClickedLink) - suspend fun processInsertCodeAtCursorPosition(message: IncomingDocMessage.InsertCodeAtCursorPosition) suspend fun processOpenDiff(message: IncomingDocMessage.OpenDiff) suspend fun processFileClicked(message: IncomingDocMessage.FileClicked) suspend fun processStopDocGeneration(message: IncomingDocMessage.StopDocGeneration) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/controller/DocController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/controller/DocController.kt index 3788e8449e5..a6ab9b4c174 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/controller/DocController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/controller/DocController.kt @@ -3,7 +3,6 @@ package software.aws.toolkits.jetbrains.services.amazonqDoc.controller -import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.diff.DiffContentFactory import com.intellij.diff.DiffManager import com.intellij.diff.contents.EmptyContent @@ -11,17 +10,12 @@ import com.intellij.diff.requests.SimpleDiffRequest import com.intellij.diff.util.DiffUserDataKeys import com.intellij.ide.BrowserUtil import com.intellij.openapi.application.runInEdt -import com.intellij.openapi.command.WriteCommandAction -import com.intellij.openapi.editor.Caret -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.fileEditor.FileEditorManager import com.intellij.openapi.vfs.VfsUtil import com.intellij.openapi.wm.ToolWindowManager import kotlinx.coroutines.withContext import software.amazon.awssdk.services.codewhispererruntime.model.DocGenerationFolderLevel import software.amazon.awssdk.services.codewhispererruntime.model.DocGenerationInteractionType import software.amazon.awssdk.services.codewhispererruntime.model.DocGenerationUserDecision -import software.amazon.awssdk.services.toolkittelemetry.model.Sentiment import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.error import software.aws.toolkits.core.utils.getLogger @@ -37,7 +31,6 @@ import software.aws.toolkits.jetbrains.services.amazonqDoc.DEFAULT_RETRY_LIMIT import software.aws.toolkits.jetbrains.services.amazonqDoc.DocException import software.aws.toolkits.jetbrains.services.amazonqDoc.FEATURE_NAME import software.aws.toolkits.jetbrains.services.amazonqDoc.InboundAppMessagesHandler -import software.aws.toolkits.jetbrains.services.amazonqDoc.ModifySourceFolderErrorReason import software.aws.toolkits.jetbrains.services.amazonqDoc.ZipFileError import software.aws.toolkits.jetbrains.services.amazonqDoc.cancellingProgressField import software.aws.toolkits.jetbrains.services.amazonqDoc.createUserFacingErrorMessage @@ -74,13 +67,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.Delete import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.NewFileZipInfo import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.SessionStatePhase import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource -import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.FeedbackComment -import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl -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.Result import java.util.UUID enum class DocGenerationStep { @@ -343,84 +330,13 @@ class DocController( } } - override suspend fun processChatItemVotedMessage(message: IncomingDocMessage.ChatItemVotedMessage) { - logger.debug { "$FEATURE_NAME: Processing ChatItemVotedMessage: $message" } - - val session = chatSessionStorage.getSession(message.tabId, context.project) - when (message.vote) { - "upvote" -> { - AmazonqTelemetry.codeGenerationThumbsUp( - amazonqConversationId = session.conversationId, - credentialStartUrl = getStartUrl(project = context.project) - ) - } - - "downvote" -> { - AmazonqTelemetry.codeGenerationThumbsDown( - amazonqConversationId = session.conversationId, - credentialStartUrl = getStartUrl(project = context.project) - ) - } - } - } - - override suspend fun processChatItemFeedbackMessage(message: IncomingDocMessage.ChatItemFeedbackMessage) { - logger.debug { "$FEATURE_NAME: Processing ChatItemFeedbackMessage: ${message.comment}" } - - val session = getSessionInfo(message.tabId) - - val comment = FeedbackComment( - conversationId = session.conversationId, - userComment = message.comment.orEmpty(), - reason = message.selectedOption, - messageId = message.messageId, - type = "doc-chat-answer-feedback" - ) - - try { - TelemetryService.getInstance().sendFeedback( - sentiment = Sentiment.NEGATIVE, - comment = objectMapper.writeValueAsString(comment), - ) - logger.info { "$FEATURE_NAME answer feedback sent: \"Negative\"" } - } catch (e: Throwable) { - e.notifyError(message("feedback.submit_failed", e)) - logger.warn(e) { "Failed to submit feedback" } - return - } - } - override suspend fun processLinkClick(message: IncomingDocMessage.ClickedLink) { BrowserUtil.browse(message.link) } - override suspend fun processInsertCodeAtCursorPosition(message: IncomingDocMessage.InsertCodeAtCursorPosition) { - logger.debug { "$FEATURE_NAME: Processing InsertCodeAtCursorPosition: $message" } - - withContext(EDT) { - val editor: Editor = FileEditorManager.getInstance(context.project).selectedTextEditor ?: return@withContext - - val caret: Caret = editor.caretModel.primaryCaret - val offset: Int = caret.offset - - WriteCommandAction.runWriteCommandAction(context.project) { - if (caret.hasSelection()) { - editor.document.deleteString(caret.selectionStart, caret.selectionEnd) - } - editor.document.insertString(offset, message.code) - } - } - } - override suspend fun processOpenDiff(message: IncomingDocMessage.OpenDiff) { val session = getSessionInfo(message.tabId) - AmazonqTelemetry.isReviewedChanges( - amazonqConversationId = session.conversationId, - enabled = true, - credentialStartUrl = getStartUrl(project = context.project) - ) - val project = context.project val sessionState = session.sessionState @@ -528,13 +444,6 @@ class DocController( } } - AmazonqTelemetry.isAcceptedCodeChanges( - amazonqNumberOfFilesAccepted = (filePaths.filterNot { it.rejected }.size + deletedFiles.filterNot { it.rejected }.size) * 1.0, - amazonqConversationId = session.conversationId, - enabled = true, - credentialStartUrl = getStartUrl(project = context.project) - ) - session.insertChanges( filePaths = filePaths.filterNot { it.rejected }, deletedFiles = deletedFiles.filterNot { it.rejected } @@ -572,14 +481,7 @@ class DocController( } private suspend fun newTask(tabId: String) { - val session = getSessionInfo(tabId) - val sessionLatency = System.currentTimeMillis() - session.sessionStartTime docGenerationTask = DocGenerationTask() - AmazonqTelemetry.endChat( - amazonqConversationId = session.conversationId, - amazonqEndOfTheConversationLatency = sessionLatency.toDouble(), - credentialStartUrl = getStartUrl(project = context.project) - ) chatSessionStorage.deleteSession(tabId) messenger.sendAnswer( @@ -627,25 +529,9 @@ class DocController( messenger.sendChatInputEnabledMessage(tabId = tabId, enabled = false) docGenerationTask.reset() - - val session = getSessionInfo(tabId) - val sessionLatency = System.currentTimeMillis() - session.sessionStartTime - AmazonqTelemetry.endChat( - amazonqConversationId = session.conversationId, - amazonqEndOfTheConversationLatency = sessionLatency.toDouble(), - credentialStartUrl = getStartUrl(project = context.project) - ) } private suspend fun provideFeedbackAndRegenerateCode(tabId: String) { - val session = getSessionInfo(tabId) - - AmazonqTelemetry.isProvideFeedbackForCodeGen( - amazonqConversationId = session.conversationId, - enabled = true, - credentialStartUrl = getStartUrl(project = context.project) - ) - // Unblock the message button messenger.sendAsyncEventProgress(tabId = tabId, inProgress = false) @@ -1007,16 +893,11 @@ class DocController( val currentSourceFolder = session.context.selectedSourceFolder val projectRoot = session.context.projectRoot - var result: Result = Result.Failed - var reason: ModifySourceFolderErrorReason? = null - withContext(EDT) { val selectedFolder = selectFolder(context.project, currentSourceFolder) // No folder was selected if (selectedFolder == null) { logger.info { "Cancelled dialog and not selected any folder" } - - reason = ModifySourceFolderErrorReason.ClosedBeforeSelection return@withContext } @@ -1029,8 +910,6 @@ class DocController( messageType = DocMessageType.Answer, message = message("amazonqFeatureDev.follow_up.incorrect_source_folder"), ) - - reason = ModifySourceFolderErrorReason.NotInWorkspaceFolder return@withContext } if (selectedFolder.path == projectRoot.path) { @@ -1042,7 +921,6 @@ class DocController( logger.info { "Selected correct folder inside workspace: ${selectedFolder.path}" } session.context.selectedSourceFolder = selectedFolder - result = Result.Succeeded promptForDocTarget(tabId) @@ -1050,13 +928,6 @@ class DocController( messenger.sendUpdatePlaceholder(tabId = tabId, newPlaceholder = message("amazonqDoc.prompt.placeholder")) } - - AmazonqTelemetry.modifySourceFolder( - amazonqConversationId = session.conversationId, - credentialStartUrl = getStartUrl(project = context.project), - result = result, - reason = reason?.toString() - ) } private fun sendDocGenerationTelemetry(tabId: String) { @@ -1086,7 +957,5 @@ class DocController( companion object { private val logger = getLogger() - - private val objectMapper = jacksonObjectMapper() } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/DocGenerationState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/DocGenerationState.kt index e08e27be6fd..18851be1376 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/DocGenerationState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/DocGenerationState.kt @@ -30,10 +30,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.Sessio import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.registerDeletedFiles import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.registerNewFiles import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource -import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl import software.aws.toolkits.resources.message -import software.aws.toolkits.telemetry.AmazonqTelemetry -import software.aws.toolkits.telemetry.MetricResult private val logger = getLogger() @@ -43,7 +40,6 @@ class DocGenerationState( val config: SessionStateConfig, val uploadId: String, val currentIteration: Int, - val repositorySize: Double, val messenger: MessagePublisher, var codeGenerationRemainingIterationCount: Int? = null, var codeGenerationTotalIterationCount: Int? = null, @@ -51,12 +47,6 @@ class DocGenerationState( override var token: CancellationTokenSource?, ) : SessionState { override suspend fun interact(action: SessionStateAction): SessionStateInteraction { - val startTime = System.currentTimeMillis() - var result: MetricResult = MetricResult.Succeeded - var failureReason: String? = null - var codeGenerationWorkflowStatus: CodeGenerationWorkflowStatus = CodeGenerationWorkflowStatus.COMPLETE - var numberOfReferencesGenerated: Int? = null - var numberOfFilesGenerated: Int? = null try { val response = config.amazonQCodeGenService.startTaskAssistCodeGeneration( conversationId = config.conversationId, @@ -66,8 +56,6 @@ class DocGenerationState( ) val mode = if (action.msg == message("amazonqDoc.session.create")) Mode.CREATE else null val codeGenerationResult = generateCode(codeGenerationId = response.codeGenerationId(), mode, token) - numberOfReferencesGenerated = codeGenerationResult.references.size - numberOfFilesGenerated = codeGenerationResult.newFiles.size codeGenerationRemainingIterationCount = codeGenerationResult.codeGenerationRemainingIterationCount codeGenerationTotalIterationCount = codeGenerationResult.codeGenerationTotalIterationCount @@ -94,25 +82,7 @@ class DocGenerationState( ) } catch (e: Exception) { logger.warn(e) { "$FEATURE_NAME: Code generation failed: ${e.message}" } - result = MetricResult.Failed - failureReason = e.javaClass.simpleName - codeGenerationWorkflowStatus = CodeGenerationWorkflowStatus.FAILED - throw e - } finally { - AmazonqTelemetry.codeGenerationInvoke( - amazonqConversationId = config.conversationId, - amazonqCodeGenerationResult = codeGenerationWorkflowStatus.toString(), - amazonqGenerateCodeIteration = currentIteration.toDouble(), - amazonqNumberOfReferences = numberOfReferencesGenerated?.toDouble(), - amazonqGenerateCodeResponseLatency = (System.currentTimeMillis() - startTime).toDouble(), - amazonqNumberOfFilesGenerated = numberOfFilesGenerated?.toDouble(), - amazonqRepositorySize = repositorySize, - result = result, - reason = failureReason, - duration = (System.currentTimeMillis() - startTime).toDouble(), - credentialStartUrl = getStartUrl(config.amazonQCodeGenService.project) - ) } } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/PrepareDocGenerationState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/PrepareDocGenerationState.kt index 1949950d237..f9720cd4ce2 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/PrepareDocGenerationState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqDoc/session/PrepareDocGenerationState.kt @@ -17,10 +17,6 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.Sessio import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.deleteUploadArtifact import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.uploadArtifactToS3 -import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl -import software.aws.toolkits.telemetry.AmazonqTelemetry -import software.aws.toolkits.telemetry.AmazonqUploadIntent -import software.aws.toolkits.telemetry.Result private val logger = getLogger() @@ -40,10 +36,6 @@ class PrepareDocGenerationState( ) : SessionState { override val phase = SessionStatePhase.CODEGEN override suspend fun interact(action: SessionStateAction): SessionStateInteraction { - val startTime = System.currentTimeMillis() - var result: Result = Result.Succeeded - var failureReason: String? = null - var failureReasonDesc: String? = null var zipFileLength: Long? = null val nextState: SessionState try { @@ -76,30 +68,14 @@ class PrepareDocGenerationState( config = this.config, uploadId = this.uploadId, currentIteration = this.currentIteration, - repositorySize = zipFileLength.toDouble(), messenger = messenger, phase = phase, token = this.token ) } catch (e: Exception) { - result = Result.Failed - failureReason = e.javaClass.simpleName - failureReasonDesc = e.message logger.warn(e) { "$FEATURE_NAME: Code uploading failed: ${e.message}" } throw e - } finally { - AmazonqTelemetry.createUpload( - amazonqConversationId = config.conversationId, - amazonqRepositorySize = zipFileLength?.toDouble(), - amazonqUploadIntent = AmazonqUploadIntent.TASKASSISTPLANNING, - result = result, - reason = failureReason, - reasonDesc = failureReasonDesc, - duration = (System.currentTimeMillis() - startTime).toDouble(), - credentialStartUrl = getStartUrl(config.amazonQCodeGenService.project) - ) } - // It is essential to interact with the next state outside of try-catch block for the telemetry to capture events for the states separately return nextState.interact(action) } }