From 33bb343537be2c284ed118bdfd144935545fb93c Mon Sep 17 00:00:00 2001 From: Richard Li Date: Fri, 6 Dec 2024 11:01:32 -0800 Subject: [PATCH] feat(amazonq): Add acknowledgement button for disclaimer --- ...-d6ec19f0-49b2-4abe-ba30-c946dae6ce27.json | 4 +++ .../services/amazonq/webview/Browser.kt | 3 +- .../amazonq/webview/BrowserConnector.kt | 4 +++ .../mynah-ui/src/mynah-ui/ui/commands.ts | 1 + .../amazonq/mynah-ui/src/mynah-ui/ui/main.ts | 31 +++++++++++++++++-- .../src/mynah-ui/ui/tabs/generator.ts | 2 +- .../src/mynah-ui/ui/texts/disclaimer.ts | 20 ++++++++++++ .../jetbrains/settings/MeetQSettings.kt | 7 +++++ 8 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 .changes/next-release/feature-d6ec19f0-49b2-4abe-ba30-c946dae6ce27.json create mode 100644 plugins/amazonq/mynah-ui/src/mynah-ui/ui/texts/disclaimer.ts diff --git a/.changes/next-release/feature-d6ec19f0-49b2-4abe-ba30-c946dae6ce27.json b/.changes/next-release/feature-d6ec19f0-49b2-4abe-ba30-c946dae6ce27.json new file mode 100644 index 0000000000..a0dce98f8d --- /dev/null +++ b/.changes/next-release/feature-d6ec19f0-49b2-4abe-ba30-c946dae6ce27.json @@ -0,0 +1,4 @@ +{ + "type" : "feature", + "description" : "Add acknowledgement button for Amazon Q Chat disclaimer" +} \ No newline at end of file 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 a7fa9e7b13..8a6abd1754 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 @@ -87,12 +87,13 @@ class Browser(parent: Disposable) : Disposable { } }, ${MeetQSettings.getInstance().reinvent2024OnboardingCount < MAX_ONBOARDING_PAGE_COUNT}, + ${MeetQSettings.getInstance().disclaimerAcknowledged}, $isFeatureDevAvailable, // whether /dev is available $isCodeTransformAvailable, // whether /transform is available $isDocAvailable, // whether /doc is available $isCodeScanAvailable, // whether /scan is available $isCodeTestAvailable // whether /test is available - ); + ); } """.trimIndent() 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 d3093fa660..af9c4b5fce 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 @@ -49,6 +49,10 @@ class BrowserConnector( } } + "disclaimer-acknowledged" -> { + MeetQSettings.getInstance().disclaimerAcknowledged = true + } + // some weird issue preventing deserialization from working "open-user-guide" -> { BrowserUtil.browse(node.get("userGuideLink").asText()) diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts index 48c5107b54..5df19981b3 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/commands.ts @@ -12,6 +12,7 @@ type MessageCommand = | 'tab-was-removed' | 'tab-was-changed' | 'ui-is-ready' + | 'disclaimer-acknowledged' | 'ui-focus' | 'follow-up-was-clicked' | 'auth-follow-up-was-clicked' 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 cb9fef9a6a..ffbd69f339 100644 --- a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/main.ts @@ -30,16 +30,20 @@ import { ChatPrompt, CodeSelectionType} from "@aws/mynah-ui-chat/dist/static"; import {welcomeScreenTabData} from "./walkthrough/welcome"; import { agentWalkthroughDataModel } from './walkthrough/agent' import {createClickTelemetry, createOpenAgentTelemetry} from "./telemetry/actions"; +import {disclaimerAcknowledgeButtonId, disclaimerCard} from "./texts/disclaimer"; export const createMynahUI = ( ideApi: any, showWelcomePage: boolean, + disclaimerAcknowledged: boolean, featureDevInitEnabled: boolean, codeTransformInitEnabled: boolean, docInitEnabled: boolean, codeScanEnabled: boolean, codeTestEnabled: boolean ) => { + let disclaimerCardActive = !disclaimerAcknowledged + // eslint-disable-next-line prefer-const let mynahUI: MynahUI // eslint-disable-next-line prefer-const @@ -556,6 +560,7 @@ export const createMynahUI = ( // make sure to show/hide it accordingly mynahUI.updateStore(tabID, { quickActionCommands: tabDataGenerator.quickActionsGenerator.generateForTab('unknown'), + ...(disclaimerCardActive ? { promptInputStickyCard: disclaimerCard } : {}), }) connector.onTabAdd(tabID) }, @@ -690,12 +695,32 @@ export const createMynahUI = ( tabs: { 'tab-1': { isSelected: true, - store: showWelcomePage - ? welcomeScreenTabData(tabDataGenerator).store - : tabDataGenerator.getTabData('cwc', true), + store: { + ...(showWelcomePage + ? welcomeScreenTabData(tabDataGenerator).store + : tabDataGenerator.getTabData('cwc', true)), + ...(disclaimerCardActive ? { promptInputStickyCard: disclaimerCard } : {}), + }, }, }, onInBodyButtonClicked: (tabId, messageId, action, eventId) => { + if (action.id === disclaimerAcknowledgeButtonId) { + disclaimerCardActive = false + // post message to tell IDE that disclaimer is acknowledged + ideApi.postMessage({ + command: 'disclaimer-acknowledged', + }) + + // create telemetry + ideApi.postMessage(createClickTelemetry('amazonq-disclaimer-acknowledge-button')) + + // remove all disclaimer cards from all tabs + Object.keys(mynahUI.getAllTabs()).forEach((storeTabKey) => { + // eslint-disable-next-line no-null/no-null + mynahUI.updateStore(storeTabKey, { promptInputStickyCard: null }) + }) + } + if (action.id === 'quick-start') { /** * quick start is the action on the welcome page. When its 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 c5fc6f62cb..f6879c5984 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 @@ -94,7 +94,7 @@ What would you like to work on?`, return { tabTitle: taskName ?? this.tabTitle.get(tabType), promptInputInfo: - 'Amazon Q Developer uses generative AI. You may need to verify responses. See the [AWS Responsible AI Policy](https://aws.amazon.com/machine-learning/responsible-ai/policy/). Amazon Q Developer processes data across all US Regions. See [here](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/cross-region-inference.html) for more info. Amazon Q may retain chats to provide and maintain the service.', + 'Amazon Q Developer uses generative AI. You may need to verify responses. See the [AWS Responsible AI Policy](https://aws.amazon.com/machine-learning/responsible-ai/policy/).', quickActionCommands: this.quickActionsGenerator.generateForTab(tabType), promptInputPlaceholder: this.tabInputPlaceholder.get(tabType), contextCommands: this.tabContextCommand.get(tabType), diff --git a/plugins/amazonq/mynah-ui/src/mynah-ui/ui/texts/disclaimer.ts b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/texts/disclaimer.ts new file mode 100644 index 0000000000..4bf62164a8 --- /dev/null +++ b/plugins/amazonq/mynah-ui/src/mynah-ui/ui/texts/disclaimer.ts @@ -0,0 +1,20 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ChatItem, MynahIcons } from '@aws/mynah-ui-chat' + +export const disclaimerAcknowledgeButtonId = 'amazonq-disclaimer-acknowledge-button-id' +export const disclaimerCard: Partial = { + messageId: 'amazonq-disclaimer-card', + body: 'Amazon Q Developer uses generative AI. You may need to verify responses. See the [AWS Responsible AI Policy](https://aws.amazon.com/machine-learning/responsible-ai/policy/). Amazon Q Developer processes data across all US Regions. See [here](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/cross-region-inference.html) for more info. Amazon Q may retain chats to provide and maintain the service.', + buttons: [ + { + text: 'Acknowledge', + id: disclaimerAcknowledgeButtonId, + status: 'info', + icon: MynahIcons.OK, + }, + ], +} diff --git a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/MeetQSettings.kt b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/MeetQSettings.kt index 53d851c6a9..77a30aea0a 100644 --- a/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/MeetQSettings.kt +++ b/plugins/amazonq/shared/jetbrains-community/src/software/aws/toolkits/jetbrains/settings/MeetQSettings.kt @@ -32,6 +32,12 @@ class MeetQSettings : PersistentStateComponent { state.reinvent2024OnboardingCount = value } + var disclaimerAcknowledged: Boolean + get() = state.disclaimerAcknowledged + set(value) { + state.disclaimerAcknowledged = value + } + companion object { fun getInstance(): MeetQSettings = service() } @@ -39,4 +45,5 @@ class MeetQSettings : PersistentStateComponent { data class MeetQSettingsConfiguration( var shouldDisplayPage: Boolean = true, var reinvent2024OnboardingCount: Int = 0, + var disclaimerAcknowledged: Boolean = false, )