Skip to content

Commit 916eabe

Browse files
committed
refactor: avoid manually crafting JSON blobs for postMessage(...)
1 parent 5ef38f7 commit 916eabe

File tree

7 files changed

+79
-56
lines changed

7 files changed

+79
-56
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.apps.AppConnection
2727
import software.aws.toolkits.jetbrains.services.amazonq.commands.MessageTypeRegistry
2828
import software.aws.toolkits.jetbrains.services.amazonq.lsp.artifacts.ArtifactManager
2929
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AsyncChatUiListener
30+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
3031
import software.aws.toolkits.jetbrains.services.amazonq.messages.AmazonQMessage
3132
import software.aws.toolkits.jetbrains.services.amazonq.messages.MessageConnector
3233
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfileManager
@@ -55,9 +56,15 @@ class AmazonQPanel(val project: Project, private val scope: CoroutineScope) : Di
5556
project.messageBus.connect().subscribe(
5657
AsyncChatUiListener.TOPIC,
5758
object : AsyncChatUiListener {
58-
override fun onChange(message: String) {
59+
override fun onChange(command: String) {
5960
runInEdt {
60-
browser.get()?.postChat(message)
61+
browser.get()?.postChat(command)
62+
}
63+
}
64+
65+
override fun onChange(command: FlareUiMessage) {
66+
runInEdt {
67+
browser.get()?.postChat(command)
6168
}
6269
}
6370
}

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

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

66
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
7+
import com.google.gson.Gson
78
import com.intellij.openapi.Disposable
89
import com.intellij.openapi.project.Project
910
import com.intellij.openapi.util.Disposer
1011
import com.intellij.ui.jcef.JBCefJSQuery
1112
import org.cef.CefApp
1213
import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
1314
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
15+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
1416
import software.aws.toolkits.jetbrains.services.amazonq.profile.QRegionProfile
1517
import software.aws.toolkits.jetbrains.services.amazonq.util.HighlightCommand
1618
import software.aws.toolkits.jetbrains.services.amazonq.util.createBrowser
@@ -62,6 +64,9 @@ class Browser(parent: Disposable, private val webUri: URI, val project: Project)
6264

6365
fun component() = jcefBrowser.component
6466

67+
fun postChat(command: FlareUiMessage) = postChat(Gson().toJson(command))
68+
69+
@Deprecated("shouldn't need this version")
6570
fun postChat(message: String) {
6671
jcefBrowser
6772
.cefBrowser

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import software.aws.toolkits.jetbrains.services.amazonq.lsp.AmazonQLspService
3232
import software.aws.toolkits.jetbrains.services.amazonq.lsp.encryption.JwtEncryptionManager
3333
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AwsServerCapabilitiesProvider
3434
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
35+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
3536
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.getTextDocumentIdentifier
3637
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ButtonClickNotification
3738
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.ButtonClickParams
@@ -256,7 +257,9 @@ class BrowserConnector(
256257
var encryptionManager: JwtEncryptionManager? = null
257258
val result = AmazonQLspService.executeIfRunning(project) { server ->
258259
encryptionManager = this.encryptionManager
259-
encryptionManager?.encrypt(chatParams)?.let { EncryptedChatParams(it, partialResultToken) }?.let { server.sendChatPrompt(it) }
260+
261+
val encryptedParams = EncryptedChatParams(this.encryptionManager.encrypt(chatParams), partialResultToken)
262+
server.sendChatPrompt(encryptedParams)
260263
} ?: (CompletableFuture.failedFuture(IllegalStateException("LSP Server not running")))
261264

262265
// We assume there is only one outgoing request per tab because the input is
@@ -272,11 +275,9 @@ class BrowserConnector(
272275
var encryptionManager: JwtEncryptionManager? = null
273276
val result = AmazonQLspService.executeIfRunning(project) { server ->
274277
encryptionManager = this.encryptionManager
275-
encryptionManager?.encrypt(quickActionParams)?.let {
276-
EncryptedQuickActionChatParams(it, partialResultToken)
277-
}?.let {
278-
server.sendQuickAction(it)
279-
}
278+
279+
val encryptedParams = EncryptedQuickActionChatParams(this.encryptionManager.encrypt(quickActionParams), partialResultToken)
280+
server.sendQuickAction(encryptedParams)
280281
} ?: (CompletableFuture.failedFuture(IllegalStateException("LSP Server not running")))
281282

282283
// We assume there is only one outgoing request per tab because the input is
@@ -424,13 +425,18 @@ class BrowserConnector(
424425
handleChatNotification<TabBarActionRequest, TabBarActionParams>(node) {
425426
server, params ->
426427
val result = server.tabBarActions(params)
427-
result.whenComplete { params1, error ->
428+
result.whenComplete { actions, error ->
428429
try {
429430
if (error != null) {
430431
throw error
431432
}
432-
val res = ChatCommunicationManager.convertNotificationToJsonForChat(CHAT_TAB_BAR_ACTIONS, params1)
433-
browser.postChat(res)
433+
434+
browser.postChat(
435+
FlareUiMessage(
436+
command = CHAT_TAB_BAR_ACTIONS,
437+
params = actions ?: "{}"
438+
)
439+
)
434440
} catch (e: Exception) {
435441
LOG.error { "Failed to perform chat tab bar action $e" }
436442
params.tabId?.let {

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

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
@file:Suppress("BannedImports")
44
package software.aws.toolkits.jetbrains.services.amazonq.lsp
55

6-
import com.google.gson.Gson
76
import com.intellij.diff.DiffContentFactory
87
import com.intellij.diff.DiffManager
98
import com.intellij.diff.requests.SimpleDiffRequest
@@ -24,13 +23,15 @@ import org.eclipse.lsp4j.PublishDiagnosticsParams
2423
import org.eclipse.lsp4j.ShowDocumentParams
2524
import org.eclipse.lsp4j.ShowDocumentResult
2625
import org.eclipse.lsp4j.ShowMessageRequestParams
26+
import software.aws.toolkits.core.utils.error
2727
import software.aws.toolkits.core.utils.getLogger
2828
import software.aws.toolkits.core.utils.warn
2929
import software.aws.toolkits.jetbrains.core.credentials.AwsBearerTokenConnection
3030
import software.aws.toolkits.jetbrains.core.credentials.ToolkitConnectionManager
3131
import software.aws.toolkits.jetbrains.core.credentials.pinning.QConnection
3232
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AsyncChatUiListener
3333
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.ChatCommunicationManager
34+
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
3435
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.LSPAny
3536
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CHAT_OPEN_TAB
3637
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.CHAT_SEND_CONTEXT_COMMANDS
@@ -135,14 +136,13 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC
135136
val result = CompletableFuture<OpenTabResult>()
136137
ChatCommunicationManager.pendingTabRequests[requestId] = result
137138

138-
val uiMessage = """
139-
{
140-
"command": "$CHAT_OPEN_TAB",
141-
"params": ${Gson().toJson(params)},
142-
"requestId": "$requestId"
143-
}
144-
""".trimIndent()
145-
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
139+
AsyncChatUiListener.notifyPartialMessageUpdate(
140+
FlareUiMessage(
141+
command = CHAT_OPEN_TAB,
142+
params = params,
143+
requestId = requestId,
144+
)
145+
)
146146

147147
result.orTimeout(30000, TimeUnit.MILLISECONDS)
148148
.whenComplete { _, error ->
@@ -188,14 +188,13 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC
188188

189189
ChatCommunicationManager.pendingSerializedChatRequests[requestId] = result
190190

191-
val uiMessage = """
192-
{
193-
"command": "$GET_SERIALIZED_CHAT_REQUEST_METHOD",
194-
"params": ${Gson().toJson(params)},
195-
"requestId": "$requestId"
196-
}
197-
""".trimIndent()
198-
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
191+
AsyncChatUiListener.notifyPartialMessageUpdate(
192+
FlareUiMessage(
193+
command = GET_SERIALIZED_CHAT_REQUEST_METHOD,
194+
params = params,
195+
requestId = requestId,
196+
)
197+
)
199198

200199
result.orTimeout(30000, TimeUnit.MILLISECONDS)
201200
.whenComplete { _, error ->
@@ -254,19 +253,17 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC
254253
try {
255254
chatCommunicationManager.handlePartialResultProgressNotification(project, params)
256255
} catch (e: Exception) {
257-
error("Cannot handle partial chat")
256+
LOG.error(e) { "Cannot handle partial chat" }
258257
}
259258
}
260259

261260
override fun sendChatUpdate(params: ChatUpdateParams): CompletableFuture<Unit> {
262-
val uiMessage = """
263-
{
264-
"command":"$CHAT_SEND_UPDATE",
265-
"params":${Gson().toJson(params)}
266-
}
267-
""".trimIndent()
268-
269-
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
261+
AsyncChatUiListener.notifyPartialMessageUpdate(
262+
FlareUiMessage(
263+
command = CHAT_SEND_UPDATE,
264+
params = params,
265+
)
266+
)
270267

271268
return CompletableFuture.completedFuture(Unit)
272269
}
@@ -311,14 +308,12 @@ class AmazonQLanguageClientImpl(private val project: Project) : AmazonQLanguageC
311308
)
312309

313310
override fun sendContextCommands(params: LSPAny): CompletableFuture<Unit> {
314-
val showContextCommands = """
315-
{
316-
"command":"$CHAT_SEND_CONTEXT_COMMANDS",
317-
"params": ${Gson().toJson(params)}
318-
}
319-
""".trimIndent()
320-
321-
AsyncChatUiListener.notifyPartialMessageUpdate(showContextCommands)
311+
AsyncChatUiListener.notifyPartialMessageUpdate(
312+
FlareUiMessage(
313+
command = CHAT_SEND_CONTEXT_COMMANDS,
314+
params = params ?: error("received empty payload for $CHAT_SEND_CONTEXT_COMMANDS"),
315+
)
316+
)
322317

323318
return CompletableFuture.completedFuture(Unit)
324319
}

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,22 @@ import com.intellij.util.messages.Topic
88
import java.util.EventListener
99

1010
interface AsyncChatUiListener : EventListener {
11-
fun onChange(message: String) {}
11+
@Deprecated("shouldn't need this version")
12+
fun onChange(command: String) {}
13+
14+
fun onChange(command: FlareUiMessage) {}
1215

1316
companion object {
1417
@Topic.AppLevel
1518
val TOPIC = Topic.create("Partial chat message provider", AsyncChatUiListener::class.java)
1619

17-
fun notifyPartialMessageUpdate(message: String) {
18-
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).onChange(message)
20+
fun notifyPartialMessageUpdate(command: FlareUiMessage) {
21+
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).onChange(command)
22+
}
23+
24+
@Deprecated("shouldn't need this version")
25+
fun notifyPartialMessageUpdate(command: String) {
26+
ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).onChange(command)
1927
}
2028
}
2129
}

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,5 @@ class ChatCommunicationManager {
114114
fun completeTabOpen(requestId: String, tabId: String) {
115115
pendingTabRequests.remove(requestId)?.complete(OpenTabResult(tabId))
116116
}
117-
118-
inline fun <reified T> convertNotificationToJsonForChat(command: String, params: T? = null) =
119-
"""
120-
{
121-
"command":"$command",
122-
"params": ${if (params != null) Gson().toJson(params) else "{}"}
123-
}
124-
""".trimIndent()
125117
}
126118
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat
5+
6+
data class FlareUiMessage(
7+
val command: String,
8+
val params: Any,
9+
val requestId: String? = null
10+
)

0 commit comments

Comments
 (0)