Skip to content

Commit

Permalink
Merge main into feature/q-inlinechat
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-toolkit-automation authored Dec 3, 2024
2 parents e31e7bb + 81cb27e commit 4198126
Show file tree
Hide file tree
Showing 164 changed files with 13,028 additions and 906 deletions.
17 changes: 17 additions & 0 deletions .changes/3.43.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"date" : "2024-12-03",
"version" : "3.43",
"entries" : [ {
"type" : "feature",
"description" : "`/review` in Q chat to scan your code for vulnerabilities and quality issues, and generate fixes"
}, {
"type" : "feature",
"description" : "`/test` in Q chat to generate unit tests for java and python"
}, {
"type" : "feature",
"description" : "`/doc` in Q chat to generate and update documentation for your project"
}, {
"type" : "feature",
"description" : "Added system notifications to inform users about critical plugin updates and potential issues with available workarounds"
} ]
}

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion .run/Run Amazon Q - Ultimate [2024.1].run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
<RunAsTest>false</RunAsTest>
<method v="2" />
</configuration>
</component>
</component>
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# _3.43_ (2024-12-03)
- **(Feature)** `/review` in Q chat to scan your code for vulnerabilities and quality issues, and generate fixes
- **(Feature)** `/test` in Q chat to generate unit tests for java and python
- **(Feature)** `/doc` in Q chat to generate and update documentation for your project
- **(Feature)** Added system notifications to inform users about critical plugin updates and potential issues with available workarounds

# _3.42_ (2024-11-27)
- **(Feature)** Amazon Q /dev: support `Dockerfile` files
- **(Feature)** Feature(Amazon Q Code Transformation): allow users to view results in 5 smaller diffs
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/toolkit-generate-sdks.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ java {

tasks.withType<JavaCompile>().configureEach {
options.encoding = "UTF-8"
sourceCompatibility = "17"
targetCompatibility = "17"
}

val generateTask = tasks.register<GenerateSdk>("generateSdks")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0

# Toolkit Version
toolkitVersion=3.43-SNAPSHOT
toolkitVersion=3.44-SNAPSHOT

# Publish Settings
publishToken=
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mockitoKotlin = "5.4.0"
mockk = "1.13.10"
nimbus-jose-jwt = "9.40"
node-gradle = "7.0.2"
telemetryGenerator = "1.0.278"
telemetryGenerator = "1.0.284"
testLogger = "4.0.0"
testRetry = "1.5.10"
# test-only; platform provides slf4j transitively at runtime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
<extensions defaultExtensionNs="amazon.q">
<appFactory implementation="software.aws.toolkits.jetbrains.services.cwc.AppFactory" />
<appFactory implementation="software.aws.toolkits.jetbrains.services.amazonqFeatureDev.FeatureDevAppFactory" />
<appFactory implementation="software.aws.toolkits.jetbrains.services.amazonqDoc.DocAppFactory" />
<appFactory implementation="software.aws.toolkits.jetbrains.services.amazonqCodeScan.CodeScanChatAppFactory" />
<appFactory implementation="software.aws.toolkits.jetbrains.services.amazonqCodeTest.CodeTestChatAppFactory" />
</extensions>

<actions>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.common.clients

import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SystemInfo
import software.amazon.awssdk.services.codewhispererruntime.CodeWhispererRuntimeClient
import software.amazon.awssdk.services.codewhispererruntime.model.ArtifactType
import software.amazon.awssdk.services.codewhispererruntime.model.ContentChecksumType
import software.amazon.awssdk.services.codewhispererruntime.model.CreateTaskAssistConversationRequest
import software.amazon.awssdk.services.codewhispererruntime.model.CreateTaskAssistConversationResponse
import software.amazon.awssdk.services.codewhispererruntime.model.CreateUploadUrlResponse
import software.amazon.awssdk.services.codewhispererruntime.model.DocGenerationEvent
import software.amazon.awssdk.services.codewhispererruntime.model.GetTaskAssistCodeGenerationResponse
import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory
import software.amazon.awssdk.services.codewhispererruntime.model.OperatingSystem
import software.amazon.awssdk.services.codewhispererruntime.model.OptOutPreference
import software.amazon.awssdk.services.codewhispererruntime.model.SendTelemetryEventResponse
import software.amazon.awssdk.services.codewhispererruntime.model.StartTaskAssistCodeGenerationResponse
import software.amazon.awssdk.services.codewhispererruntime.model.TaskAssistPlanningUploadContext
import software.amazon.awssdk.services.codewhispererruntime.model.UploadContext
import software.amazon.awssdk.services.codewhispererruntime.model.UploadIntent
import software.amazon.awssdk.services.codewhispererruntime.model.UserContext
import software.amazon.awssdk.services.codewhispererstreaming.model.ExportIntent
import software.aws.toolkits.core.utils.error
import software.aws.toolkits.core.utils.getLogger
import software.aws.toolkits.core.utils.info
import software.aws.toolkits.jetbrains.common.session.Intent
import software.aws.toolkits.jetbrains.core.awsClient
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
import software.aws.toolkits.jetbrains.services.amazonq.clients.AmazonQStreamingClient
import software.aws.toolkits.jetbrains.services.amazonqDoc.FEATURE_EVALUATION_PRODUCT_NAME
import software.aws.toolkits.jetbrains.services.codemodernizer.utils.calculateTotalLatency
import software.aws.toolkits.jetbrains.services.telemetry.ClientMetadata
import software.aws.toolkits.jetbrains.settings.AwsSettings
import java.time.Instant
import software.amazon.awssdk.services.codewhispererruntime.model.ChatTriggerType as SyncChatTriggerType

@Service(Service.Level.PROJECT)
class AmazonQCodeGenerateClient(private val project: Project) {
private fun getTelemetryOptOutPreference() =
if (AwsSettings.getInstance().isTelemetryEnabled) {
OptOutPreference.OPTIN
} else {
OptOutPreference.OPTOUT
}

private val docGenerationUserContext = ClientMetadata.getDefault().let {
val osForFeatureDev: OperatingSystem =
when {
SystemInfo.isWindows -> OperatingSystem.WINDOWS
SystemInfo.isMac -> OperatingSystem.MAC
// For now, categorize everything else as "Linux" (Linux/FreeBSD/Solaris/etc.)
else -> OperatingSystem.LINUX
}

UserContext.builder()
.ideCategory(IdeCategory.JETBRAINS)
.operatingSystem(osForFeatureDev)
.product(FEATURE_EVALUATION_PRODUCT_NAME)
.clientId(it.clientId)
.ideVersion(it.awsVersion)
.build()
}

fun connection() = ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(QConnection.getInstance())
?: error("Attempted to use connection while one does not exist")

fun bearerClient() = connection().getConnectionSettings().awsClient<CodeWhispererRuntimeClient>()

private val amazonQStreamingClient
get() = AmazonQStreamingClient.getInstance(project)

fun sendDocGenerationTelemetryEvent(
docGenerationEvent: DocGenerationEvent,
): SendTelemetryEventResponse =
bearerClient().sendTelemetryEvent { requestBuilder ->
requestBuilder.telemetryEvent { telemetryEventBuilder ->
telemetryEventBuilder.docGenerationEvent(docGenerationEvent)
}
requestBuilder.optOutPreference(getTelemetryOptOutPreference())
requestBuilder.userContext(docGenerationUserContext)
}

fun createTaskAssistConversation(): CreateTaskAssistConversationResponse = bearerClient().createTaskAssistConversation(
CreateTaskAssistConversationRequest.builder().build()
)

fun createTaskAssistUploadUrl(conversationId: String, contentChecksumSha256: String, contentLength: Long): CreateUploadUrlResponse =
bearerClient().createUploadUrl {
it.contentChecksumType(ContentChecksumType.SHA_256)
.contentChecksum(contentChecksumSha256)
.contentLength(contentLength)
.artifactType(ArtifactType.SOURCE_CODE)
.uploadIntent(UploadIntent.TASK_ASSIST_PLANNING)
.uploadContext(
UploadContext.builder()
.taskAssistPlanningUploadContext(
TaskAssistPlanningUploadContext.builder()
.conversationId(conversationId)
.build()
)
.build()
)
}

fun startTaskAssistCodeGeneration(conversationId: String, uploadId: String, userMessage: String, intent: Intent): StartTaskAssistCodeGenerationResponse =
bearerClient()
.startTaskAssistCodeGeneration { request ->
request
.conversationState {
it
.conversationId(conversationId)
.chatTriggerType(SyncChatTriggerType.MANUAL)
.currentMessage { cm -> cm.userInputMessage { um -> um.content(userMessage) } }
}
.workspaceState {
it
.programmingLanguage { pl -> pl.languageName("javascript") }
.uploadId(uploadId)
}
.intent(intent.name)
}

fun getTaskAssistCodeGeneration(conversationId: String, codeGenerationId: String): GetTaskAssistCodeGenerationResponse = bearerClient()
.getTaskAssistCodeGeneration {
it
.conversationId(conversationId)
.codeGenerationId(codeGenerationId)
}

suspend fun exportTaskAssistResultArchive(conversationId: String): MutableList<ByteArray> = amazonQStreamingClient.exportResultArchive(
conversationId,
ExportIntent.TASK_ASSIST,
null,
{ e ->
LOG.error(e) { "TaskAssist - ExportResultArchive stream exportId=$conversationId exportIntent=${ExportIntent.TASK_ASSIST} Failed: ${e.message} " }
},
{ startTime ->
LOG.info { "TaskAssist - ExportResultArchive latency: ${calculateTotalLatency(startTime, Instant.now())}" }
}
)

companion object {
private val LOG = getLogger<AmazonQCodeGenerateClient>()

fun getInstance(project: Project) = project.service<AmazonQCodeGenerateClient>()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.common.session

import software.aws.toolkits.jetbrains.services.amazonqDoc.session.SessionStateInteraction
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.SessionStateAction
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.SessionStatePhase
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource

class ConversationNotStartedState(
override var approach: String,
override val tabID: String,
override var token: CancellationTokenSource?,
) : SessionState {
override val phase = SessionStatePhase.INIT

override suspend fun interact(action: SessionStateAction): SessionStateInteraction<SessionState> {
error("Illegal transition between states, restart the conversation")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.common.session

import software.aws.toolkits.jetbrains.services.amazonqDoc.session.SessionStateInteraction
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.SessionStateAction
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.SessionStatePhase
import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource

interface SessionState {
val tabID: String
val phase: SessionStatePhase?
var token: CancellationTokenSource?
var approach: String
suspend fun interact(action: SessionStateAction): SessionStateInteraction<SessionState>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.common.session

import software.aws.toolkits.jetbrains.common.util.AmazonQCodeGenService
import software.aws.toolkits.jetbrains.services.amazonq.FeatureDevSessionContext

open class SessionStateConfig(
open val conversationId: String,
open val repoContext: FeatureDevSessionContext,
open val amazonQCodeGenService: AmazonQCodeGenService,
)

data class SessionStateConfigData(
override val conversationId: String,
override val repoContext: FeatureDevSessionContext,
override val amazonQCodeGenService: AmazonQCodeGenService,
) : SessionStateConfig(conversationId, repoContext, amazonQCodeGenService)

enum class Intent {
DEV,
DOC,
}
Loading

0 comments on commit 4198126

Please sign in to comment.