Skip to content

fix(amazonq): Support chat quick action commands #5700

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

Merged
merged 12 commits into from
May 9, 2025
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@

package software.aws.toolkits.jetbrains.services.cwc.commands

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.runBlocking
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.AsyncChatUiListener
import software.aws.toolkits.jetbrains.services.amazonq.lsp.flareChat.FlareUiMessage
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.GenericCommandParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.SendToPromptParams
import software.aws.toolkits.jetbrains.services.amazonq.lsp.model.aws.chat.TriggerType
import software.aws.toolkits.jetbrains.services.amazonq.messages.AmazonQMessage
import software.aws.toolkits.jetbrains.services.cwc.editor.context.ActiveFileContextExtractor
import software.aws.toolkits.jetbrains.services.cwc.editor.context.ExtractionTriggerType

// Register Editor Actions in the Editor Context Menu
class ActionRegistrar {
Expand All @@ -15,7 +24,28 @@
val flow = _messages.asSharedFlow()

fun reportMessageClick(command: EditorContextCommand, project: Project) {
_messages.tryEmit(ContextMenuActionMessage(command, project))
if (command == EditorContextCommand.GenerateUnitTests) {
// pre-existing old chat code path
_messages.tryEmit(ContextMenuActionMessage(command, project))
} else {
// new agentic chat route
ApplicationManager.getApplication().executeOnPooledThread {
runBlocking {
val contextExtractor = ActiveFileContextExtractor.create(fqnWebviewAdapter = null, project = project)
val fileContext = contextExtractor.extractContextForTrigger(ExtractionTriggerType.ContextMenu)
val codeSelection = "\n```\n${fileContext.focusAreaContext?.codeSelection?.trimIndent()?.trim()}\n```\n"
var uiMessage: FlareUiMessage? = null

Check warning on line 37 in plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/commands/ActionRegistrar.kt

View workflow job for this annotation

GitHub Actions / qodana

Variable initializer is redundant

Initializer is redundant
if (command.verb != "sendToPrompt") {
val params = GenericCommandParams(selection = codeSelection, triggerType = TriggerType.CONTEXT_MENU, genericCommand = command.name)
uiMessage = FlareUiMessage(command = "genericCommand", params = params)
} else {
val params = SendToPromptParams(selection = codeSelection, triggerType = TriggerType.CONTEXT_MENU)
uiMessage = FlareUiMessage(command = "sendToPrompt", params = params)
}
AsyncChatUiListener.notifyPartialMessageUpdate(uiMessage)
}
}
}
}

fun reportMessageClick(command: EditorContextCommand, issue: MutableMap<String, String>, project: Project) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum class EditorContextCommand(
actionId = "aws.amazonq.generateUnitTests",
),
SendToPrompt(
verb = "SendToPrompt",
verb = "sendToPrompt",
actionId = "aws.amazonq.sendToPrompt",
),
ExplainCodeScanIssue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,28 +289,11 @@ class ChatController private constructor(
if (message.project != context.project) {
return
}
val fileContext = contextExtractor.extractContextForTrigger(ExtractionTriggerType.ContextMenu)
val triggerId = UUID.randomUUID().toString()
val codeSelection = "\n```\n${fileContext.focusAreaContext?.codeSelection?.trimIndent()?.trim()}\n```\n"

if (message.command == EditorContextCommand.SendToPrompt) {
messagePublisher.publish(
EditorContextCommandMessage(
message = codeSelection,
command = message.command.actionId,
triggerId = triggerId,
),
)
return
}

if (message.command == EditorContextCommand.GenerateUnitTests) {
// Publish an event to "codetest" tab with command as "test" and type as "addAnswer"
val messageToPublish = TestCommandMessage()
context.messagesFromAppToUi.publish(messageToPublish)
} else {
// Create prompt
val prompt = "${message.command} the following part of my code for me: $codeSelection"
processPromptActions(prompt, message, triggerId, fileContext)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.chat

// https://github.com/aws/language-server-runtimes/blob/main/chat-client-ui-types/src/uiContracts.ts#L27
enum class TriggerType(val value: String) {
HOTKEYS("hotkeys"),

Check warning on line 8 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/GenericCommandParams.kt

View workflow job for this annotation

GitHub Actions / qodana

Unused symbol

Class "HOTKEYS" is never used
CLICK("click"),

Check warning on line 9 in plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/lsp/model/aws/chat/GenericCommandParams.kt

View workflow job for this annotation

GitHub Actions / qodana

Unused symbol

Class "CLICK" is never used
CONTEXT_MENU("contextMenu"),
}

data class GenericCommandParams(
val tabId: String? = null,
val selection: String,
val triggerType: TriggerType,
val genericCommand: String,
)

// https://github.com/aws/language-server-runtimes/blob/b7c4718b9bd84e08e72b992da5d699549af9f115/chat-client-ui-types/src/uiContracts.ts#L67
data class SendToPromptParams(
val selection: String,
val triggerType: TriggerType,
val prompt: ChatPrompt? = null,
val autoSubmit: Boolean? = null,
)
Loading