Skip to content

Commit 9fa33e8

Browse files
Merge branch 'main' into samgst/q-chat-reauth-profile-select-bug
2 parents 1f4d52e + ba228e1 commit 9fa33e8

File tree

17 files changed

+192
-24
lines changed

17 files changed

+192
-24
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type" : "feature",
3+
"description" : "Support for Amazon Q Builder ID paid tier"
4+
}

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/QRefreshPanelAction.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,25 @@ import com.intellij.openapi.actionSystem.AnActionEvent
99
import com.intellij.openapi.application.ApplicationManager
1010
import com.intellij.openapi.project.DumbAwareAction
1111
import com.intellij.util.messages.Topic
12+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
13+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
14+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CHAT_TAB_REMOVE
1215
import software.aws.toolkits.jetbrains.services.amazonq.toolwindow.AmazonQToolWindow
1316
import software.aws.toolkits.resources.AmazonQBundle
1417
import java.util.EventListener
1518

1619
class QRefreshPanelAction : DumbAwareAction(AmazonQBundle.message("amazonq.refresh.panel"), null, AllIcons.Actions.Refresh) {
1720
override fun actionPerformed(e: AnActionEvent) {
1821
val project = e.project ?: return
22+
23+
// Notify LSP server about all open tabs being removed
24+
val chatManager = ChatCommunicationManager.getInstance(project)
25+
chatManager.getAllTabIds().forEach { tabId ->
26+
AmazonQLspService.executeIfRunning(project) { server ->
27+
rawEndpoint.notify(CHAT_TAB_REMOVE, mapOf("tabId" to tabId))
28+
}
29+
}
30+
1931
// recreate chat browser
2032
AmazonQToolWindow.getInstance(project).disposeAndRecreate()
2133
// recreate signin browser

plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/webview/BrowserConnector.kt

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.Encry
7272
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.EncryptedQuickActionChatParams
7373
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GET_SERIALIZED_CHAT_REQUEST_METHOD
7474
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatResponse
75+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.LIST_MCP_SERVERS_REQUEST_METHOD
76+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.MCP_SERVER_CLICK_REQUEST_METHOD
7577
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OPEN_SETTINGS
7678
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OPEN_WORKSPACE_SETTINGS_KEY
7779
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.OpenSettingsNotification
@@ -307,14 +309,19 @@ class BrowserConnector(
307309
}
308310

309311
CHAT_TAB_ADD -> {
310-
handleChat(AmazonQChatServer.tabAdd, node)
312+
handleChat(AmazonQChatServer.tabAdd, node) { params, invoke ->
313+
// Track the tab ID when a tab is added
314+
chatCommunicationManager.addTabId(params.tabId)
315+
invoke()
316+
}
311317
}
312318

313319
CHAT_TAB_REMOVE -> {
314320
handleChat(AmazonQChatServer.tabRemove, node) { params, invoke ->
315321
chatCommunicationManager.removePartialChatMessage(params.tabId)
316322
cancelInflightRequests(params.tabId)
317-
323+
// Remove the tab ID from tracking when a tab is removed
324+
chatCommunicationManager.removeTabId(params.tabId)
318325
invoke()
319326
}
320327
}
@@ -456,6 +463,28 @@ class BrowserConnector(
456463
TELEMETRY_EVENT -> {
457464
handleChat(AmazonQChatServer.telemetryEvent, node)
458465
}
466+
LIST_MCP_SERVERS_REQUEST_METHOD -> {
467+
handleChat(AmazonQChatServer.listMcpServers, node)
468+
.whenComplete { response, _ ->
469+
browser.postChat(
470+
FlareUiMessage(
471+
command = LIST_MCP_SERVERS_REQUEST_METHOD,
472+
params = response
473+
)
474+
)
475+
}
476+
}
477+
MCP_SERVER_CLICK_REQUEST_METHOD -> {
478+
handleChat(AmazonQChatServer.mcpServerClick, node)
479+
.whenComplete { response, _ ->
480+
browser.postChat(
481+
FlareUiMessage(
482+
command = MCP_SERVER_CLICK_REQUEST_METHOD,
483+
params = response
484+
)
485+
)
486+
}
487+
}
459488
}
460489
}
461490

plugins/amazonq/codewhisperer/jetbrains-community/resources/META-INF/plugin-codewhisperer.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,7 @@
139139
class="software.aws.toolkits.jetbrains.services.cwc.commands.codescan.actions.CodeScanCompleteAction" />
140140
</group>
141141

142+
<action id="q.manage.subscription"
143+
class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.ManageSubscription"/>
142144
</actions>
143145
</idea-plugin>

plugins/amazonq/codewhisperer/jetbrains-community/src/software/aws/toolkits/jetbrains/services/codewhisperer/explorer/QStatusBarLoggedInActionGroup.kt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@ import com.intellij.openapi.project.Project
1212
import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection
1313
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
1414
import software.aws.toolkits.jetbrains.core.credentials.actions.SsoLogoutAction
15-
import software.aws.toolkits.jetbrains.core.credentials.pinning.CodeWhispererConnection
1615
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
1716
import software.aws.toolkits.jetbrains.core.credentials.sono.isSono
18-
import software.aws.toolkits.jetbrains.services.amazonq.actions.QSwitchProfilesAction
1917
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager
2018
import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererConnectOnGithubAction
2119
import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererLearnMoreAction
2220
import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererProvideFeedbackAction
23-
import software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererShowSettingsAction
2421
import software.aws.toolkits.jetbrains.services.codewhisperer.codescan.actions.CodeWhispererCodeScanRunAction
2522
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.actions.ActionProvider
2623
import software.aws.toolkits.jetbrains.services.codewhisperer.explorer.actions.Customize
@@ -54,6 +51,7 @@ class QStatusBarLoggedInActionGroup : DefaultActionGroup() {
5451

5552
override fun getChildren(e: AnActionEvent?) = e?.project?.let {
5653
val isPendingActiveProfile = QRegionProfileManager.getInstance().hasValidConnectionButNoActiveProfile(it)
54+
val actionManager = ActionManager.getInstance()
5755
buildList {
5856
if (!isPendingActiveProfile) {
5957
addAll(buildActionListForActiveProfileSelected(it, actionProvider))
@@ -64,15 +62,18 @@ class QStatusBarLoggedInActionGroup : DefaultActionGroup() {
6462
addAll(buildActionListForConnectHelp(actionProvider))
6563

6664
add(Separator.create())
67-
add(CodeWhispererShowSettingsAction())
68-
(
69-
ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection
70-
)?.takeIf { !it.isSono() }
71-
?.let { add(QSwitchProfilesAction()) }
72-
ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(CodeWhispererConnection.getInstance())?.let { c ->
73-
(c as? AwsBearerTokenConnection)?.let { connection ->
74-
add(SsoLogoutAction(connection))
65+
add(actionManager.getAction("codewhisperer.settings"))
66+
67+
val connection = ToolkitConnectionManager.getInstance(it).activeConnectionForFeature(QConnection.getInstance()) as? AwsBearerTokenConnection
68+
69+
if (connection != null) {
70+
if (!connection.isSono()) {
71+
add(actionManager.getAction("codewhisperer.switchProfiles"))
72+
} else {
73+
add(actionManager.getAction("q.manage.subscription"))
7574
}
75+
76+
add(SsoLogoutAction(connection))
7677
}
7778
}.toTypedArray()
7879
}.orEmpty()

plugins/amazonq/shared/jetbrains-community/resources/software/aws/toolkits/resources/AmazonQBundle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ amazonqInlineChat.popup.title=Enter Instructions for Q
99
amazonq.refresh.panel=Refresh Chat Session
1010
amazonq.title=Amazon Q
1111
amazonq.workspace.settings.open.prompt=Workspace index is now enabled. You can disable it from Amazon Q settings.
12+
action.q.manage.subscription.text=Manage Subscription
1213
action.q.profile.usage.text=You changed your profile
1314
action.q.profile.usage=You''re using the ''<b>{0}</b>'' profile for Amazon Q.
1415
action.q.switchProfiles.text=Change Profile

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/AmazonQChatServer.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package software.aws.toolkits.jetbrains.services.amazonq.lsp
55

66
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethodProvider
7+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LSPAny
78
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ButtonClickParams
89
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ButtonClickResult
910
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CHAT_BUTTON_CLICK
@@ -37,8 +38,10 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSe
3738
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GetSerializedChatResult
3839
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.InfoLinkClickParams
3940
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.InsertToCursorPositionParams
41+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.LIST_MCP_SERVERS_REQUEST_METHOD
4042
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.LinkClickParams
4143
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ListConversationsParams
44+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.MCP_SERVER_CLICK_REQUEST_METHOD
4245
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.PROMPT_INPUT_OPTIONS_CHANGE
4346
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.PromptInputOptionChangeParams
4447
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.SEND_CHAT_COMMAND_PROMPT
@@ -174,6 +177,18 @@ object AmazonQChatServer : JsonRpcMethodProvider {
174177
Any::class.java
175178
)
176179

180+
val listMcpServers = JsonRpcRequest(
181+
LIST_MCP_SERVERS_REQUEST_METHOD,
182+
LSPAny::class.java,
183+
LSPAny::class.java
184+
)
185+
186+
val mcpServerClick = JsonRpcRequest(
187+
MCP_SERVER_CLICK_REQUEST_METHOD,
188+
LSPAny::class.java,
189+
LSPAny::class.java
190+
)
191+
177192
val conversationClick = JsonRpcRequest(
178193
CHAT_CONVERSATION_CLICK,
179194
ConversationClickParams::class.java,

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/artifacts/ArtifactHelper.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ import java.util.concurrent.atomic.AtomicInteger
2929
class ArtifactHelper(private val lspArtifactsPath: Path = DEFAULT_ARTIFACT_PATH, private val maxDownloadAttempts: Int = MAX_DOWNLOAD_ATTEMPTS) {
3030

3131
companion object {
32-
private val DEFAULT_ARTIFACT_PATH = getToolkitsCommonCacheRoot().resolve(Paths.get("aws", "toolkits", "language-servers", "AmazonQ-JetBrains-temp"))
32+
private val DEFAULT_ARTIFACT_PATH = getToolkitsCommonCacheRoot().resolve(
33+
Paths.get("aws", "toolkits", "language-servers", "AmazonQ-JetBrains-temp")
34+
)
3335
private val logger = getLogger<ArtifactHelper>()
3436
private const val MAX_DOWNLOAD_ATTEMPTS = 3
3537
}

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/AwsServerCapabilitiesProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class AwsServerCapabilitiesProvider {
3333
)
3434
),
3535
history = true,
36-
export = true
36+
export = true,
37+
mcpServers = false
3738
)
3839
}
3940
}
@@ -46,6 +47,7 @@ data class ChatOptions(
4647
val quickActions: QuickActions,
4748
val history: Boolean,
4849
val export: Boolean,
50+
val mcpServers: Boolean,
4951
)
5052

5153
data class QuickActions(

plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/flareChat/ChatCommunicationManager.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class ChatCommunicationManager(private val project: Project, private val cs: Cor
4545
private val pendingTabRequests = ConcurrentHashMap<String, CompletableFuture<LSPAny>>()
4646
private val partialResultLocks = ConcurrentHashMap<String, Any>()
4747
private val finalResultProcessed = ConcurrentHashMap<String, Boolean>()
48+
private val openTabs = mutableSetOf<String>()
4849

4950
fun setUiReady() {
5051
uiReady.complete(true)
@@ -80,6 +81,24 @@ class ChatCommunicationManager(private val project: Project, private val cs: Cor
8081
fun removePartialChatMessage(partialResultToken: String) =
8182
chatPartialResultMap.remove(partialResultToken)
8283

84+
fun addTabId(tabId: String) {
85+
synchronized(openTabs) {
86+
openTabs.add(tabId)
87+
}
88+
}
89+
90+
fun removeTabId(tabId: String) {
91+
synchronized(openTabs) {
92+
openTabs.remove(tabId)
93+
}
94+
}
95+
96+
fun getAllTabIds(): Set<String> {
97+
synchronized(openTabs) {
98+
return openTabs.toSet()
99+
}
100+
}
101+
83102
fun addSerializedChatRequest(requestId: String, result: CompletableFuture<GetSerializedChatResult>) {
84103
pendingSerializedChatRequests[requestId] = result
85104
}

0 commit comments

Comments
 (0)