Skip to content
Merged
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
Expand Up @@ -22,7 +22,6 @@ import software.amazon.awssdk.services.codewhispererruntime.model.GetCodeFixJobR
import software.amazon.awssdk.services.codewhispererruntime.model.GetTestGenerationResponse
import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory
import software.amazon.awssdk.services.codewhispererruntime.model.InlineChatUserDecision
import software.amazon.awssdk.services.codewhispererruntime.model.ListAvailableCustomizationsRequest
import software.amazon.awssdk.services.codewhispererruntime.model.ListCodeAnalysisFindingsRequest
import software.amazon.awssdk.services.codewhispererruntime.model.ListCodeAnalysisFindingsResponse
import software.amazon.awssdk.services.codewhispererruntime.model.ListFeatureEvaluationsResponse
Expand All @@ -35,8 +34,6 @@ import software.amazon.awssdk.services.codewhispererruntime.model.StartTestGener
import software.amazon.awssdk.services.codewhispererruntime.model.SuggestionState
import software.amazon.awssdk.services.codewhispererruntime.model.TargetCode
import software.amazon.awssdk.services.codewhispererruntime.model.UserIntent
import software.aws.toolkits.core.utils.debug
import software.aws.toolkits.core.utils.getLogger
import software.aws.toolkits.jetbrains.services.amazonq.codeWhispererUserContext
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager
import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization
Expand Down Expand Up @@ -78,8 +75,6 @@ interface CodeWhispererClientAdaptor {

fun getCodeFixJob(request: GetCodeFixJobRequest): GetCodeFixJobResponse

fun listAvailableCustomizations(): List<CodeWhispererCustomization>

fun startTestGeneration(uploadId: String, targetCode: List<TargetCode>, userInput: String): StartTestGenerationResponse

fun getTestGeneration(jobId: String, jobGroupName: String): GetTestGenerationResponse
Expand Down Expand Up @@ -281,28 +276,6 @@ open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeW

override fun getCodeFixJob(request: GetCodeFixJobRequest): GetCodeFixJobResponse = bearerClient().getCodeFixJob(request)

// DO NOT directly use this method to fetch customizations, use wrapper [CodeWhispererModelConfigurator.listCustomization()] instead
override fun listAvailableCustomizations(): List<CodeWhispererCustomization> =
bearerClient().listAvailableCustomizationsPaginator(
ListAvailableCustomizationsRequest.builder().profileArn(QRegionProfileManager.getInstance().activeProfile(project)?.arn).build()
)
.stream()
.toList()
.flatMap { resp ->
LOG.debug {
"listAvailableCustomizations: requestId: ${resp.responseMetadata().requestId()}, customizations: ${
resp.customizations().map { it.name() }
}"
}
resp.customizations().map {
CodeWhispererCustomization(
arn = it.arn(),
name = it.name(),
description = it.description()
)
}
}

override fun startTestGeneration(uploadId: String, targetCode: List<TargetCode>, userInput: String): StartTestGenerationResponse =
bearerClient().startTestGeneration { builder ->
builder.uploadId(uploadId)
Expand Down Expand Up @@ -799,10 +772,6 @@ open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeW
requestBuilder.userContext(codeWhispererUserContext())
requestBuilder.profileArn(QRegionProfileManager.getInstance().activeProfile(project)?.arn)
}

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

private fun CodewhispererSuggestionState.toCodeWhispererSdkType() = when {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhisperer
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getTelemetryOptOutPreference
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.notifyErrorCodeWhispererUsageLimit
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.promptReAuth
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CustomizationConstants
import software.aws.toolkits.jetbrains.services.codewhisperer.util.FileContextProvider
import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings
import software.aws.toolkits.jetbrains.utils.isInjectedText
Expand Down Expand Up @@ -333,7 +334,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable {
val displayMessage: String

if (
CodeWhispererConstants.Customization.invalidCustomizationExceptionPredicate(e) ||
CustomizationConstants.invalidCustomizationExceptionPredicate(e) ||
e is ResourceNotFoundException
) {
(e as CodeWhispererRuntimeException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhisperer
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getTelemetryOptOutPreference
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.notifyErrorCodeWhispererUsageLimit
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.promptReAuth
import software.aws.toolkits.jetbrains.services.codewhisperer.util.CustomizationConstants
import software.aws.toolkits.jetbrains.services.codewhisperer.util.FileContextProvider
import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings
import software.aws.toolkits.jetbrains.utils.isInjectedText
Expand Down Expand Up @@ -360,7 +361,7 @@ class CodeWhispererServiceNew(private val cs: CoroutineScope) : Disposable {
val displayMessage: String

if (
CodeWhispererConstants.Customization.invalidCustomizationExceptionPredicate(e) ||
CustomizationConstants.invalidCustomizationExceptionPredicate(e) ||
e is ResourceNotFoundException
) {
(e as CodeWhispererRuntimeException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.intellij.openapi.options.SearchableConfigurable
import com.intellij.openapi.options.ex.Settings
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.ui.emptyText
import com.intellij.ui.components.ActionLink
import com.intellij.ui.components.fields.ExpandableTextField
Expand All @@ -23,6 +24,7 @@
import com.intellij.util.execution.ParametersListUtil
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManagerListener
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererLoginType
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isCodeWhispererEnabled
Expand Down Expand Up @@ -284,6 +286,20 @@
}
}
}
}.also {
val newCallbacks = it.applyCallbacks.toMutableMap()
.also { map ->
val list = map.getOrPut(null) { mutableListOf() } as MutableList<() -> Unit>
list.add {
ProjectManager.getInstance().openProjects.forEach { project ->

Check warning on line 294 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt#L289-L294

Added lines #L289 - L294 were not covered by tests
if (project.isDisposed) {
return@forEach

Check warning on line 296 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt#L296

Added line #L296 was not covered by tests
}
AmazonQLspService.didChangeConfiguration(project)
}
}
}
it.applyCallbacks = newCallbacks

Check warning on line 302 in plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt

View check run for this annotation

Codecov / codecov/patch

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt#L298-L302

Added lines #L298 - L302 were not covered by tests
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import com.intellij.openapi.editor.markup.EffectType
import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.ui.JBColor
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.codewhispererruntime.model.AccessDeniedException
import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeScanResponse
import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava
import software.aws.toolkits.telemetry.CodewhispererGettingStartedTask
Expand Down Expand Up @@ -59,7 +57,6 @@ object CodeWhispererConstants {
val scanResultsKey = DataKey.create<CodeScanResponse>("amazonq.codescan.result")
val scanScopeKey = DataKey.create<CodeAnalysisScope>("amazonq.codescan.scope")

const val Q_CUSTOM_LEARN_MORE_URI = "https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/customizations.html"
const val Q_SUPPORTED_LANG_URI = "https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/q-language-ide-support.html"
const val CODEWHISPERER_CODE_SCAN_LEARN_MORE_URI = "https://docs.aws.amazon.com/codewhisperer/latest/userguide/security-scans.html"
const val CODEWHISPERER_ONBOARDING_DOCUMENTATION_URI = "https://docs.aws.amazon.com/codewhisperer/latest/userguide/features.html"
Expand Down Expand Up @@ -157,27 +154,6 @@ object CodeWhispererConstants {
val Sigv4ClientRegion = Region.US_EAST_1
}

object Customization {
private const val noAccessToCustomizationMessage = "Your account is not authorized to use CodeWhisperer Enterprise."
private const val invalidCustomizationMessage = "You are not authorized to access"

val noAccessToCustomizationExceptionPredicate: (e: Exception) -> Boolean = { e ->
if (e !is CodeWhispererRuntimeException) {
false
} else {
e is AccessDeniedException && (e.message?.contains(noAccessToCustomizationMessage, ignoreCase = true) ?: false)
}
}

val invalidCustomizationExceptionPredicate: (e: Exception) -> Boolean = { e ->
if (e !is CodeWhispererRuntimeException) {
false
} else {
e is AccessDeniedException && (e.message?.contains(invalidCustomizationMessage, ignoreCase = true) ?: false)
}
}
}

object CrossFile {
const val CHUNK_SIZE = 60
const val NUMBER_OF_LINE_IN_CHUNK = 50
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@ import software.amazon.awssdk.services.codewhispererruntime.model.CodeAnalysisSt
import software.amazon.awssdk.services.codewhispererruntime.model.CompletionType
import software.amazon.awssdk.services.codewhispererruntime.model.CreateUploadUrlRequest
import software.amazon.awssdk.services.codewhispererruntime.model.CreateUploadUrlResponse
import software.amazon.awssdk.services.codewhispererruntime.model.Customization
import software.amazon.awssdk.services.codewhispererruntime.model.GenerateCompletionsRequest
import software.amazon.awssdk.services.codewhispererruntime.model.GetCodeAnalysisRequest
import software.amazon.awssdk.services.codewhispererruntime.model.GetCodeAnalysisResponse
import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory
import software.amazon.awssdk.services.codewhispererruntime.model.ListAvailableCustomizationsRequest
import software.amazon.awssdk.services.codewhispererruntime.model.ListAvailableCustomizationsResponse
import software.amazon.awssdk.services.codewhispererruntime.model.ListCodeAnalysisFindingsRequest
import software.amazon.awssdk.services.codewhispererruntime.model.ListCodeAnalysisFindingsResponse
import software.amazon.awssdk.services.codewhispererruntime.model.ListFeatureEvaluationsRequest
Expand All @@ -51,7 +48,6 @@ import software.amazon.awssdk.services.codewhispererruntime.model.StartCodeAnaly
import software.amazon.awssdk.services.codewhispererruntime.model.StartCodeAnalysisResponse
import software.amazon.awssdk.services.codewhispererruntime.model.SuggestionState
import software.amazon.awssdk.services.codewhispererruntime.paginators.GenerateCompletionsIterable
import software.amazon.awssdk.services.codewhispererruntime.paginators.ListAvailableCustomizationsIterable
import software.amazon.awssdk.services.ssooidc.SsoOidcClient
import software.aws.toolkits.core.utils.test.aString
import software.aws.toolkits.jetbrains.core.MockClientManagerRule
Expand Down Expand Up @@ -158,48 +154,6 @@ class CodeWhispererClientAdaptorTest {
.isInstanceOf(CodeWhispererRuntimeClient::class.java)
}

@Test
fun `listCustomizations`() {
val sdkIterable = ListAvailableCustomizationsIterable(bearerClient, ListAvailableCustomizationsRequest.builder().build())
val mockResponse1 = ListAvailableCustomizationsResponse.builder()
.customizations(
listOf(
Customization.builder().name("custom-1").arn("arn-1").build(),
Customization.builder().name("custom-2").arn("arn-2").build()
)
)
.nextToken("token-1")
.responseMetadata(metadata)
.sdkHttpResponse(sdkHttpResponse)
.build() as ListAvailableCustomizationsResponse

val mockResponse2 = ListAvailableCustomizationsResponse.builder()
.customizations(
listOf(
Customization.builder().name("custom-3").arn("arn-3").build(),
)
)
.nextToken("")
.responseMetadata(metadata)
.sdkHttpResponse(sdkHttpResponse)
.build() as ListAvailableCustomizationsResponse

bearerClient.stub { client ->
on { client.listAvailableCustomizations(any<ListAvailableCustomizationsRequest>()) } doReturnConsecutively listOf(mockResponse1, mockResponse2)
on { client.listAvailableCustomizationsPaginator(any<ListAvailableCustomizationsRequest>()) } doReturn sdkIterable
}

val actual = sut.listAvailableCustomizations()
assertThat(actual).hasSize(3)
assertThat(actual).isEqualTo(
listOf(
CodeWhispererCustomization(name = "custom-1", arn = "arn-1"),
CodeWhispererCustomization(name = "custom-2", arn = "arn-2"),
CodeWhispererCustomization(name = "custom-3", arn = "arn-3")
)
)
}

@Test
fun `generateCompletionsPaginator - bearer`() {
val request = pythonRequest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class CodeWhispererModelConfiguratorTest {
"</option>" +
"</component>"

assertThat(actual).isEqualTo(expected)
assertThat(actual).isEqualToIgnoringWhitespace(expected)
}

@Test
Expand Down Expand Up @@ -574,11 +574,6 @@ class CodeWhispererModelConfiguratorTest {

assertThat(sut.activeCustomization(projectRule.project)).isEqualTo(oldCustomization)

val fakeCustomizations = listOf(
CodeWhispererCustomization("oldArn", "oldName", "oldDescription")
)
mockClintAdaptor.stub { on { listAvailableCustomizations() } doReturn fakeCustomizations }

ApplicationManager.getApplication().messageBus
.syncPublisher(QRegionProfileSelectedListener.TOPIC)
.onProfileSelected(projectRule.project, null)
Expand All @@ -593,10 +588,6 @@ class CodeWhispererModelConfiguratorTest {
val oldCustomization = CodeWhispererCustomization("oldArn", "oldName", "oldDescription")
sut.switchCustomization(projectRule.project, oldCustomization)
assertThat(sut.activeCustomization(projectRule.project)).isEqualTo(oldCustomization)
val fakeCustomizations = listOf(
CodeWhispererCustomization("newArn", "newName", "newDescription")
)
mockClintAdaptor.stub { on { listAvailableCustomizations() } doReturn fakeCustomizations }

val latch = CountDownLatch(1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ import com.intellij.openapi.wm.impl.status.widget.StatusBarWidgetsManager
import com.intellij.testFramework.replaceService
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.xmlb.XmlSerializer
import io.mockk.every
import io.mockk.junit4.MockKRule
import io.mockk.mockkObject
import org.assertj.core.api.Assertions.assertThat
import org.jdom.output.XMLOutputter
import org.junit.Before
Expand All @@ -28,7 +26,6 @@ import org.mockito.kotlin.spy
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import software.aws.toolkits.jetbrains.core.ToolWindowHeadlessManagerImpl
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererLoginType
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExploreActionState
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isCodeWhispererEnabled
Expand Down Expand Up @@ -254,18 +251,6 @@ class CodeWhispererSettingsTest : CodeWhispererTestBase() {
assertThat(sut.getProjectContextIndexMaxSize()).isEqualTo(expected)
}
}

@Test
fun `toggleMetricOptIn should trigger LSP didChangeConfiguration`() {
mockkObject(AmazonQLspService)
every { AmazonQLspService.didChangeConfiguration(any()) } returns Unit
settingsManager.toggleMetricOptIn(true)
settingsManager.toggleMetricOptIn(false)

io.mockk.verify(atLeast = 2) {
AmazonQLspService.didChangeConfiguration(any())
}
}
}

class CodeWhispererSettingUnitTest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package migration.software.aws.toolkits.jetbrains.services.codewhisperer.customization
Expand Down
Loading
Loading