diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt index 27ec40a7894..652b73ddf9e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/Browser.kt @@ -11,7 +11,6 @@ import com.intellij.openapi.util.Disposer import com.intellij.ui.jcef.JBCefJSQuery 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.flareChat.FlareUiMessage import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfile import software.aws.toolkits.jetbrains.services.amazonq.util.HighlightCommand @@ -114,7 +113,7 @@ class Browser(parent: Disposable, private val webUri: URI, val project: Project) ): 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 = """ @@ -266,10 +265,6 @@ class Browser(parent: Disposable, private val webUri: URI, val project: Project) 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() diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt index 915a3a23343..f32a2f07aa3 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt @@ -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 @@ -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 @@ -567,15 +567,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 @@ -588,7 +592,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 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 89069f490e7..04da9d08b02 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 @@ -129,7 +129,7 @@ open class CodeWhispererTestBase { get() = CompletableFuture() override val initializeResult: Deferred - get() = CompletableDeferred(AwsExtendedInitializeResult()) + get() = CompletableDeferred(AwsExtendedInitializeResult(mockk())) override val encryptionManager: JwtEncryptionManager get() = TODO("Not yet implemented") diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt index 9f115b05776..75c037f86f2 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQLspService.kt @@ -76,7 +76,6 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.auth.DefaultAuthCred 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 @@ -155,7 +154,7 @@ class AmazonQLspService @VisibleForTesting constructor( constructor(project: Project, cs: CoroutineScope) : this(DefaultAmazonQServerInstanceStarter, project, cs) private val _flowInstance = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) - val instanceFlow = _flowInstance.asSharedFlow().map { it.languageServer } + val instanceFlow = _flowInstance.asSharedFlow() private var instance: Deferred @@ -533,11 +532,6 @@ private class AmazonQServerInstance(private val project: Project, private val cs } } - if (message is ResponseMessage && message.result is AwsExtendedInitializeResult) { - val result = message.result as AwsExtendedInitializeResult - AwsServerCapabilitiesProvider.getInstance(project).setAwsServerCapabilities(result.getAwsServerCapabilities()) - } - // required consumer?.consume(message) } diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AmazonQLspTypeAdapterFactory.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AmazonQLspTypeAdapterFactory.kt index 89d76c205c3..c26ca85d37a 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AmazonQLspTypeAdapterFactory.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AmazonQLspTypeAdapterFactory.kt @@ -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 { @@ -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() diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/ExtendedClientMetadata.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/ExtendedClientMetadata.kt index 9b6cb857ea4..b74737c8a1d 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/ExtendedClientMetadata.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/ExtendedClientMetadata.kt @@ -17,18 +17,18 @@ 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, val pinnedContextEnabled: Boolean, val workspaceFilePath: String?, ) -data class WindowSettings( +data class WindowCapabilities( val showSaveFileDialog: Boolean, ) @@ -62,13 +62,13 @@ fun createExtendedClientMetadata(project: Project): ExtendedClientMetadata { name = metadata.parentProduct ), awsClientCapabilities = AwsClientCapabilities( - q = DeveloperProfiles( + q = QCapabilities( developerProfiles = true, mcp = true, pinnedContextEnabled = true, workspaceFilePath = project.workspaceFile?.path, ), - window = WindowSettings( + window = WindowCapabilities( showSaveFileDialog = true ) ), diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AwsServerCapabilitiesProvider.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/AwsServerCapabilities.kt similarity index 51% rename from plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AwsServerCapabilitiesProvider.kt rename to plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/AwsServerCapabilities.kt index 4055b8381a5..faf3639109b 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AwsServerCapabilitiesProvider.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/AwsServerCapabilities.kt @@ -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() - - 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, ) @@ -48,6 +14,7 @@ data class ChatOptions( val history: Boolean, val export: Boolean, val mcpServers: Boolean, + val modelSelection: Boolean, ) data class QuickActions( diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/ChatPrompt.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/ChatPrompt.kt index 80e39191891..0d22f7bee64 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/ChatPrompt.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/ChatPrompt.kt @@ -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, diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/SendChatPrompt.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/SendChatPrompt.kt index 136f9adc336..8a20f696a97 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/SendChatPrompt.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/SendChatPrompt.kt @@ -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,