Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
39f2f5b
add message and data classes
samgst-amazon Mar 17, 2025
7204f2a
server config support for includeSuggestionsWithCodeReferences
samgst-amazon Mar 17, 2025
7b41616
Update plugins/amazonq/shared/jetbrains-community/src/software/aws/to…
samgst-amazon Mar 18, 2025
497cbdb
Merge branch 'feature/q-lsp' into samgst/q-lsp-aws-config
samgst-amazon Mar 18, 2025
430bf1b
data classes
samgst-amazon Mar 18, 2025
0b95441
send inlineCompletionParams to lsp
samgst-amazon Mar 18, 2025
dad393e
handler for aws/textDocument
samgst-amazon Mar 19, 2025
8a93408
add to existing textDocumentServiceHandler
samgst-amazon Mar 19, 2025
fa5b08a
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 19, 2025
37c88e3
detekt
samgst-amazon Mar 20, 2025
ae44899
code scan
samgst-amazon Mar 20, 2025
4f62d74
didOpen captures already open files in IDE
samgst-amazon Mar 21, 2025
c9cdb9e
Merge branch 'samgst/q-lsp-didOpen-init' into samgst/q-lsp-inlineComp…
samgst-amazon Mar 24, 2025
a2afd32
add more listeners to handler
samgst-amazon Mar 24, 2025
ee72f6d
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 24, 2025
8af0bb3
move call into codewhispererService
samgst-amazon Mar 26, 2025
e60ee13
add call
samgst-amazon Mar 26, 2025
72d1c1f
triggerType passed through
samgst-amazon Mar 26, 2025
9cfb452
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 26, 2025
bf77c91
ReadAction for param building
samgst-amazon Mar 27, 2025
2ddd138
test
samgst-amazon Mar 27, 2025
6ebef65
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 27, 2025
7bf9e83
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 31, 2025
8eca4ad
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Mar 31, 2025
a5c4c1a
Merge branch 'feature/q-lsp' into samgst/q-lsp-inlineCompletion
samgst-amazon Apr 1, 2025
87292a0
Merge branch 'main' into samgst/q-lsp-inlineCompletion
samgst-amazon Apr 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.intellij.notification.NotificationAction
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationInfo
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.components.Service
Expand All @@ -29,6 +30,8 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.TextDocumentIdentifier
import software.amazon.awssdk.core.exception.SdkServiceException
import software.amazon.awssdk.core.util.DefaultSdkAutoConstructList
import software.amazon.awssdk.services.codewhispererruntime.model.CodeWhispererRuntimeException
Expand All @@ -54,6 +57,10 @@ import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection
import software.aws.toolkits.jetbrains.services.amazonq.SUPPLEMENTAL_CONTEXT_TIMEOUT
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionContext
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.GetConfigurationFromServerParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LspServerConfigurations
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager
Expand Down Expand Up @@ -212,6 +219,7 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable {
return
}

handleLspInlineCompletion(editor, triggerTypeInfo)
invokeCodeWhispererInBackground(requestContext)
}

Expand Down Expand Up @@ -536,6 +544,15 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable {
return nextStates
}

fun handleLspInlineCompletion(editor: Editor, triggerType: TriggerTypeInfo) {
editor.project?.let { project ->
AmazonQLspService.executeIfRunning(project) { server ->
val params = createInlineCompletionParams(editor, triggerType)
server.inlineCompletionWithReferences(params)
}
}
}

private fun initStates(
requestContext: RequestContext,
responseContext: ResponseContext,
Expand Down Expand Up @@ -752,6 +769,26 @@ class CodeWhispererService(private val cs: CoroutineScope) : Disposable {
return states
}

private fun createInlineCompletionParams(editor: Editor, triggerTypeInfo: TriggerTypeInfo): InlineCompletionWithReferencesParams =
ReadAction.compute<InlineCompletionWithReferencesParams, RuntimeException> {
InlineCompletionWithReferencesParams(
context = InlineCompletionContext(
// Map the triggerTypeInfo to appropriate InlineCompletionTriggerKind
triggerKind = when (triggerTypeInfo.triggerType) {
CodewhispererTriggerType.OnDemand -> InlineCompletionTriggerKind.Invoke
CodewhispererTriggerType.AutoTrigger -> InlineCompletionTriggerKind.Automatic
else -> InlineCompletionTriggerKind.Invoke
}
)
).apply {
textDocument = TextDocumentIdentifier(toUriString(editor.virtualFile))
position = Position(
editor.caretModel.primaryCaret.visualPosition.line,
editor.caretModel.primaryCaret.offset
)
}
}

private fun addPopupChildDisposables(popup: JBPopup) {
codeInsightSettingsFacade.disableCodeInsightUntil(popup)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
package software.aws.toolkits.jetbrains.services.codewhisperer

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.ui.popup.JBPopup
import com.intellij.psi.PsiFile
import com.intellij.testFramework.DisposableRule
import com.intellij.testFramework.replaceService
import com.intellij.testFramework.runInEdtAndWait
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.mock
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doReturn
Expand All @@ -31,6 +35,12 @@ 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.lsp.AmazonQLanguageServer
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionTriggerKind
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.FileUriUtil.toUriString
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
Expand All @@ -51,6 +61,7 @@ import software.aws.toolkits.jetbrains.services.codewhisperer.telemetry.CodeWhis
import software.aws.toolkits.jetbrains.services.codewhisperer.util.FileContextProvider
import software.aws.toolkits.jetbrains.utils.rules.JavaCodeInsightTestFixtureRule
import software.aws.toolkits.telemetry.CodewhispererTriggerType
import java.util.concurrent.CompletableFuture

class CodeWhispererServiceTest {
@Rule
Expand Down Expand Up @@ -231,6 +242,46 @@ class CodeWhispererServiceTest {
assertThat(firstValue.supplementalContexts()).isEqualTo(mockSupContext.toSdkModel())
}
}

@Test
fun `test handleInlineCompletion creates correct params and sends to server`() = runTest {
val mockLspServer = mock(AmazonQLanguageServer::class.java)
val mockLspService = mock(AmazonQLspService::class.java)
val project = projectRule.project

project.replaceService(
AmazonQLspService::class.java,
mockLspService,
disposableRule.disposable
)
whenever(mockLspService.executeSync<CompletableFuture<ResponseMessage>>(any())).thenAnswer { invocation ->
val func = invocation.getArgument<suspend AmazonQLspService.(AmazonQLanguageServer) -> CompletableFuture<ResponseMessage>>(0)
runBlocking {
func.invoke(mockLspService, mockLspServer)
}
}

val mockEditor = projectRule.fixture.editor
val mockCompletableFuture = CompletableFuture<InlineCompletionListWithReferences>()

whenever(mockLspServer.inlineCompletionWithReferences(any())).thenReturn(mockCompletableFuture)
val paramsCaptor = argumentCaptor<InlineCompletionWithReferencesParams>()

sut.handleLspInlineCompletion(
mockEditor,
TriggerTypeInfo(CodewhispererTriggerType.OnDemand, CodeWhispererAutomatedTriggerType.Unknown())
)

verify(mockLspServer).inlineCompletionWithReferences(paramsCaptor.capture())

runReadAction {
val capturedParams = paramsCaptor.firstValue
assertThat(capturedParams.textDocument.uri).isEqualTo(toUriString(file.virtualFile))
assertThat(capturedParams.position.line).isEqualTo(mockEditor.caretModel.primaryCaret.visualPosition.line)
assertThat(capturedParams.position.character).isEqualTo(mockEditor.caretModel.primaryCaret.offset)
assertThat(capturedParams.context.triggerKind).isEqualTo(InlineCompletionTriggerKind.Invoke)
}
}
}

private fun CodeWhispererProgrammingLanguage.toSdkModel(): ProgrammingLanguage = ProgrammingLanguage.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LspServerC
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.UpdateConfigurationParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.credentials.UpdateCredentialsPayload
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.dependencies.DidChangeDependencyPathsParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionListWithReferences
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument.InlineCompletionWithReferencesParams
import java.util.concurrent.CompletableFuture

/**
* Remote interface exposed by the Amazon Q language server
*/
@Suppress("unused")
interface AmazonQLanguageServer : LanguageServer {
@JsonRequest("aws/textDocument/inlineCompletionWithReferences")
fun inlineCompletionWithReferences(params: InlineCompletionWithReferencesParams): CompletableFuture<InlineCompletionListWithReferences>

@JsonNotification("aws/didChangeDependencyPaths")
fun didChangeDependencyPaths(params: DidChangeDependencyPathsParams): CompletableFuture<Unit>

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

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

data class InlineCompletionContext(
var triggerKind: InlineCompletionTriggerKind,
var selectedCompletionInfo: SelectedCompletionInfo? = null,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

data class InlineCompletionItem(
var itemId: String,
var insertText: String,
var references: List<InlineCompletionReference>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

data class InlineCompletionListWithReferences(
var items: List<InlineCompletionItem>,
var sessionId: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

data class InlineCompletionReference(
var referenceName: String,
var referenceUrl: String,
var licenseName: String,
var position: InlineCompletionReferencePosition,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

data class InlineCompletionReferencePosition(
var startCharacter: Int = 0,
var endCharacter: Int = 0,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

enum class InlineCompletionTriggerKind(val value: Int) {
Invoke(0),
Automatic(1),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

import org.eclipse.lsp4j.TextDocumentPositionAndWorkDoneProgressParams

data class InlineCompletionWithReferencesParams(
var context: InlineCompletionContext,
) : TextDocumentPositionAndWorkDoneProgressParams()
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.textDocument

import org.eclipse.lsp4j.Range

data class SelectedCompletionInfo(
var text: String,
var range: Range,
)
Loading