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 + d3ba908 commit f7cde37
Show file tree
Hide file tree
Showing 163 changed files with 13,016 additions and 901 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "feature",
"description" : "`/review` in Q chat to scan your code for vulnerabilities and quality issues, and generate fixes"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "feature",
"description" : "`/test` in Q chat to generate unit tests for java and python"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type" : "feature",
"description" : "`/doc` in Q chat to generate and update documentation for your project"
}
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>
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/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 f7cde37

Please sign in to comment.