Skip to content

fix(amazonq): delete AwsServerCapabilitiesProvider #5833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.ui.jcef.JBCefJSQuery
import kotlinx.coroutines.flow.first

Check warning on line 12 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive

Check warning

Code scanning / QDJVMC

Unused import directive Warning

Unused import directive
import org.cef.CefApp
import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigService
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService

Check warning on line 15 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive

Check warning

Code scanning / QDJVMC

Unused import directive Warning

Unused import directive
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfile
import software.aws.toolkits.jetbrains.services.amazonq.util.HighlightCommand
Expand Down Expand Up @@ -114,7 +115,7 @@
): String {
val postMessageToJavaJsCode = receiveMessageQuery.inject("JSON.stringify(message)")
val connectorAdapterPath = "http://mynah/js/connectorAdapter.js"
generateQuickActionConfig()

// https://github.com/highlightjs/highlight.js/issues/1387
// language=HTML
val jsScripts = """
Expand Down Expand Up @@ -257,10 +258,6 @@
activeProfile
}

private fun generateQuickActionConfig() = AwsServerCapabilitiesProvider.getInstance(project).getChatOptions().quickActions.quickActionsCommandGroups
.let { OBJECT_MAPPER.writeValueAsString(it) }
?: "[]"

companion object {
private const val MAX_ONBOARDING_PAGE_COUNT = 3
private val OBJECT_MAPPER = jacksonObjectMapper()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
Expand All @@ -40,7 +41,6 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.JsonRpcMethod
import software.aws.toolkits.jetbrains.services.amazonq.lsp.JsonRpcNotification
import software.aws.toolkits.jetbrains.services.amazonq.lsp.JsonRpcRequest
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatAsyncResultManager
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
Expand Down Expand Up @@ -535,15 +535,19 @@ class BrowserConnector(
browser.postChat(cancelMessage)
}

private fun updateQuickActionsInBrowser(browser: Browser) {
private suspend fun updateQuickActionsInBrowser(browser: Browser) {
val isFeatureDevAvailable = isFeatureDevAvailable(project)
val isCodeTransformAvailable = isCodeTransformAvailable(project)
val isDocAvailable = isDocAvailable(project)
val isCodeScanAvailable = isCodeScanAvailable(project)
val isCodeTestAvailable = isCodeTestAvailable(project)

val serverCapabilities = AmazonQLspService.getInstance(project).instanceFlow.first().initializeResult.await().awsServerCapabilities

// language=JavaScript
val script = """
try {
// hack to create the list of actions across all tab types
const tempConnector = connectorAdapter.initiateAdapter(
false,
true, // the two values are not used here, needed for constructor
Expand All @@ -556,7 +560,7 @@ class BrowserConnector(
);

const commands = tempConnector.initialQuickActions?.slice(0, 2) || [];
const options = ${Gson().toJson(AwsServerCapabilitiesProvider.getInstance(project).getChatOptions())};
const options = ${Gson().toJson(serverCapabilities.chatOptions)};
options.quickActions.quickActionsCommandGroups = [
...commands,
...options.quickActions.quickActionsCommandGroups
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.map

Check warning on line 40 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import kotlinx.coroutines.future.asCompletableFuture
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
Expand All @@ -50,7 +51,7 @@
import org.eclipse.lsp4j.DidChangeConfigurationParams
import org.eclipse.lsp4j.FileOperationsWorkspaceCapabilities
import org.eclipse.lsp4j.InitializeParams
import org.eclipse.lsp4j.InitializeResult

Check warning on line 54 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import org.eclipse.lsp4j.InitializedParams
import org.eclipse.lsp4j.SynchronizationCapabilities
import org.eclipse.lsp4j.TextDocumentClientCapabilities
Expand All @@ -59,7 +60,6 @@
import org.eclipse.lsp4j.jsonrpc.MessageConsumer
import org.eclipse.lsp4j.jsonrpc.RemoteEndpoint
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod
import org.eclipse.lsp4j.jsonrpc.messages.ResponseMessage
import org.eclipse.lsp4j.launch.LSPLauncher
import org.slf4j.event.Level
import software.aws.toolkits.core.utils.debug
Expand All @@ -74,7 +74,6 @@
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AmazonQLspTypeAdapterFactory
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsExtendedInitializeResult
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.createExtendedClientMetadata
import software.aws.toolkits.jetbrains.services.amazonq.lsp.textdocument.TextDocumentServiceHandler
import software.aws.toolkits.jetbrains.services.amazonq.lsp.util.WorkspaceFolderUtil.createWorkspaceFolders
Expand All @@ -91,8 +90,8 @@
import java.io.OutputStreamWriter
import java.io.PipedInputStream
import java.io.PipedOutputStream
import java.io.PrintWriter

Check warning on line 93 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import java.io.StringWriter

Check warning on line 94 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused import directive

Unused import directive
import java.net.Proxy
import java.net.URI
import java.nio.charset.StandardCharsets
Expand Down Expand Up @@ -138,11 +137,9 @@
@Service(Service.Level.PROJECT)
class AmazonQLspService(private val project: Project, private val cs: CoroutineScope) : Disposable {
private val _flowInstance = MutableSharedFlow<AmazonQServerInstance>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
val instanceFlow = _flowInstance.asSharedFlow().map { it.languageServer }
val instanceFlow: Flow<AmazonQServerInstanceFacade> = _flowInstance.asSharedFlow()

private var instance: Deferred<AmazonQServerInstance>
val capabilities
get() = instance.getCompleted().initializeResult.getCompleted().capabilities

val encryptionManager
get() = instance.getCompleted().encryptionManager
Expand Down Expand Up @@ -312,12 +309,17 @@
}
}

private class AmazonQServerInstance(private val project: Project, private val cs: CoroutineScope) : Disposable {
interface AmazonQServerInstanceFacade {
val languageServer: AmazonQLanguageServer
val initializeResult: Deferred<AwsExtendedInitializeResult>
}

private class AmazonQServerInstance(private val project: Project, private val cs: CoroutineScope) : Disposable, AmazonQServerInstanceFacade {
val encryptionManager = JwtEncryptionManager()

private val launcher: Launcher<AmazonQLanguageServer>

val languageServer: AmazonQLanguageServer
override val languageServer: AmazonQLanguageServer
get() = launcher.remoteProxy

val rawEndpoint: RemoteEndpoint
Expand All @@ -326,7 +328,7 @@
@Suppress("ForbiddenVoid")
val launcherFuture: Future<Void>
private val launcherHandler: KillableProcessHandler
val initializeResult: Deferred<InitializeResult>
override val initializeResult: Deferred<AwsExtendedInitializeResult>

private fun createClientCapabilities(): ClientCapabilities =
ClientCapabilities().apply {
Expand Down Expand Up @@ -479,10 +481,12 @@
}
.wrapMessages { consumer ->
MessageConsumer { message ->
if (message is ResponseMessage && message.result is AwsExtendedInitializeResult) {
val result = message.result as AwsExtendedInitializeResult
AwsServerCapabilitiesProvider.getInstance(project).setAwsServerCapabilities(result.getAwsServerCapabilities())
}
// logging
val traceLogger = LOG.atLevel(if (isDeveloperMode()) Level.INFO else Level.DEBUG)
val direction = if (consumer is RemoteEndpoint) "Sent" else "Received"
traceLogger.log { "$direction: $message" }

// required
consumer?.consume(message)
}
}
Expand All @@ -495,18 +499,7 @@
// otherwise Gson treats all numbers as double which causes deser issues
it.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
it.registerTypeAdapterFactory(AmazonQLspTypeAdapterFactory())
}.traceMessages(
PrintWriter(
object : StringWriter() {
private val traceLogger = LOG.atLevel(if (isDeveloperMode()) Level.INFO else Level.DEBUG)

override fun flush() {
traceLogger.log { buffer.toString() }
buffer.setLength(0)
}
}
)
)
}
.setInput(inputWrapper.inputStream)
.setOutput(launcherHandler.process.outputStream)
.create()
Expand All @@ -531,7 +524,7 @@
}
languageServer.initialized(InitializedParams())

initializeResult
initializeResult as AwsExtendedInitializeResult
}

// invokeOnCompletion results in weird lock/timeout error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import org.eclipse.lsp4j.InitializeResult
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.AwsServerCapabilities
import java.io.IOException

class AmazonQLspTypeAdapterFactory : TypeAdapterFactory {
Expand All @@ -32,12 +33,4 @@ class AmazonQLspTypeAdapterFactory : TypeAdapterFactory {
}
}

class AwsExtendedInitializeResult(awsServerCapabilities: AwsServerCapabilities? = null) : InitializeResult() {
private var awsServerCapabilities: AwsServerCapabilities? = null

fun getAwsServerCapabilities(): AwsServerCapabilities? = awsServerCapabilities

fun setAwsServerCapabilities(awsServerCapabilities: AwsServerCapabilities?) {
this.awsServerCapabilities = awsServerCapabilities
}
}
data class AwsExtendedInitializeResult(val awsServerCapabilities: AwsServerCapabilities) : InitializeResult()
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ data class AwsMetadata(
)

data class AwsClientCapabilities(
val q: DeveloperProfiles,
val window: WindowSettings,
val q: QCapabilities,
val window: WindowCapabilities,
)

data class DeveloperProfiles(
data class QCapabilities(
val developerProfiles: Boolean,
val mcp: Boolean,
)

data class WindowSettings(
data class WindowCapabilities(
val showSaveFileDialog: Boolean,
)

Expand Down Expand Up @@ -60,11 +60,11 @@ fun createExtendedClientMetadata(project: Project): ExtendedClientMetadata {
name = metadata.parentProduct
),
awsClientCapabilities = AwsClientCapabilities(
q = DeveloperProfiles(
q = QCapabilities(
developerProfiles = true,
mcp = true
),
window = WindowSettings(
window = WindowCapabilities(
showSaveFileDialog = true
)
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +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.flareChat
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws

import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.IconType

@Service(Service.Level.PROJECT)
class AwsServerCapabilitiesProvider {
private var serverCapabilities: AwsServerCapabilities? = null

fun setAwsServerCapabilities(serverCapabilities: AwsServerCapabilities?) {
this.serverCapabilities = serverCapabilities
}

fun getChatOptions() = serverCapabilities?.chatOptions ?: DEFAULT_CHAT_OPTIONS

companion object {
fun getInstance(project: Project) = project.service<AwsServerCapabilitiesProvider>()

private val DEFAULT_CHAT_OPTIONS: ChatOptions = ChatOptions(
QuickActions(
listOf(
QuickActionsCommandGroups(
listOf(
QuickActionCommand("/help", "Learn more about Amazon Q then"),
QuickActionCommand("/clear", "Clear this session")
)
)
)
),
history = true,
export = true,
mcpServers = true
)
}
}

data class AwsServerCapabilities(
val chatOptions: ChatOptions,
)
Expand All @@ -48,6 +14,7 @@ data class ChatOptions(
val history: Boolean,
val export: Boolean,
val mcpServers: Boolean,
val modelSelection: Boolean,
)

data class QuickActions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat

import com.fasterxml.jackson.annotation.JsonProperty
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ContextCommand
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.ContextCommand

data class ChatPrompt(
val prompt: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
package software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat

import org.eclipse.lsp4j.TextDocumentIdentifier
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ContextCommand
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.ContextCommand

data class ChatParams(
val tabId: String,
Expand Down
Loading