diff --git a/plugins/amazonq/chat/jetbrains-community/build.gradle.kts b/plugins/amazonq/chat/jetbrains-community/build.gradle.kts index 1df61f69fe2..daf5d50d116 100644 --- a/plugins/amazonq/chat/jetbrains-community/build.gradle.kts +++ b/plugins/amazonq/chat/jetbrains-community/build.gradle.kts @@ -19,7 +19,6 @@ dependencies { implementation(project(":plugin-amazonq:shared:jetbrains-community")) // everything references codewhisperer, which is not ideal implementation(project(":plugin-amazonq:codewhisperer:jetbrains-community")) - implementation(libs.nimbus.jose.jwt) compileOnly(project(":plugin-core:jetbrains-community")) diff --git a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml index daec47d1094..6aaea05a6c6 100644 --- a/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml +++ b/plugins/amazonq/chat/jetbrains-community/resources/META-INF/plugin-chat.xml @@ -8,7 +8,7 @@ - diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/startup/AmazonQStartupActivity.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/startup/AmazonQStartupActivity.kt index 5dfb0b0cf62..1a66c5198e2 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/startup/AmazonQStartupActivity.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/startup/AmazonQStartupActivity.kt @@ -14,11 +14,10 @@ import kotlinx.coroutines.time.withTimeout import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.core.gettingstarted.emitUserState +import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextController import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AmazonQToolWindow import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AmazonQToolWindowFactory import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.ProjectContextController import java.lang.management.ManagementFactory import java.time.Duration import java.util.concurrent.atomic.AtomicBoolean @@ -47,26 +46,24 @@ class AmazonQStartupActivity : ProjectActivity { // Automatically start the project context LSP after some delay when average CPU load is below 30%. // The CPU load requirement is to avoid competing with native JetBrains indexing and other CPU expensive OS processes // In the future we will decouple LSP start and indexing start to let LSP perform other tasks. - if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { - val startLspIndexingDuration = Duration.ofMinutes(30) - project.waitForSmartMode() - try { - withTimeout(startLspIndexingDuration) { - while (true) { - val cpuUsage = ManagementFactory.getOperatingSystemMXBean().systemLoadAverage - if (cpuUsage > 0 && cpuUsage < 30) { - ProjectContextController.getInstance(project = project) - break - } else { - delay(60_000) // Wait for 60 seconds - } + val startLspIndexingDuration = Duration.ofMinutes(30) + project.waitForSmartMode() + try { + withTimeout(startLspIndexingDuration) { + while (true) { + val cpuUsage = ManagementFactory.getOperatingSystemMXBean().systemLoadAverage + if (cpuUsage > 0 && cpuUsage < 30) { + ProjectContextController.getInstance(project = project) + break + } else { + delay(60_000) // Wait for 60 seconds } } - } catch (e: TimeoutCancellationException) { - LOG.warn { "Failed to start LSP server due to time out" } - } catch (e: Exception) { - LOG.warn { "Failed to start LSP server" } } + } catch (e: TimeoutCancellationException) { + LOG.warn { "Failed to start LSP server due to time out" } + } catch (e: Exception) { + LOG.warn { "Failed to start LSP server" } } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/model/Requests.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/model/Requests.kt index 0813d80db11..ad81832d749 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/model/Requests.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/model/Requests.kt @@ -5,9 +5,9 @@ package software.aws.toolkits.jetbrains.services.cwc.clients.chat.model import com.fasterxml.jackson.annotation.JsonProperty import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization +import software.aws.toolkits.jetbrains.services.amazonq.project.RelevantDocument import software.aws.toolkits.jetbrains.services.cwc.editor.context.ActiveFileContext -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.RelevantDocument enum class TriggerType { Click, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt index a5057f797c8..8da68f5dea2 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/clients/chat/v1/ChatSessionV1.kt @@ -40,6 +40,7 @@ import software.aws.toolkits.jetbrains.core.AwsClientManager import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineBgContext import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection +import software.aws.toolkits.jetbrains.services.amazonq.project.RelevantDocument import software.aws.toolkits.jetbrains.services.cwc.ChatConstants import software.aws.toolkits.jetbrains.services.cwc.clients.chat.ChatSession import software.aws.toolkits.jetbrains.services.cwc.clients.chat.exceptions.ChatApiException @@ -51,7 +52,6 @@ import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.Reference import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.SuggestedFollowUp import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.Suggestion import software.aws.toolkits.jetbrains.services.cwc.editor.context.ActiveFileContext -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.RelevantDocument class ChatSessionV1( private val project: Project, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt index 2513bb5d4c6..de1309cc2ee 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/ChatController.kt @@ -36,15 +36,16 @@ import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.core.coroutines.EDT +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext import software.aws.toolkits.jetbrains.services.amazonq.auth.AuthController import software.aws.toolkits.jetbrains.services.amazonq.auth.AuthNeededState import software.aws.toolkits.jetbrains.services.amazonq.messages.MessagePublisher import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteraction import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteractionType -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextController +import software.aws.toolkits.jetbrains.services.amazonq.project.RelevantDocument import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererConfigurable -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhispererUserModificationTracker import software.aws.toolkits.jetbrains.services.cwc.InboundAppMessagesHandler import software.aws.toolkits.jetbrains.services.cwc.clients.chat.exceptions.ChatApiException @@ -65,8 +66,6 @@ import software.aws.toolkits.jetbrains.services.cwc.controller.chat.userIntent.U import software.aws.toolkits.jetbrains.services.cwc.editor.context.ActiveFileContext import software.aws.toolkits.jetbrains.services.cwc.editor.context.ActiveFileContextExtractor import software.aws.toolkits.jetbrains.services.cwc.editor.context.ExtractionTriggerType -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.ProjectContextController -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.RelevantDocument import software.aws.toolkits.jetbrains.services.cwc.messages.AuthNeededException import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessage import software.aws.toolkits.jetbrains.services.cwc.messages.ChatMessageType @@ -79,6 +78,7 @@ import software.aws.toolkits.jetbrains.services.cwc.messages.OnboardingPageInter import software.aws.toolkits.jetbrains.services.cwc.messages.OpenSettingsMessage import software.aws.toolkits.jetbrains.services.cwc.messages.QuickActionMessage import software.aws.toolkits.jetbrains.services.cwc.storage.ChatSessionStorage +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.telemetry.CwsprChatCommandType import java.time.Instant import java.util.UUID @@ -137,7 +137,7 @@ class ChatController private constructor( shouldUseWorkspaceContext = true prompt = prompt.replace("@workspace", "") val projectContextController = ProjectContextController.getInstance(context.project) - queryResult = projectContextController.query(prompt) + queryResult = projectContextController.queryChat(prompt) if (!projectContextController.getProjectContextIndexComplete()) shouldAddIndexInProgressMessage = true logger.info { "project context relevant document count: ${queryResult.size}" } } else { @@ -145,7 +145,7 @@ class ChatController private constructor( } } else if (CodeWhispererSettings.getInstance().isProjectContextEnabled() && isDataCollectionGroup) { val projectContextController = ProjectContextController.getInstance(context.project) - queryResult = projectContextController.query(prompt) + queryResult = projectContextController.queryChat(prompt) } handleChat( diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt index 88bb7fc19b2..231e5ac1d26 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/controller/chat/telemetry/TelemetryHelper.kt @@ -13,10 +13,9 @@ import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.ChatRequestData import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.TriggerType import software.aws.toolkits.jetbrains.services.cwc.clients.chat.v1.ChatSessionV1 @@ -26,6 +25,7 @@ import software.aws.toolkits.jetbrains.services.cwc.messages.IncomingCwcMessage import software.aws.toolkits.jetbrains.services.cwc.messages.LinkType import software.aws.toolkits.jetbrains.services.cwc.storage.ChatSessionStorage import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.utils.notifyError import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.AmazonqTelemetry @@ -412,27 +412,6 @@ class TelemetryHelper(private val context: AmazonQAppInitContext, private val se fun recordTelemetryChatRunCommand(type: CwsprChatCommandType, name: String? = null, startUrl: String? = null) { AmazonqTelemetry.runCommand(cwsprChatCommandType = type, cwsprChatCommandName = name, credentialStartUrl = startUrl) } - - fun recordIndexWorkspace( - duration: Double, - fileCount: Int = 0, - fileSize: Int = 0, - isSuccess: Boolean, - memoryUsage: Int? = 0, - cpuUsage: Int? = 0, - startUrl: String? = null, - ) { - AmazonqTelemetry.indexWorkspace( - project = null, - duration = duration, - amazonqIndexFileCount = fileCount.toLong(), - amazonqIndexFileSizeInMB = fileSize.toLong(), - success = isSuccess, - amazonqIndexMemoryUsageInMB = memoryUsage?.toLong(), - amazonqIndexCpuUsagePercentage = cpuUsage?.toLong(), - credentialStartUrl = startUrl - ) - } } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextController.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextController.kt deleted file mode 100644 index 994d3e8f501..00000000000 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextController.kt +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project - -import com.intellij.openapi.Disposable -import com.intellij.openapi.components.Service -import com.intellij.openapi.components.service -import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Disposer -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import software.aws.toolkits.core.utils.getLogger -import software.aws.toolkits.core.utils.warn -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings - -@Service(Service.Level.PROJECT) -class ProjectContextController(private val project: Project, private val cs: CoroutineScope) : Disposable { - private val encoderServer: EncoderServer = EncoderServer(project) - private val projectContextProvider: ProjectContextProvider = ProjectContextProvider(project, encoderServer, cs) - init { - cs.launch { - if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { - encoderServer.downloadArtifactsAndStartServer() - } - } - } - - fun getProjectContextIndexComplete() = projectContextProvider.isIndexComplete.get() - - fun query(prompt: String): List { - try { - return projectContextProvider.query(prompt) - } catch (e: Exception) { - logger.warn { "error while querying for project context $e.message" } - return emptyList() - } - } - - fun updateIndex(filePath: String) { - try { - return projectContextProvider.updateIndex(filePath) - } catch (e: Exception) { - logger.warn { "error while updating index for project context $e.message" } - } - } - - override fun dispose() { - Disposer.dispose(encoderServer) - Disposer.dispose(projectContextProvider) - } - - companion object { - private val logger = getLogger() - fun getInstance(project: Project) = project.service() - } -} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextEditorListener.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextEditorListener.kt deleted file mode 100644 index 8997254f7d0..00000000000 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextEditorListener.kt +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 - -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project -import com.intellij.openapi.fileEditor.FileEditorManager -import com.intellij.openapi.fileEditor.FileEditorManagerListener -import com.intellij.openapi.vfs.VirtualFile -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings - -class ProjectContextEditorListener : FileEditorManagerListener { - override fun fileClosed(source: FileEditorManager, file: VirtualFile) { - if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { - ProjectContextController.getInstance(source.project).updateIndex(file.path) - } - } -} diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/TelemetryHelperTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/TelemetryHelperTest.kt index 0cba45227e8..94850b8bad6 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/TelemetryHelperTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/TelemetryHelperTest.kt @@ -40,10 +40,9 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection import software.aws.toolkits.jetbrains.core.credentials.sono.Q_SCOPES import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.cwc.clients.chat.ChatSession import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.ChatRequestData import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.CodeNamesImpl @@ -63,6 +62,7 @@ import software.aws.toolkits.jetbrains.services.cwc.messages.LinkType import software.aws.toolkits.jetbrains.services.cwc.storage.ChatSessionInfo import software.aws.toolkits.jetbrains.services.cwc.storage.ChatSessionStorage import software.aws.toolkits.jetbrains.services.telemetry.MockTelemetryServiceExtension +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.telemetry.CwsprChatConversationType import software.aws.toolkits.telemetry.CwsprChatInteractionType import software.aws.toolkits.telemetry.CwsprChatTriggerInteraction diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/EncoderServerTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/EncoderServerTest.kt index eb79f5d98ce..7fd76f2c044 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/EncoderServerTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/EncoderServerTest.kt @@ -9,7 +9,7 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Rule import org.junit.Test -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.EncoderServer +import software.aws.toolkits.jetbrains.services.amazonq.project.EncoderServer import software.aws.toolkits.jetbrains.utils.rules.CodeInsightTestFixtureRule import software.aws.toolkits.jetbrains.utils.rules.JavaCodeInsightTestFixtureRule import java.math.BigInteger diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextProviderTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextProviderTest.kt index 01727673523..b11a26519aa 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextProviderTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonq/workspace/context/ProjectContextProviderTest.kt @@ -13,8 +13,8 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.times import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.EncoderServer -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.ProjectContextProvider +import software.aws.toolkits.jetbrains.services.amazonq.project.EncoderServer +import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextProvider import software.aws.toolkits.jetbrains.utils.rules.CodeInsightTestFixtureRule import software.aws.toolkits.jetbrains.utils.rules.JavaCodeInsightTestFixtureRule import java.net.ConnectException @@ -51,7 +51,7 @@ class ProjectContextProviderTest { fun `test query payload is encrypted`() = runTest { whenever(encoderServer.port).thenReturn(3000) try { - sut.query("what does this project do") + sut.queryChat("what does this project do") } catch (e: ConnectException) { // no-op } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt index 5a155b5078d..2d7e9baf149 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/migration/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt @@ -5,7 +5,7 @@ package migration.software.aws.toolkits.jetbrains.services.codewhisperer.customi import com.intellij.openapi.components.service import com.intellij.openapi.project.Project -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CustomizationUiItem // A component responsible managing client's codewhisperer model configuration (currently customization feature only support enterprise tier users) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/credentials/CodeWhispererClientAdaptor.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/credentials/CodeWhispererClientAdaptor.kt index 1dfd5d556be..3f059a24e71 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/credentials/CodeWhispererClientAdaptor.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/credentials/CodeWhispererClientAdaptor.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.components.service import com.intellij.openapi.project.Project -import com.intellij.openapi.util.SystemInfo import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider import software.amazon.awssdk.services.codewhisperer.CodeWhispererClient import software.amazon.awssdk.services.codewhisperer.model.CreateCodeScanRequest @@ -25,13 +24,10 @@ import software.amazon.awssdk.services.codewhispererruntime.model.CreateUploadUr import software.amazon.awssdk.services.codewhispererruntime.model.Dimension import software.amazon.awssdk.services.codewhispererruntime.model.GenerateCompletionsRequest import software.amazon.awssdk.services.codewhispererruntime.model.GenerateCompletionsResponse -import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory import software.amazon.awssdk.services.codewhispererruntime.model.ListAvailableCustomizationsRequest import software.amazon.awssdk.services.codewhispererruntime.model.ListFeatureEvaluationsResponse -import software.amazon.awssdk.services.codewhispererruntime.model.OperatingSystem import software.amazon.awssdk.services.codewhispererruntime.model.SendTelemetryEventResponse import software.amazon.awssdk.services.codewhispererruntime.model.SuggestionState -import software.amazon.awssdk.services.codewhispererruntime.model.UserContext import software.amazon.awssdk.services.codewhispererruntime.model.UserIntent import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger @@ -43,16 +39,15 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManagerListener import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization +import software.aws.toolkits.jetbrains.services.amazonq.codeWhispererUserContext +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.service.RequestContext import software.aws.toolkits.jetbrains.services.codewhisperer.service.ResponseContext import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants -import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.FEATURE_EVALUATION_PRODUCT_NAME import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getTelemetryOptOutPreference import software.aws.toolkits.jetbrains.services.codewhisperer.util.transform -import software.aws.toolkits.jetbrains.services.telemetry.ClientMetadata import software.aws.toolkits.telemetry.CodewhispererCompletionType import software.aws.toolkits.telemetry.CodewhispererSuggestionState import java.time.Instant @@ -187,24 +182,6 @@ interface CodeWhispererClientAdaptor : Disposable { } open class CodeWhispererClientAdaptorImpl(override val project: Project) : CodeWhispererClientAdaptor { - private val codeWhispererUserContext = ClientMetadata.getDefault().let { - val osForCodeWhisperer: 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(osForCodeWhisperer) - .product(FEATURE_EVALUATION_PRODUCT_NAME) - .clientId(it.clientId) - .ideVersion(it.awsVersion) - .build() - } - private val mySigv4Client by lazy { createUnmanagedSigv4Client() } @Volatile diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomizationDialog.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomizationDialog.kt index a05ed37b92c..405515b53cb 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomizationDialog.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomizationDialog.kt @@ -26,6 +26,7 @@ import software.amazon.awssdk.arns.Arn import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.tryOrNull +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.Q_CUSTOM_LEARN_MORE_URI import software.aws.toolkits.jetbrains.ui.AsyncComboBox import software.aws.toolkits.jetbrains.utils.notifyInfo diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt index 1d2f4b2788d..31fe369b522 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererModelConfigurator.kt @@ -20,10 +20,11 @@ import com.intellij.util.xmlb.annotations.Property import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.calculateIfIamIdentityCenterConnection +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants -import software.aws.toolkits.jetbrains.services.codewhisperer.util.calculateIfIamIdentityCenterConnection import software.aws.toolkits.jetbrains.utils.notifyInfo import software.aws.toolkits.jetbrains.utils.notifyWarn import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/editor/CodeWhispererEditorUtil.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/editor/CodeWhispererEditorUtil.kt index e699e97e856..cce06446e6c 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/editor/CodeWhispererEditorUtil.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/editor/CodeWhispererEditorUtil.kt @@ -31,7 +31,8 @@ object CodeWhispererEditorUtil { val fileName = getFileName(psiFile) val programmingLanguage = psiFile.programmingLanguage() val fileRelativePath = getRelativePathToContentRoot(editor) - return FileContextInfo(caretContext, fileName, programmingLanguage, fileRelativePath) + val filePath = psiFile.virtualFile.path + return FileContextInfo(caretContext, fileName, programmingLanguage, filePath, fileRelativePath) } fun extractCaretContext(editor: Editor): CaretContext { diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/importadder/CodeWhispererImportAdderListener.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/importadder/CodeWhispererImportAdderListener.kt index 0a2f8110b5d..3caf2931366 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/importadder/CodeWhispererImportAdderListener.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/importadder/CodeWhispererImportAdderListener.kt @@ -9,7 +9,7 @@ import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.jetbrains.services.codewhisperer.model.InvocationContext import software.aws.toolkits.jetbrains.services.codewhisperer.model.SessionContext import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUserActionListener -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings object CodeWhispererImportAdderListener : CodeWhispererUserActionListener { internal val LOG = getLogger() diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/model/CodeWhispererModel.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/model/CodeWhispererModel.kt index cf465134162..3ecbe61b1f0 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/model/CodeWhispererModel.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/model/CodeWhispererModel.kt @@ -43,6 +43,7 @@ data class FileContextInfo( val caretContext: CaretContext, val filename: String, val programmingLanguage: CodeWhispererProgrammingLanguage, + val filePath: String, val fileRelativePath: String?, ) diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt index 8b9c9d22949..ee8ea6b1c44 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererService.kt @@ -70,7 +70,6 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.model.Supplemental import software.aws.toolkits.jetbrains.services.codewhisperer.model.TriggerTypeInfo import software.aws.toolkits.jetbrains.services.codewhisperer.model.WorkerContext import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhispererTelemetryService import software.aws.toolkits.jetbrains.services.codewhisperer.util.CaretMovement import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeInsightsSettingsFacade @@ -81,6 +80,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhisperer 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.FileContextProvider +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.utils.isInjectedText import software.aws.toolkits.jetbrains.utils.isQExpired import software.aws.toolkits.jetbrains.utils.notifyWarn diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt index 9db80018184..87ca1c728c0 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererConfigurable.kt @@ -16,6 +16,7 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager 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 +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.resources.message import java.awt.Font diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupActivity.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupActivity.kt index ab20e89b0b7..cba7d4ab3e2 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupActivity.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupActivity.kt @@ -10,17 +10,17 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import software.aws.toolkits.jetbrains.core.coroutines.projectCoroutineScope +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.calculateIfIamIdentityCenterConnection import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanManager import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isUserBuilderId import software.aws.toolkits.jetbrains.services.codewhisperer.importadder.CodeWhispererImportAdderListener import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager.Companion.CODEWHISPERER_USER_ACTION_PERFORMED -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants.FEATURE_CONFIG_POLL_INTERVAL_IN_MS import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.promptReAuth -import software.aws.toolkits.jetbrains.services.codewhisperer.util.calculateIfIamIdentityCenterConnection import software.aws.toolkits.jetbrains.utils.isQConnected import software.aws.toolkits.jetbrains.utils.isQExpired import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupSettingsListener.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupSettingsListener.kt index b528c1c7096..24dbd5bd7f3 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupSettingsListener.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/startup/CodeWhispererProjectStartupSettingsListener.kt @@ -19,9 +19,9 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhisp import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererActivationChangedListener import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isCodeWhispererEnabled -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.status.CodeWhispererStatusBarWidgetFactory import software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceManager +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings class CodeWhispererProjectStartupSettingsListener(private val project: Project) : CodeWhispererActivationChangedListener, diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererTelemetryService.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererTelemetryService.kt index 2ab7597f7c4..173c912659c 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererTelemetryService.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererTelemetryService.kt @@ -17,6 +17,7 @@ import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererR import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.jetbrains.core.coroutines.projectCoroutineScope +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.CodeWhispererCodeScanIssue import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage @@ -27,17 +28,16 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.model.Recommendati import software.aws.toolkits.jetbrains.services.codewhisperer.model.SessionContext import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererAutoTriggerService import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererAutomatedTriggerType -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus import software.aws.toolkits.jetbrains.services.codewhisperer.service.RequestContext import software.aws.toolkits.jetbrains.services.codewhisperer.service.ResponseContext -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererConstants import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getCodeWhispererStartUrl import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getConnectionStartUrl import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getGettingStartedTaskType import software.aws.toolkits.jetbrains.services.codewhisperer.util.runIfIdcConnectionOrTelemetryEnabled import software.aws.toolkits.jetbrains.settings.AwsSettings +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.telemetry.CodewhispererCodeScanScope import software.aws.toolkits.telemetry.CodewhispererCompletionType import software.aws.toolkits.telemetry.CodewhispererGettingStartedTask diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererUserModificationTracker.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererUserModificationTracker.kt index 84e93fb8198..75310cc0d37 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererUserModificationTracker.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/telemetry/CodeWhispererUserModificationTracker.kt @@ -24,11 +24,11 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.customization.Code import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererUnknownLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.programmingLanguage -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererUtil.getConnectionStartUrl import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.InsertedCodeModificationEntry import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl import software.aws.toolkits.jetbrains.settings.AwsSettings +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.telemetry.AmazonqTelemetry import software.aws.toolkits.telemetry.CodewhispererCompletionType import software.aws.toolkits.telemetry.CodewhispererRuntime diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererEndpointCustomizer.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererEndpointCustomizer.kt index 30e771f8957..acb94f8a373 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererEndpointCustomizer.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererEndpointCustomizer.kt @@ -26,8 +26,8 @@ import software.amazon.awssdk.services.cognitoidentity.CognitoIdentityClient import software.aws.toolkits.core.ToolkitClientCustomizer import software.aws.toolkits.jetbrains.core.AwsSdkClient import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.telemetry.AwsCognitoCredentialsProvider +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import java.net.Proxy import java.net.URI import java.time.Duration diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererFileContextProvider.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererFileContextProvider.kt index d2fda694d75..3a63951aa5d 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererFileContextProvider.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererFileContextProvider.kt @@ -22,6 +22,8 @@ import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.warn +import software.aws.toolkits.jetbrains.isDeveloperMode +import software.aws.toolkits.jetbrains.services.amazonq.project.ProjectContextController import software.aws.toolkits.jetbrains.services.codewhisperer.editor.CodeWhispererEditorUtil import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava @@ -214,6 +216,24 @@ class DefaultCodeWhispererFileContextProvider(private val project: Project) : Fi // takeLast(11) will extract 10 lines (exclusing current line) of left context as the query parameter val query = targetContext.caretContext.leftFileContext.split("\n").takeLast(11).joinToString("\n") + if (isDeveloperMode()) { + val response = ProjectContextController.getInstance(project).queryInline(query, psiFile.virtualFile.path).filter { it.content.isBlank() } + LOG.info { response.toString() } + + return SupplementalContextInfo( + isUtg = false, + contents = response.map { + Chunk( + content = it.content, + path = it.filePath, + nextChunk = it.content, + score = it.score + ) + }, + targetFileName = targetContext.filename, + strategy = CrossFileStrategy.ProjectContext + ) + } // step 1: prepare data val first60Chunks: List = try { diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererUtil.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererUtil.kt index 220ef0200d4..1501f0ea903 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererUtil.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/CodeWhispererUtil.kt @@ -46,27 +46,6 @@ import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.CodewhispererCompletionType import software.aws.toolkits.telemetry.CodewhispererGettingStartedTask -fun calculateIfIamIdentityCenterConnection(project: Project, calculationTask: (connection: ToolkitConnection) -> T): T? = - ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { - calculateIfIamIdentityCenterConnection(it, calculationTask) - } - -fun calculateIfIamIdentityCenterConnection(connection: ToolkitConnection, calculationTask: (connection: ToolkitConnection) -> T): T? = - if (connection.isSono()) { - null - } else { - calculationTask(connection) - } - -fun calculateIfBIDConnection(project: Project, calculationTask: (connection: ToolkitConnection) -> T): T? = - ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { - if (it.isSono()) { - calculationTask(it) - } else { - null - } - } - // Controls the condition to send telemetry event to CodeWhisperer service, currently: // 1. It will be sent for Builder ID users, only if they have optin telemetry sharing. // 2. It will be sent for IdC users, regardless of telemetry optout status. diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/SupplementalContextStrategy.kt b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/SupplementalContextStrategy.kt index d3982a9d77c..3fc081c0071 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/SupplementalContextStrategy.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/util/SupplementalContextStrategy.kt @@ -21,10 +21,12 @@ enum class UtgStrategy : SupplementalContextStrategy { enum class CrossFileStrategy : SupplementalContextStrategy { OpenTabsBM25, Empty, + ProjectContext, ; override fun toString() = when (this) { OpenTabsBM25 -> "OpenTabs_BM25" Empty -> "Empty" + ProjectContext -> "Project_context" } } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientAdaptorTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientAdaptorTest.kt index e76a34d2e45..5c395716059 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientAdaptorTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientAdaptorTest.kt @@ -73,13 +73,13 @@ import software.aws.toolkits.jetbrains.core.credentials.MockCredentialManagerRul import software.aws.toolkits.jetbrains.core.credentials.MockToolkitAuthManagerRule import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_REGION +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.metadata import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.pythonRequest import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.pythonResponseWithToken import software.aws.toolkits.jetbrains.services.codewhisperer.CodeWhispererTestUtil.sdkHttpResponse import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptorImpl -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.model.LatencyContext import software.aws.toolkits.jetbrains.services.codewhisperer.model.TriggerTypeInfo diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientTest.kt index 98bebf1e67c..c680883b7c5 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererClientTest.kt @@ -31,8 +31,8 @@ import software.aws.toolkits.jetbrains.core.MockClientManager import software.aws.toolkits.jetbrains.core.MockClientManagerRule import software.aws.toolkits.jetbrains.core.credentials.MockCredentialManagerRule import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExplorerActionManager -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererEndpointCustomizer +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings /** * If this test class failed, highly likely because the endpoint is overwritten by [CodeWhispererEndpointCustomizer] diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeCoverageTrackerTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeCoverageTrackerTest.kt index 61ac7b68426..6f7655b48c8 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeCoverageTrackerTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererCodeCoverageTrackerTest.kt @@ -162,7 +162,7 @@ internal class CodeWhispererCodeCoverageTrackerTestPython : CodeWhispererCodeCov fixture.editor, mock(), mock(), - FileContextInfo(mock(), pythonFileName, CodeWhispererPython.INSTANCE, pythonFileName), + FileContextInfo(mock(), pythonFileName, CodeWhispererPython.INSTANCE, "filePath", pythonFileName), runBlocking { async { SupplementalContextInfo( diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererFeatureConfigServiceTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererFeatureConfigServiceTest.kt index 55f6df683bb..16b9611a4d5 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererFeatureConfigServiceTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererFeatureConfigServiceTest.kt @@ -21,9 +21,9 @@ import software.aws.toolkits.jetbrains.core.credentials.LegacyManagedBearerSsoCo import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_URL +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService import kotlin.reflect.full.memberFunctions import kotlin.test.Test diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererModelConfiguratorTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererModelConfiguratorTest.kt index 333d2574ab7..1285a87378c 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererModelConfiguratorTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererModelConfiguratorTest.kt @@ -37,10 +37,10 @@ import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_REGION import software.aws.toolkits.jetbrains.core.credentials.sono.SONO_URL import software.aws.toolkits.jetbrains.core.credentials.sono.isSono import software.aws.toolkits.jetbrains.core.region.MockRegionProviderRule -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomizationState import software.aws.toolkits.jetbrains.services.codewhisperer.customization.DefaultCodeWhispererModelConfigurator -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService import software.aws.toolkits.jetbrains.utils.xmlElement import kotlin.reflect.full.memberProperties import kotlin.reflect.jvm.isAccessible diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt index 4bff4965c3d..cc642520023 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererServiceTest.kt @@ -30,8 +30,8 @@ import software.amazon.awssdk.services.codewhispererruntime.model.ProgrammingLan import software.amazon.awssdk.services.codewhispererruntime.model.SupplementalContext import software.aws.toolkits.jetbrains.core.credentials.AwsConnectionManager import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.language.CodeWhispererProgrammingLanguage import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererSettingsTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererSettingsTest.kt index bde3d169f52..e82b4f13a41 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererSettingsTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererSettingsTest.kt @@ -26,10 +26,10 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWh import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.CodeWhispererExploreActionState import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.isCodeWhispererEnabled import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererConfiguration -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.status.CodeWhispererStatusBarWidgetFactory import software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceToolWindowFactory +import software.aws.toolkits.jetbrains.settings.CodeWhispererConfiguration +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import kotlin.test.fail class CodeWhispererSettingsTest : CodeWhispererTestBase() { diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestBase.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestBase.kt index 6b76b28c939..ace44249538 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestBase.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestBase.kt @@ -46,10 +46,10 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispere import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatus import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererRecommendationManager import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererConfiguration -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererConfigurationType -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.util.CodeWhispererColorUtil.POPUP_DIM_HEX +import software.aws.toolkits.jetbrains.settings.CodeWhispererConfiguration +import software.aws.toolkits.jetbrains.settings.CodeWhispererConfigurationType +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.utils.rules.PythonCodeInsightTestFixtureRule import software.aws.toolkits.resources.message import java.util.concurrent.atomic.AtomicReference diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererUserModificationTrackerTest.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererUserModificationTrackerTest.kt index 482d0fde62c..492c162662d 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererUserModificationTrackerTest.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererUserModificationTrackerTest.kt @@ -33,16 +33,16 @@ import software.amazon.awssdk.http.SdkHttpResponse import software.amazon.awssdk.services.codewhispererruntime.model.SendTelemetryEventResponse import software.aws.toolkits.core.telemetry.MetricEvent import software.aws.toolkits.core.telemetry.TelemetryBatcher +import software.aws.toolkits.jetbrains.services.amazonq.models.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererCustomization import software.aws.toolkits.jetbrains.services.codewhisperer.customization.CodeWhispererModelConfigurator import software.aws.toolkits.jetbrains.services.codewhisperer.language.languages.CodeWhispererJava -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeInsertionDiff import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhispererUserModificationTracker import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.percentage import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.InsertedCodeModificationEntry import software.aws.toolkits.jetbrains.services.telemetry.MockTelemetryServiceExtension +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import java.time.Instant import kotlin.math.min import kotlin.test.assertNotNull diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/tstFixtures/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestUtil.kt b/plugins/amazonq/codewhisperer/jetbrains-community/tstFixtures/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestUtil.kt index 8a05e4085a8..04ba5b218a6 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/tstFixtures/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestUtil.kt +++ b/plugins/amazonq/codewhisperer/jetbrains-community/tstFixtures/software/aws/toolkits/jetbrains/services/codewhisperer/CodeWhispererTestUtil.kt @@ -172,7 +172,7 @@ object CodeWhispererTestUtil { const val leftContext_success_Iac = "# Create an S3 Bucket named CodeWhisperer in CloudFormation" const val leftContext_failure_Iac = "Create an S3 Bucket named CodeWhisperer" - internal fun pythonResponseWithToken(token: String): GenerateCompletionsResponse = + fun pythonResponseWithToken(token: String): GenerateCompletionsResponse = pythonResponse.toBuilder().nextToken(token).build() internal fun generateMockCompletionDetail(content: String): Completion { @@ -392,13 +392,14 @@ fun aResponseContext(): ResponseContext = ResponseContext(aString()) fun aFileContextInfo(language: CodeWhispererProgrammingLanguage? = null): FileContextInfo { val caretContextInfo = CaretContext(aString(), aString(), aString()) val fileName = aString() + val filePath = aString() val fileRelativePath = Paths.get("test", fileName).toString() val programmingLanguage = language ?: listOf( CodeWhispererPython.INSTANCE, CodeWhispererJava.INSTANCE ).random() - return FileContextInfo(caretContextInfo, fileName, programmingLanguage, fileRelativePath) + return FileContextInfo(caretContextInfo, fileName, programmingLanguage, filePath, fileRelativePath) } fun aTriggerType(): CodewhispererTriggerType = diff --git a/plugins/amazonq/shared/jetbrains-community/build.gradle.kts b/plugins/amazonq/shared/jetbrains-community/build.gradle.kts index d7943798eec..315356836b5 100644 --- a/plugins/amazonq/shared/jetbrains-community/build.gradle.kts +++ b/plugins/amazonq/shared/jetbrains-community/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { // CodeWhispererTelemetryService uses a CircularFifoQueue implementation(libs.commons.collections) + implementation(libs.nimbus.jose.jwt) testFixturesApi(testFixtures(project(":plugin-core:jetbrains-community"))) } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererFeatureConfigService.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt similarity index 76% rename from plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererFeatureConfigService.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt index 7e9a48b4baa..1d72fc80b31 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/service/CodeWhispererFeatureConfigService.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt @@ -1,18 +1,18 @@ -// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.codewhisperer.service +package software.aws.toolkits.jetbrains.services.amazonq import com.intellij.openapi.components.Service import com.intellij.openapi.components.service import com.intellij.openapi.project.Project import com.intellij.util.concurrency.annotations.RequiresBackgroundThread +import software.amazon.awssdk.services.codewhispererruntime.CodeWhispererRuntimeClient import software.amazon.awssdk.services.codewhispererruntime.model.FeatureValue +import software.amazon.awssdk.services.codewhispererruntime.model.ListAvailableCustomizationsRequest import software.aws.toolkits.core.utils.debug import software.aws.toolkits.core.utils.getLogger -import software.aws.toolkits.jetbrains.services.codewhisperer.credentials.CodeWhispererClientAdaptor -import software.aws.toolkits.jetbrains.services.codewhisperer.util.calculateIfBIDConnection -import software.aws.toolkits.jetbrains.services.codewhisperer.util.calculateIfIamIdentityCenterConnection +import software.aws.toolkits.jetbrains.core.awsClient import software.aws.toolkits.jetbrains.utils.isQExpired @Service @@ -25,7 +25,9 @@ class CodeWhispererFeatureConfigService { LOG.debug { "Fetching feature configs" } try { - val response = CodeWhispererClientAdaptor.getInstance(project).listFeatureEvaluations() + val response = project.awsClient().listFeatureEvaluations { + it.userContext(codeWhispererUserContext) + } // Simply force overwrite feature configs from server response, no needed to check existing values. response.featureEvaluations().forEach { @@ -41,7 +43,20 @@ class CodeWhispererFeatureConfigService { val availableCustomizations = calculateIfIamIdentityCenterConnection(project) { try { - CodeWhispererClientAdaptor.getInstance(project).listAvailableCustomizations().map { c -> c.arn } + project.awsClient() + .listAvailableCustomizationsPaginator(ListAvailableCustomizationsRequest.builder().build()) + .stream() + .toList() + .flatMap { resp -> + LOG.debug { + "listAvailableCustomizations: requestId: ${resp.responseMetadata().requestId()}, customizations: ${ + resp.customizations().map { it.name() } + }" + } + resp.customizations().map { + it.arn() + } + } } catch (e: Exception) { LOG.debug(e) { "Failed to list available customizations" } null @@ -63,9 +78,11 @@ class CodeWhispererFeatureConfigService { } fun getFeatureConfigsTelemetry(): String = - "{${featureConfigs.entries.joinToString(", ") { (name, context) -> - "$name: ${context.variation}" - }}}" + "{${ + featureConfigs.entries.joinToString(", ") { (name, context) -> + "$name: ${context.variation}" + } + }}" // TODO: for all feature variations, define a contract that can be enforced upon the implementation of // the business logic. @@ -98,7 +115,7 @@ class CodeWhispererFeatureConfigService { private val LOG = getLogger() // TODO: add real feature later - internal val FEATURE_DEFINITIONS = mapOf( + val FEATURE_DEFINITIONS = mapOf( TEST_FEATURE_NAME to FeatureContext( TEST_FEATURE_NAME, "CONTROL", diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/Constants.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/Constants.kt index 4b298106c7b..200a20dc5c9 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/Constants.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/Constants.kt @@ -3,6 +3,12 @@ package software.aws.toolkits.jetbrains.services.amazonq +import com.intellij.openapi.util.SystemInfo +import software.amazon.awssdk.services.codewhispererruntime.model.IdeCategory +import software.amazon.awssdk.services.codewhispererruntime.model.OperatingSystem +import software.amazon.awssdk.services.codewhispererruntime.model.UserContext +import software.aws.toolkits.jetbrains.services.telemetry.ClientMetadata + const val APPLICATION_ZIP = "application/zip" const val SERVER_SIDE_ENCRYPTION = "x-amz-server-side-encryption" const val AWS_KMS = "aws:kms" @@ -35,3 +41,23 @@ const val CODE_TRANSFORM_TROUBLESHOOT_DOC_DOWNLOAD_ERROR_OVERVIEW = const val CODE_TRANSFORM_PREREQUISITES = "https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/code-transformation.html#prerequisites" + +val codeWhispererUserContext = ClientMetadata.getDefault().let { + val osForCodeWhisperer: 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(osForCodeWhisperer) + .product(FEATURE_EVALUATION_PRODUCT_NAME) + .clientId(it.clientId) + .ideVersion(it.awsVersion) + .build() +} + +const val FEATURE_EVALUATION_PRODUCT_NAME = "CodeWhisperer" diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt new file mode 100644 index 00000000000..c8267b03514 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QUtils.kt @@ -0,0 +1,31 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq + +import com.intellij.openapi.project.Project +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnection +import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager +import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection +import software.aws.toolkits.jetbrains.core.credentials.sono.isSono + +fun calculateIfIamIdentityCenterConnection(project: Project, calculationTask: (connection: ToolkitConnection) -> T): T? = + ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { + calculateIfIamIdentityCenterConnection(it, calculationTask) + } + +fun calculateIfIamIdentityCenterConnection(connection: ToolkitConnection, calculationTask: (connection: ToolkitConnection) -> T): T? = + if (connection.isSono()) { + null + } else { + calculationTask(connection) + } + +fun calculateIfBIDConnection(project: Project, calculationTask: (connection: ToolkitConnection) -> T): T? = + ToolkitConnectionManager.getInstance(project).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { + if (it.isSono()) { + calculationTask(it) + } else { + null + } + } diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomization.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/models/CodeWhispererCustomization.kt similarity index 79% rename from plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomization.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/models/CodeWhispererCustomization.kt index 92335fec559..90988c50aef 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/customization/CodeWhispererCustomization.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/models/CodeWhispererCustomization.kt @@ -1,7 +1,7 @@ // Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.codewhisperer.customization +package software.aws.toolkits.jetbrains.services.amazonq.models data class CodeWhispererCustomization( @JvmField diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/BM25Chunk.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/BM25Chunk.kt new file mode 100644 index 00000000000..40f7038d0f7 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/BM25Chunk.kt @@ -0,0 +1,10 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.project + +data class BM25Chunk( + val content: String, + val filePath: String, + val score: Double, +) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/EncoderServer.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/EncoderServer.kt similarity index 97% rename from plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/EncoderServer.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/EncoderServer.kt index 9907331f687..5420b0f6669 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/EncoderServer.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/EncoderServer.kt @@ -1,7 +1,7 @@ // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project +package software.aws.toolkits.jetbrains.services.amazonq.project import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.intellij.execution.configurations.GeneralCommandLine @@ -26,8 +26,8 @@ import software.aws.toolkits.core.utils.getLogger import software.aws.toolkits.core.utils.info import software.aws.toolkits.core.utils.tryDirOp import software.aws.toolkits.core.utils.warn -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings -import software.aws.toolkits.jetbrains.services.cwc.editor.context.project.manifest.ManifestManager +import software.aws.toolkits.jetbrains.services.amazonq.project.manifest.ManifestManager +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings import java.io.FileOutputStream import java.io.IOException import java.nio.file.Files diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/LspApi.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/LspApi.kt new file mode 100644 index 00000000000..a440abcdfff --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/LspApi.kt @@ -0,0 +1,37 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.project + +sealed interface LspApi { + val command: String + + data object Initialize : LspApi { + override val command: String = "initialize" + } + + data object BuildIndex : LspApi { + override val command: String = "buildIndex" + } + + data object UpdateIndex : LspApi { + override val command: String = "updateIndexV2" + } + + data object QueryChat : LspApi { + override val command: String = "query" + } + + data object QueryInline : LspApi { + override val command: String = "queryInlineProjectContext" + } + + data object GetUsageMetrics : LspApi { + override val command: String = "getUsage" + } +} + +data class LspResponse( + val responseCode: Int, + val responseBody: String, +) diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt new file mode 100644 index 00000000000..34f23ef9c8c --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextController.kt @@ -0,0 +1,91 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.project + +import com.intellij.openapi.Disposable +import com.intellij.openapi.components.Service +import com.intellij.openapi.components.service +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Disposer +import com.intellij.openapi.vfs.VirtualFileManager +import com.intellij.openapi.vfs.newvfs.BulkFileListener +import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent +import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent +import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import software.aws.toolkits.core.utils.getLogger +import software.aws.toolkits.core.utils.warn +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings + +@Service(Service.Level.PROJECT) +class ProjectContextController(private val project: Project, private val cs: CoroutineScope) : Disposable { + private val encoderServer: EncoderServer = EncoderServer(project) + private val projectContextProvider: ProjectContextProvider = ProjectContextProvider(project, encoderServer, cs) + init { + cs.launch { + if (CodeWhispererSettings.getInstance().isProjectContextEnabled()) { + encoderServer.downloadArtifactsAndStartServer() + } + } + + project.messageBus.connect(this).subscribe( + VirtualFileManager.VFS_CHANGES, + object : BulkFileListener { + override fun after(events: MutableList) { + val createdFiles = events.filterIsInstance().mapNotNull { it.file?.path } + val deletedFiles = events.filterIsInstance().map { it.file.path } + + updateIndex(createdFiles, IndexUpdateMode.ADD) + updateIndex(deletedFiles, IndexUpdateMode.REMOVE) + } + } + ) + } + + enum class IndexUpdateMode(val value: String) { + UPDATE("update"), + REMOVE("remove"), + ADD("add"), + } + + fun getProjectContextIndexComplete() = projectContextProvider.isIndexComplete.get() + + fun queryChat(prompt: String): List { + try { + return projectContextProvider.queryChat(prompt) + } catch (e: Exception) { + logger.warn { "error while querying for project context $e.message" } + return emptyList() + } + } + + // TODO: should we make it suspend and how? + fun queryInline(prompt: String, filePath: String): List { + try { + return projectContextProvider.queryInline(prompt, filePath) + } catch (e: Exception) { + logger.warn { "error while querying for project context $e.message" } + return emptyList() + } + } + + fun updateIndex(filePaths: List, mode: IndexUpdateMode) { + try { + return projectContextProvider.updateIndex(filePaths, mode.value) + } catch (e: Exception) { + logger.warn { "error while updating index for project context $e.message" } + } + } + + override fun dispose() { + Disposer.dispose(encoderServer) + Disposer.dispose(projectContextProvider) + } + + companion object { + private val logger = getLogger() + fun getInstance(project: Project) = project.service() + } +} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextEditorListener.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextEditorListener.kt new file mode 100644 index 00000000000..4de3eb767a9 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextEditorListener.kt @@ -0,0 +1,20 @@ +// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq.project +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.fileEditor.FileEditorManagerEvent +import com.intellij.openapi.fileEditor.FileEditorManagerListener + +class ProjectContextEditorListener : FileEditorManagerListener { + override fun selectionChanged(event: FileEditorManagerEvent) { + val oldFile = event.oldFile ?: return + + // TODO: should respect isIdeAutosave config + with(FileDocumentManager.getInstance()) { + getDocument(oldFile)?.let { + saveDocument(it) + } + } + } +} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextProvider.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextProvider.kt similarity index 71% rename from plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextProvider.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextProvider.kt index a31508f0b5e..77775f2878c 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/ProjectContextProvider.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/ProjectContextProvider.kt @@ -1,7 +1,7 @@ // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project +package software.aws.toolkits.jetbrains.services.amazonq.project import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty @@ -20,13 +20,14 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.yield import software.aws.toolkits.core.utils.debug +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.core.utils.warn import software.aws.toolkits.jetbrains.services.amazonq.FeatureDevSessionContext -import software.aws.toolkits.jetbrains.services.codewhisperer.settings.CodeWhispererSettings -import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.TelemetryHelper import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl +import software.aws.toolkits.jetbrains.settings.CodeWhispererSettings +import software.aws.toolkits.telemetry.AmazonqTelemetry import java.io.OutputStreamWriter import java.net.HttpURLConnection import java.net.URL @@ -53,10 +54,12 @@ class ProjectContextProvider(val project: Project, private val encoderServer: En } } } - data class IndexRequestPayload( + + data class IndexRequestV2( val filePaths: List, val projectRoot: String, - val refresh: Boolean, + val config: String, + val language: String = "", ) data class FileCollectionResult( @@ -68,10 +71,16 @@ class ProjectContextProvider(val project: Project, private val encoderServer: En val query: String, ) - data class UpdateIndexRequestPayload( + data class QueryRequestV2( + val query: String, val filePath: String, ) + data class UpdateIndexRequestV2( + val filePaths: List, + val mode: String, + ) + data class Usage( @JsonIgnoreProperties(ignoreUnknown = true) @JsonProperty("memoryUsage") @@ -118,6 +127,7 @@ class ProjectContextProvider(val project: Project, private val encoderServer: En return@launch } } catch (e: Exception) { + logger.error { "project context index error: message=${e.message} stack=${e.stackTraceToString()}" } if (e.stackTraceToString().contains("Connection refused")) { retryCount.incrementAndGet() delay(10000) @@ -131,112 +141,135 @@ class ProjectContextProvider(val project: Project, private val encoderServer: En private fun initEncryption(): Boolean { logger.info { "project context: init key for ${project.guessProjectDir()} on port ${encoderServer.port}" } - val url = URL("http://localhost:${encoderServer.port}/initialize") - val payload = encoderServer.getEncryptionRequest() - val connection = url.openConnection() as HttpURLConnection - setConnectionProperties(connection) - setConnectionRequest(connection, payload) - logger.info { "project context initialize response code: ${connection.responseCode} for ${project.name}" } - return connection.responseCode == 200 + val request = encoderServer.getEncryptionRequest() + val response = sendMsgToLsp(LspApi.Initialize, request) + return response.responseCode == 200 } fun index(): Boolean { logger.info { "project context: indexing ${project.name} on port ${encoderServer.port}" } val indexStartTime = System.currentTimeMillis() - val url = URL("http://localhost:${encoderServer.port}/indexFiles") val filesResult = collectFiles() var duration = (System.currentTimeMillis() - indexStartTime).toDouble() logger.debug { "project context file collection time: ${duration}ms" } - logger.debug { "list of files collected: ${filesResult.files.joinToString("\n")}" } + logger.debug { "collected ${filesResult.files.size} files" } val projectRoot = project.guessProjectDir()?.path ?: return false - val payload = IndexRequestPayload(filesResult.files, projectRoot, false) + + val payload = IndexRequestV2(filesResult.files, projectRoot, "all", "") val payloadJson = mapper.writeValueAsString(payload) val encrypted = encoderServer.encrypt(payloadJson) - val connection = url.openConnection() as HttpURLConnection - setConnectionProperties(connection) - setConnectionRequest(connection, encrypted) - logger.info { "project context index response code: ${connection.responseCode} for ${project.name}" } + val response = sendMsgToLsp(LspApi.BuildIndex, encrypted) + duration = (System.currentTimeMillis() - indexStartTime).toDouble() val startUrl = getStartUrl(project) logger.debug { "project context index time: ${duration}ms" } - if (connection.responseCode == 200) { + + if (response.responseCode == 200) { val usage = getUsage() - TelemetryHelper.recordIndexWorkspace(duration, filesResult.files.size, filesResult.fileSize, true, usage?.memoryUsage, usage?.cpuUsage, startUrl) + recordIndexWorkspace(duration, filesResult.files.size, filesResult.fileSize, true, usage?.memoryUsage, usage?.cpuUsage, startUrl) logger.debug { "project context index finished for ${project.name}" } return true } else { - TelemetryHelper.recordIndexWorkspace(duration, filesResult.files.size, filesResult.fileSize, false, null, null, startUrl) + recordIndexWorkspace(duration, filesResult.files.size, filesResult.fileSize, false, null, null, startUrl) return false } } - fun query(prompt: String): List { - logger.info { "project context: querying ${project.name} on port ${encoderServer.port}" } - val url = URL("http://localhost:${encoderServer.port}/query") + fun updateIndex(filePaths: List, mode: String) { + // TODO: do we need this? + // it might result in dirty stale data? also we have eventQueue in the LSP so it should be fine? + if (!isIndexComplete.get()) return + + val payload = UpdateIndexRequestV2(filePaths, mode) + val encrypted = encoderServer.encrypt(mapper.writeValueAsString(payload)) + + sendMsgToLsp(LspApi.UpdateIndex, encrypted) + } + + fun queryChat(prompt: String): List { val payload = QueryRequestPayload(prompt) val payloadJson = mapper.writeValueAsString(payload) val encrypted = encoderServer.encrypt(payloadJson) - val connection = url.openConnection() as HttpURLConnection - setConnectionProperties(connection) - setConnectionTimeout(connection) - setConnectionRequest(connection, encrypted) + val response = sendMsgToLsp(LspApi.QueryChat, encrypted) - val responseCode = connection.responseCode - logger.info { "project context query response code: $responseCode for $prompt" } - val responseBody = if (responseCode == 200) { - connection.inputStream.bufferedReader().use { reader -> reader.readText() } - } else { - "" + return try { + val parsedResponse = mapper.readValue>(response.responseBody) + queryResultToRelevantDocuments(parsedResponse) + } catch (e: Exception) { + logger.warn { "error parsing query response ${e.message}" } + emptyList() } - connection.disconnect() - try { - val parsedResponse = mapper.readValue>(responseBody) - return queryResultToRelevantDocuments(parsedResponse) + } + + fun queryInline(prompt: String, filePath: String): List { + val payload = QueryRequestV2(prompt, filePath) + val payloadJson = mapper.writeValueAsString(payload) + val encrypted = encoderServer.encrypt(payloadJson) + + val response = sendMsgToLsp(LspApi.QueryInline, encrypted) + + return try { + mapper.readValue>(response.responseBody) } catch (e: Exception) { logger.warn { "error parsing query response ${e.message}" } - return emptyList() + throw e } } + private fun recordIndexWorkspace( + duration: Double, + fileCount: Int = 0, + fileSize: Int = 0, + isSuccess: Boolean, + memoryUsage: Int? = 0, + cpuUsage: Int? = 0, + startUrl: String? = null, + ) { + AmazonqTelemetry.indexWorkspace( + project = null, + duration = duration, + amazonqIndexFileCount = fileCount.toLong(), + amazonqIndexFileSizeInMB = fileSize.toLong(), + success = isSuccess, + amazonqIndexMemoryUsageInMB = memoryUsage?.toLong(), + amazonqIndexCpuUsagePercentage = cpuUsage?.toLong(), + credentialStartUrl = startUrl + ) + } + private fun getUsage(): Usage? { - logger.info { "project context: getting usage for ${project.name} on port ${encoderServer.port}" } - val url = URL("http://localhost:${encoderServer.port}/getUsage") - val connection = url.openConnection() as HttpURLConnection - setConnectionProperties(connection) - val responseCode = connection.responseCode - - logger.info { "project context getUsage response code: $responseCode for ${project.name} " } - val responseBody = if (responseCode == 200) { - connection.inputStream.bufferedReader().use { reader -> reader.readText() } - } else { - "" - } - connection.disconnect() - try { - val parsedResponse = mapper.readValue(responseBody) - return parsedResponse + val response = sendMsgToLsp(LspApi.GetUsageMetrics, null) + return try { + mapper.readValue(response.responseBody) } catch (e: Exception) { logger.warn { "error parsing query response ${e.message}" } return null } } - fun updateIndex(filePath: String) { - if (!isIndexComplete.get()) return - logger.info { "project context: updating index for $filePath on port ${encoderServer.port}" } - val url = URL("http://localhost:${encoderServer.port}/updateIndex") - val payload = UpdateIndexRequestPayload(filePath) - val payloadJson = mapper.writeValueAsString(payload) - val encrypted = encoderServer.encrypt(payloadJson) - with(url.openConnection() as HttpURLConnection) { + // TODO: make messageType sealed object + private fun sendMsgToLsp(msgType: LspApi, request: String?): LspResponse { + logger.info { "sending message: ${msgType.command} to lsp on port ${encoderServer.port}" } + val url = URL("http://localhost:${encoderServer.port}/${msgType.command}") + + return with(url.openConnection() as HttpURLConnection) { setConnectionProperties(this) setConnectionTimeout(this) - setConnectionRequest(this, encrypted) - val responseCode = responseCode - logger.debug { "project context update index response code: $responseCode for $filePath" } - return + request?.let { r -> + setConnectionRequest(this, r) + } + val responseCode = this.responseCode + logger.info { "receiving response for $msgType with responseCode $responseCode" } + + val responseBody = if (responseCode == 200) { + this.inputStream.bufferedReader().use { reader -> reader.readText() } + } else { + "" + } + + LspResponse(responseCode, responseBody) } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/RelevantDocument.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/RelevantDocument.kt similarity index 72% rename from plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/RelevantDocument.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/RelevantDocument.kt index d77ade0f5dc..be4565ba8a3 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/RelevantDocument.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/RelevantDocument.kt @@ -1,7 +1,7 @@ // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project +package software.aws.toolkits.jetbrains.services.amazonq.project data class RelevantDocument( val relativeFilePath: String, diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/manifest/ManifestManager.kt similarity index 94% rename from plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/manifest/ManifestManager.kt index 383eeffd78d..b79dac18936 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/editor/context/project/manifest/ManifestManager.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/project/manifest/ManifestManager.kt @@ -1,7 +1,7 @@ // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.cwc.editor.context.project.manifest +package software.aws.toolkits.jetbrains.services.amazonq.project.manifest import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty @@ -14,8 +14,8 @@ import software.aws.toolkits.core.utils.warn import software.aws.toolkits.jetbrains.core.getTextFromUrl class ManifestManager { - private val cloudFrontUrl = "https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json" - val currentVersion = "0.1.10" + private val cloudFrontUrl = "https://ducvaeoffl85c.cloudfront.net/manifest-0.1.15.json" + val currentVersion = "0.1.15" val currentOs = getOs() private val arch = CpuArch.CURRENT private val mapper = jacksonObjectMapper() diff --git a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererSettings.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/CodeWhispererSettings.kt similarity index 96% rename from plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererSettings.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/CodeWhispererSettings.kt index d4adf2364c7..1619ae3f7a2 100644 --- a/plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/settings/CodeWhispererSettings.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/CodeWhispererSettings.kt @@ -1,7 +1,7 @@ // Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -package software.aws.toolkits.jetbrains.services.codewhisperer.settings +package software.aws.toolkits.jetbrains.settings import com.intellij.openapi.components.BaseState import com.intellij.openapi.components.PersistentStateComponent @@ -11,7 +11,7 @@ import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage import com.intellij.openapi.components.service import com.intellij.util.xmlb.annotations.Property -import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService @Service @State(name = "codewhispererSettings", storages = [Storage("aws.xml", roamingType = RoamingType.DISABLED)])