diff --git a/.changes/next-release/feature-634f17f8-0782-4c9b-a57e-0c9431eb4eb4.json b/.changes/next-release/feature-634f17f8-0782-4c9b-a57e-0c9431eb4eb4.json new file mode 100644 index 0000000000..4d6dc149bc --- /dev/null +++ b/.changes/next-release/feature-634f17f8-0782-4c9b-a57e-0c9431eb4eb4.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Adds event listener for notifying UI that AB feature configurations have been resolved" +} \ No newline at end of file diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/App.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/App.kt index f871a24710..b206595f9e 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/App.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/App.kt @@ -3,17 +3,21 @@ package software.aws.toolkits.jetbrains.services.cwc +import com.intellij.openapi.application.ApplicationManager import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch import software.aws.toolkits.jetbrains.core.coroutines.disposableCoroutineScope +import software.aws.toolkits.jetbrains.services.amazonq.CodeWhispererFeatureConfigListener import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQApp import software.aws.toolkits.jetbrains.services.amazonq.apps.AmazonQAppInitContext import software.aws.toolkits.jetbrains.services.amazonq.messages.AmazonQMessage import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteraction +import software.aws.toolkits.jetbrains.services.amazonq.util.highlightCommand import software.aws.toolkits.jetbrains.services.cwc.commands.ActionRegistrar import software.aws.toolkits.jetbrains.services.cwc.commands.CodeScanIssueActionMessage import software.aws.toolkits.jetbrains.services.cwc.commands.ContextMenuActionMessage import software.aws.toolkits.jetbrains.services.cwc.controller.ChatController +import software.aws.toolkits.jetbrains.services.cwc.messages.FeatureConfigsAvailableMessage import software.aws.toolkits.jetbrains.services.cwc.messages.IncomingCwcMessage class App : AmazonQApp { @@ -56,6 +60,21 @@ class App : AmazonQApp { scope.launch { handleMessage(message, inboundAppMessagesHandler) } } } + + ApplicationManager.getApplication().messageBus.connect(this).subscribe( + CodeWhispererFeatureConfigListener.TOPIC, + object : CodeWhispererFeatureConfigListener { + override fun publishFeatureConfigsAvailble() { + scope.launch { + context.messagesFromAppToUi.publish( + FeatureConfigsAvailableMessage( + highlightCommand = highlightCommand() + ) + ) + } + } + } + ) } private suspend fun handleMessage(message: AmazonQMessage, inboundAppMessagesHandler: InboundAppMessagesHandler) { diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/messages/CwcMessage.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/messages/CwcMessage.kt index 85b3075c96..f695ba4993 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/messages/CwcMessage.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/cwc/messages/CwcMessage.kt @@ -17,6 +17,7 @@ import software.amazon.awssdk.services.codewhispererstreaming.model.UserIntent import software.aws.toolkits.jetbrains.services.amazonq.auth.AuthFollowUpType import software.aws.toolkits.jetbrains.services.amazonq.messages.AmazonQMessage import software.aws.toolkits.jetbrains.services.amazonq.onboarding.OnboardingPageInteractionType +import software.aws.toolkits.jetbrains.services.amazonq.util.HighlightCommand import software.aws.toolkits.jetbrains.services.cwc.clients.chat.model.FollowUpType import java.time.Instant @@ -264,6 +265,14 @@ data class ErrorMessage( type = "errorMessage", ) +data class FeatureConfigsAvailableMessage( + val highlightCommand: HighlightCommand?, + +) : UiMessage( + null, + type = "featureConfigsAvailableMessage", +) + data class QuickActionMessage( val message: String, @JsonProperty("triggerID") val triggerId: String, diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/cwChatConnector.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/cwChatConnector.ts index ffbca2fb06..7f478f0fbe 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/cwChatConnector.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/apps/cwChatConnector.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ChatItemAction, ChatItemType, FeedbackPayload } from '@aws/mynah-ui-chat' +import {ChatItemAction, ChatItemType, FeedbackPayload, QuickActionCommand} from '@aws/mynah-ui-chat' import { ExtensionMessage } from '../commands' import { CodeReference } from './amazonqCommonsConnector' import { TabOpenType, TabsStorage } from '../storages/tabsStorage' @@ -23,6 +23,9 @@ export interface ConnectorProps { onError: (tabID: string, message: string, title: string) => void onWarning: (tabID: string, message: string, title: string) => void onOpenSettingsMessage: (tabID: string) => void + onFeatureConfigsAvailable: ( + highlightCommand?: QuickActionCommand + ) => void tabsStorage: TabsStorage } @@ -33,6 +36,7 @@ export class Connector { private readonly onChatAnswerReceived private readonly onCWCContextCommandMessage private readonly onOpenSettingsMessage + private readonly onFeatureConfigsAvailable private readonly followUpGenerator: FollowUpGenerator constructor(props: ConnectorProps) { @@ -42,6 +46,7 @@ export class Connector { this.onError = props.onError this.onCWCContextCommandMessage = props.onCWCContextCommandMessage this.onOpenSettingsMessage = props.onOpenSettingsMessage + this.onFeatureConfigsAvailable = props.onFeatureConfigsAvailable this.followUpGenerator = new FollowUpGenerator() } @@ -373,5 +378,12 @@ export class Connector { await this.processOpenSettingsMessage(messageData) return } + + if (messageData.type === 'featureConfigsAvailableMessage') { + this.onFeatureConfigsAvailable( + messageData.highlightCommand, + ) + return + } } } diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/connector.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/connector.ts index 3405a59f32..143b3f017a 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/connector.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/connector.ts @@ -10,7 +10,7 @@ import { Engagement, NotificationType, ProgressField, - ChatPrompt, + ChatPrompt, QuickActionCommand, } from '@aws/mynah-ui-chat' import { Connector as CWChatConnector } from './apps/cwChatConnector' import { Connector as FeatureDevChatConnector } from './apps/featureDevChatConnector' @@ -84,6 +84,9 @@ export interface ConnectorProps { codeTestEnabled: boolean, authenticatingTabIDs: string[] ) => void + onFeatureConfigsAvailable: ( + highlightCommand?: QuickActionCommand + ) => void onNewTab: (tabType: TabType) => void onStartNewTransform: (tabID: string) => void onCodeTransformCommandMessageReceived: (message: ChatItem, command?: string) => void diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts index 685c496d1a..1be8f151a7 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts @@ -552,6 +552,17 @@ export const createMynahUI = ( tabsStorage.updateTabStatus(tabID, 'free') } } + }, + onFeatureConfigsAvailable: ( + highlightCommand?: QuickActionCommand + ): void => { + tabDataGenerator.highlightCommand = highlightCommand + + for (const tab of tabsStorage.getTabs()) { + mynahUI.updateStore(tab.id, { + contextCommands: tabDataGenerator.getTabData(tab.type, true).contextCommands + }) + } } }) diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/tabs/generator.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/tabs/generator.ts index b5fb3d047f..63682d596e 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/tabs/generator.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/tabs/generator.ts @@ -21,7 +21,7 @@ export interface TabDataGeneratorProps { export class TabDataGenerator { private followUpsGenerator: FollowUpGenerator public quickActionsGenerator: QuickActionGenerator - private highlightCommand?: QuickActionCommand + public highlightCommand?: QuickActionCommand private tabTitle: Map = new Map([ ['unknown', 'Chat'], diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigListener.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigListener.kt new file mode 100644 index 0000000000..2ae46a8285 --- /dev/null +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigListener.kt @@ -0,0 +1,20 @@ +// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package software.aws.toolkits.jetbrains.services.amazonq + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.util.messages.Topic + +interface CodeWhispererFeatureConfigListener { + fun publishFeatureConfigsAvailble() {} + + companion object { + @Topic.AppLevel + val TOPIC = Topic.create("feature configs listener", CodeWhispererFeatureConfigListener::class.java) + + fun notifyUiFeatureConfigsAvailable() { + ApplicationManager.getApplication().messageBus.syncPublisher(TOPIC).publishFeatureConfigsAvailble() + } + } +} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt index 736879327c..84a75038ad 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonq/CodeWhispererFeatureConfigService.kt @@ -83,6 +83,7 @@ class CodeWhispererFeatureConfigService { featureConfigs.remove(CUSTOMIZATION_ARN_OVERRIDE_NAME) } } + CodeWhispererFeatureConfigListener.notifyUiFeatureConfigsAvailable() } catch (e: Exception) { LOG.debug(e) { "Error when fetching feature configs" } }