Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "bugfix",
"description" : "Amazon Q Feature Dev: Add error messages when the upload URL expires"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "bugfix",
"description" : "Fix inability to sign out in reauth view in Q chat panel"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "feature",
"description" : "Loosen inline completion support limitations for YAML/JSON"
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package software.aws.toolkits.jetbrains.services.amazonq
import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
Expand Down Expand Up @@ -177,13 +178,15 @@ class QWebviewBrowser(val project: Project, private val parentDisposable: Dispos
ToolkitConnectionManager.getInstance(project)
.activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection
)?.let { connection ->
SsoLogoutAction(connection).actionPerformed(
AnActionEvent.createFromDataContext(
"qBrowser",
null,
DataContext.EMPTY_CONTEXT
runInEdt {
SsoLogoutAction(connection).actionPerformed(
AnActionEvent.createFromDataContext(
"qBrowser",
null,
DataContext.EMPTY_CONTEXT
)
)
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@

class MonthlyConversationLimitError(override val message: String, override val cause: Throwable?) : RuntimeException()

class UploadURLExpired(
override val message: String = message(
"amazonqFeatureDev.exception.upload_url_expiry"
),
override val cause: Throwable? = null,
) : FeatureDevException(message, cause)

internal fun featureDevServiceError(message: String?): Nothing =
throw FeatureDevException(message)

Expand All @@ -23,7 +30,7 @@
throw FeatureDevException(message("amazonqFeatureDev.code_generation.failed_generation"))

internal fun uploadCodeError(): Nothing =
throw FeatureDevException(message("amazonqFeatureDev.exception.upload_code"))

Check warning on line 33 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/FeatureDevExceptions.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Usage of redundant or deprecated syntax or deprecated symbols

'message(String, vararg Any): String' is deprecated. Use extension-specific localization bundle instead

internal fun conversationIdNotFound(): Nothing =
throw FeatureDevException(message("amazonqFeatureDev.exception.conversation_not_found"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevExce
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.InboundAppMessagesHandler
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ModifySourceFolderErrorReason
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.MonthlyConversationLimitError
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.UploadURLExpired
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ZipFileError
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.createUserFacingErrorMessage
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.denyListedErrors
Expand Down Expand Up @@ -444,6 +445,12 @@ class FeatureDevController(
messenger.sendMonthlyLimitError(tabId = tabId)
messenger.sendChatInputEnabledMessage(tabId, enabled = false)
}
is UploadURLExpired -> messenger.sendAnswer(
tabId = tabId,
message = err.message,
messageType = FeatureDevMessageType.Answer,
canBeVoted = true
)
is FeatureDevException -> {
messenger.sendError(
tabId = tabId,
Expand Down Expand Up @@ -471,7 +478,6 @@ class FeatureDevController(
),
)
}

else -> {
var msg = createUserFacingErrorMessage("$FEATURE_NAME request failed: ${err.message ?: err.cause?.message}")
val isDenyListedError = denyListedErrors.any { msg?.contains(it) ?: false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.CONTENT_SHA256
import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION
import software.aws.toolkits.jetbrains.services.amazonq.SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FEATURE_NAME
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.UploadURLExpired
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.clients.FeatureDevClient
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.uploadCodeError
import java.io.File
Expand All @@ -36,9 +37,13 @@ fun uploadArtifactToS3(url: String, fileToUpload: File, checksumSha256: String,
connection.setFixedLengthStreamingMode(fileToUpload.length())
IoUtils.copy(fileToUpload.inputStream(), connection.outputStream)
}
} catch (err: Exception) {
} catch (err: HttpRequests.HttpStatusException) {
logger.warn(err) { "$FEATURE_NAME: Failed to upload code to S3" }
uploadCodeError()

when (err.statusCode) {
403 -> throw UploadURLExpired()
else -> uploadCodeError()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
.onStart {
// The first thing we always send back is an AnswerStream message to indicate the beginning of a streaming answer
val response =
ChatMessage(tabId = tabId, triggerId = triggerId, messageId = requestId, messageType = ChatMessageType.AnswerStream, message = "")
ChatMessage(
tabId = tabId,
triggerId = triggerId,
messageId = requestId,
messageType = ChatMessageType.AnswerStream,
message = "",
userIntent = data.userIntent,
)

telemetryHelper.setResponseStreamStartTime(tabId)
emit(response)
Expand All @@ -81,13 +88,20 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
messageType = ChatMessageType.AnswerPart,
message = responseText.toString(),
relatedSuggestions = relatedSuggestions,
userIntent = data.userIntent,
)
emit(suggestionMessage)
}

// Send the Answer message to indicate the end of the response stream
val response =
ChatMessage(tabId = tabId, triggerId = triggerId, messageId = requestId, messageType = ChatMessageType.Answer, followUps = followUps)
val response = ChatMessage(
tabId = tabId,
triggerId = triggerId,
messageId = requestId,
messageType = ChatMessageType.Answer,
followUps = followUps,
userIntent = data.userIntent,
)

telemetryHelper.setResponseStreamTotalTime(tabId)
telemetryHelper.setResponseHasProjectContext(
Expand Down Expand Up @@ -119,11 +133,23 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
}
}
.collect { responseEvent ->
processChatEvent(tabId, triggerId, responseEvent, shouldAddIndexInProgressMessage)?.let { emit(it) }
processChatEvent(
tabId,
triggerId,
data,
responseEvent,
shouldAddIndexInProgressMessage
)?.let { emit(it) }
}
}

private fun processChatEvent(tabId: String, triggerId: String, event: ChatResponseEvent, shouldAddIndexInProgressMessage: Boolean): ChatMessage? {
private fun processChatEvent(
tabId: String,
triggerId: String,
data: ChatRequestData,
event: ChatResponseEvent,
shouldAddIndexInProgressMessage: Boolean,
): ChatMessage? {
requestId = event.requestId
statusCode = event.statusCode

Expand Down Expand Up @@ -190,6 +216,7 @@ class ChatPromptHandler(private val telemetryHelper: TelemetryHelper) {
messageType = ChatMessageType.AnswerPart,
message = message,
codeReference = codeReferences,
userIntent = data.userIntent,
)
} else {
null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ data class ChatMessage(
val followUpsHeader: String? = null,
val relatedSuggestions: List<Suggestion>? = null,
val codeReference: List<CodeReference>? = null,
val userIntent: UserIntent? = null,
) : UiMessage(
tabId = tabId,
type = "chatMessage",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ import com.intellij.openapi.util.TextRange
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.psi.PsiFile
import com.intellij.ui.popup.AbstractPopup
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJson
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererYaml
import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage
import software.aws.toolkits.jetbrains.services.codewhisperer.model.CaretContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.CaretPosition
import software.aws.toolkits.jetbrains.services.codewhisperer.model.FileContextInfo
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.AWSTemplateCaseInsensitiveKeyWordsRegex
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.AWSTemplateKeyWordsRegex
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.JsonConfigFileNamingConvention
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.LEFT_CONTEXT_ON_CURRENT_LINE
import java.awt.Point
import java.util.Locale
Expand Down Expand Up @@ -106,16 +107,12 @@ object CodeWhispererEditorUtil {
}

/**
* Checks if the language is json or yaml and checks if left context contains keywords
* Check if left context contains keywords or file name follow config json file naming pattern
*/
fun checkLeftContextKeywordsForJsonAndYaml(leftContext: String, language: String): Boolean = (
(language == CodeWhispererJson.INSTANCE.languageId) ||
(language == CodeWhispererYaml.INSTANCE.languageId)
) &&
(
(!CodeWhispererConstants.AWSTemplateKeyWordsRegex.containsMatchIn(leftContext)) &&
(!CodeWhispererConstants.AWSTemplateCaseInsensitiveKeyWordsRegex.containsMatchIn(leftContext.lowercase(Locale.getDefault())))
)
fun isSupportedJsonFormat(fileName: String, leftContext: String): Boolean =
JsonConfigFileNamingConvention.contains(fileName.lowercase()) ||
AWSTemplateKeyWordsRegex.containsMatchIn(leftContext) ||
AWSTemplateCaseInsensitiveKeyWordsRegex.containsMatchIn(leftContext.lowercase(Locale.getDefault()))

/**
* Checks if the [otherRange] overlaps this TextRange. Note that the comparison is `<` because the endOffset of TextRange is exclusive.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,31 @@ import com.intellij.psi.PsiFile
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererC
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererCpp
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererCsharp
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererDart
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererGo
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJavaScript
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJson
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJsx
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererKotlin
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererLua
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererPhp
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererPlainText
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererPowershell
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererPython
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererR
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererRuby
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererRust
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererScala
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererShell
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererSql
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererSwift
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererSystemVerilog
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererTf
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererTsx
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererTypeScript
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererVue
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererYaml

@Service
Expand Down Expand Up @@ -73,8 +80,15 @@ class CodeWhispererLanguageManager {
fileTypeName.contains("php") -> CodeWhispererPhp.INSTANCE
fileTypeName.contains("sql") -> CodeWhispererSql.INSTANCE
fileTypeName.contains("go") -> CodeWhispererGo.INSTANCE
fileTypeName.contains("shell") -> CodeWhispererShell.INSTANCE
fileTypeName.contains("rust") -> CodeWhispererRust.INSTANCE
fileTypeName.contains("swift") -> CodeWhispererSwift.INSTANCE
fileTypeName.contains("lua") -> CodeWhispererLua.INSTANCE
fileTypeName.contains("dart") -> CodeWhispererDart.INSTANCE
fileTypeName.contains("vue") -> CodeWhispererVue.INSTANCE
fileTypeName.contains("systemverilog") -> CodeWhispererSystemVerilog.INSTANCE
fileTypeName.contains("powershell") -> CodeWhispererPowershell.INSTANCE
fileTypeName.contains("shell") -> CodeWhispererShell.INSTANCE
fileTypeName == "r" -> CodeWhispererR.INSTANCE
// fileTypeName.contains("plain_text") -> CodeWhispererPlainText.INSTANCE // This needs to be removed because Hcl files are recognised as plain_text by JB
else -> null
}
Expand Down Expand Up @@ -125,7 +139,14 @@ class CodeWhispererLanguageManager {
listOf("go") to CodeWhispererGo.INSTANCE,
listOf("php") to CodeWhispererPhp.INSTANCE,
listOf("sql") to CodeWhispererSql.INSTANCE,
listOf("txt") to CodeWhispererPlainText.INSTANCE
listOf("txt") to CodeWhispererPlainText.INSTANCE,
listOf("sv", "svh", "vh") to CodeWhispererSystemVerilog.INSTANCE,
listOf("dart") to CodeWhispererDart.INSTANCE,
listOf("lua", "wlua") to CodeWhispererLua.INSTANCE,
listOf("swift") to CodeWhispererSwift.INSTANCE,
listOf("vue") to CodeWhispererVue.INSTANCE,
listOf("ps1", "psm1") to CodeWhispererPowershell.INSTANCE,
listOf("r") to CodeWhispererR.INSTANCE,
).map {
val exts = it.first
val lang = it.second
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.language.languages

import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
import software.aws.toolkits.telemetry.CodewhispererLanguage

class CodeWhispererDart private constructor() : CodeWhispererProgrammingLanguage() {

Check warning on line 9 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererDart.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Extension class should be final and non-public

Extension class should not be public
override val languageId: String = ID

override fun toTelemetryType(): CodewhispererLanguage = CodewhispererLanguage.Dart

override fun isCodeCompletionSupported(): Boolean = true

companion object {

Check warning on line 16 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererDart.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Companion object in extensions

Companion objects in IDE extension implementations may only contain a logger and constants
// TODO: confirm with service team language id
const val ID = "dart"

val INSTANCE = CodeWhispererDart()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.language.languages

import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
import software.aws.toolkits.telemetry.CodewhispererLanguage

class CodeWhispererLua private constructor() : CodeWhispererProgrammingLanguage() {

Check warning on line 9 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererLua.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Extension class should be final and non-public

Extension class should not be public
override val languageId: String = ID

override fun toTelemetryType(): CodewhispererLanguage = CodewhispererLanguage.Lua

override fun isCodeCompletionSupported(): Boolean = true

companion object {

Check warning on line 16 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererLua.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Companion object in extensions

Companion objects in IDE extension implementations may only contain a logger and constants
// TODO: confirm with service team language id
const val ID = "lua"

val INSTANCE = CodeWhispererLua()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.language.languages

import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
import software.aws.toolkits.telemetry.CodewhispererLanguage

class CodeWhispererPowershell private constructor() : CodeWhispererProgrammingLanguage() {

Check warning on line 9 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererPowershell.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Extension class should be final and non-public

Extension class should not be public
override val languageId: String = ID

override fun toTelemetryType(): CodewhispererLanguage = CodewhispererLanguage.Powershell

override fun isCodeCompletionSupported(): Boolean = true

companion object {

Check warning on line 16 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererPowershell.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Companion object in extensions

Companion objects in IDE extension implementations may only contain a logger and constants
// TODO: confirm with service team language id
const val ID = "powershell"

val INSTANCE = CodeWhispererPowershell()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.language.languages

import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage
import software.aws.toolkits.telemetry.CodewhispererLanguage

class CodeWhispererR private constructor() : CodeWhispererProgrammingLanguage() {

Check warning on line 9 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererR.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Extension class should be final and non-public

Extension class should not be public
override val languageId: String = ID

override fun toTelemetryType(): CodewhispererLanguage = CodewhispererLanguage.R

override fun isCodeCompletionSupported(): Boolean = true

companion object {

Check warning on line 16 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/language/languages/CodeWhispererR.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Companion object in extensions

Companion objects in IDE extension implementations may only contain a logger and constants
// TODO: confirm with service team language id
const val ID = "r"

val INSTANCE = CodeWhispererR()
}
}
Loading
Loading