diff --git a/packages/amazonq/.changes/next-release/Feature-b92f1e8b-78a0-46a6-ba9b-2300c884fcbc.json b/packages/amazonq/.changes/next-release/Feature-b92f1e8b-78a0-46a6-ba9b-2300c884fcbc.json
new file mode 100644
index 00000000000..20664e7f542
--- /dev/null
+++ b/packages/amazonq/.changes/next-release/Feature-b92f1e8b-78a0-46a6-ba9b-2300c884fcbc.json
@@ -0,0 +1,4 @@
+{
+ "type": "Feature",
+ "description": "Add acknowledgement button for amazon q chat disclaimer"
+}
diff --git a/packages/core/src/amazonq/webview/generators/webViewContent.ts b/packages/core/src/amazonq/webview/generators/webViewContent.ts
index fb83ab895a6..6b935e83642 100644
--- a/packages/core/src/amazonq/webview/generators/webViewContent.ts
+++ b/packages/core/src/amazonq/webview/generators/webViewContent.ts
@@ -78,6 +78,7 @@ export class WebViewContentGenerator {
const featureConfigsString = await this.generateFeatureConfigsData()
const disabledCommandsString = isSageMaker() ? `['/dev', '/transform']` : '[]'
+ const disclaimerAcknowledged = globals.globalState.tryGet('aws.amazonq.disclaimerAcknowledged', Boolean, false)
return `
@@ -86,7 +87,7 @@ export class WebViewContentGenerator {
const init = () => {
createMynahUI(acquireVsCodeApi(), ${
(await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'
- },${featureConfigsString},${showWelcomePage},${disabledCommandsString});
+ },${featureConfigsString},${showWelcomePage},${disclaimerAcknowledged},${disabledCommandsString});
}
`
diff --git a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
index 244f6ae1583..95e301a0470 100644
--- a/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
+++ b/packages/core/src/amazonq/webview/messages/messageDispatcher.ts
@@ -11,7 +11,7 @@ import { getLogger } from '../../../shared/logger'
import { amazonqMark } from '../../../shared/performance/marks'
import { telemetry } from '../../../shared/telemetry'
import { AmazonQChatMessageDuration } from '../../messages/chatMessageDuration'
-import { openUrl } from '../../../shared'
+import { globals, openUrl } from '../../../shared'
import { isClickTelemetry, isOpenAgentTelemetry } from '../ui/telemetry/actions'
export function dispatchWebViewMessagesToApps(
@@ -60,12 +60,19 @@ export function dispatchWebViewMessagesToApps(
source: msg.trigger,
result: 'Succeeded',
})
+ return
} else if (isClickTelemetry(msg)) {
telemetry.ui_click.emit({
elementId: msg.source,
result: 'Succeeded',
})
+ return
}
+ return
+ }
+ case 'disclaimer-acknowledged': {
+ globals.globalState.tryUpdate('aws.amazonq.disclaimerAcknowledged', true)
+ return
}
}
diff --git a/packages/core/src/amazonq/webview/ui/commands.ts b/packages/core/src/amazonq/webview/ui/commands.ts
index ea925d93bef..643595e3e1f 100644
--- a/packages/core/src/amazonq/webview/ui/commands.ts
+++ b/packages/core/src/amazonq/webview/ui/commands.ts
@@ -10,6 +10,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/packages/core/src/amazonq/webview/ui/main.ts b/packages/core/src/amazonq/webview/ui/main.ts
index 58511517e7a..d4243928a1b 100644
--- a/packages/core/src/amazonq/webview/ui/main.ts
+++ b/packages/core/src/amazonq/webview/ui/main.ts
@@ -31,14 +31,17 @@ import { tryNewMap } from '../../util/functionUtils'
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,
amazonQEnabled: boolean,
featureConfigsSerialized: [string, FeatureContext][],
showWelcomePage: boolean,
+ disclaimerAcknowledged: boolean,
disabledCommands?: string[]
) => {
+ let disclaimerCardActive = !disclaimerAcknowledged
// eslint-disable-next-line prefer-const
let mynahUI: MynahUI
// eslint-disable-next-line prefer-const
@@ -542,6 +545,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)
},
@@ -609,43 +613,64 @@ export const createMynahUI = (
},
onVote: connector.onChatItemVoted,
onInBodyButtonClicked: (tabId, messageId, action, eventId) => {
- if (action.id === 'quick-start') {
- /**
- * quick start is the action on the welcome page. When its
- * clicked it collapses the view and puts it into regular
- * "chat" which is cwc
- */
- tabsStorage.updateTabTypeFromUnknown(tabId, 'cwc')
-
- // show quick start in the current tab instead of a new one
- mynahUI.updateStore(tabId, {
- tabHeaderDetails: undefined,
- compactMode: false,
- tabBackground: false,
- promptInputText: '/',
- promptInputLabel: undefined,
- chatItems: [],
- })
+ switch (action.id) {
+ case disclaimerAcknowledgeButtonId: {
+ disclaimerCardActive = false
- ideApi.postMessage(createClickTelemetry('amazonq-welcome-quick-start-button'))
- return
- }
+ // post message to tell VSCode that disclaimer is acknowledged
+ ideApi.postMessage({
+ command: 'disclaimer-acknowledged',
+ })
- if (action.id === 'explore') {
- const newTabId = mynahUI.updateStore('', agentWalkthroughDataModel)
- if (newTabId === undefined) {
- mynahUI.notify({
- content: uiComponentsTexts.noMoreTabsTooltip,
- type: NotificationType.WARNING,
+ // 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 unicorn/no-null
+ mynahUI.updateStore(storeTabKey, { promptInputStickyCard: null })
})
return
}
- tabsStorage.updateTabTypeFromUnknown(newTabId, 'agentWalkthrough')
- ideApi.postMessage(createClickTelemetry('amazonq-welcome-explore-button'))
- return
- }
+ case 'quick-start': {
+ /**
+ * quick start is the action on the welcome page. When its
+ * clicked it collapses the view and puts it into regular
+ * "chat" which is cwc
+ */
+ tabsStorage.updateTabTypeFromUnknown(tabId, 'cwc')
+
+ // show quick start in the current tab instead of a new one
+ mynahUI.updateStore(tabId, {
+ tabHeaderDetails: undefined,
+ compactMode: false,
+ tabBackground: false,
+ promptInputText: '/',
+ promptInputLabel: undefined,
+ chatItems: [],
+ })
- connector.onCustomFormAction(tabId, messageId, action, eventId)
+ ideApi.postMessage(createClickTelemetry('amazonq-welcome-quick-start-button'))
+ return
+ }
+ case 'explore': {
+ const newTabId = mynahUI.updateStore('', agentWalkthroughDataModel)
+ if (newTabId === undefined) {
+ mynahUI.notify({
+ content: uiComponentsTexts.noMoreTabsTooltip,
+ type: NotificationType.WARNING,
+ })
+ return
+ }
+ tabsStorage.updateTabTypeFromUnknown(newTabId, 'agentWalkthrough')
+ ideApi.postMessage(createClickTelemetry('amazonq-welcome-explore-button'))
+ return
+ }
+ default: {
+ connector.onCustomFormAction(tabId, messageId, action, eventId)
+ return
+ }
+ }
},
onCustomFormAction: (tabId, action, eventId) => {
connector.onCustomFormAction(tabId, undefined, action, eventId)
@@ -786,9 +811,12 @@ 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 } : {}),
+ },
},
},
defaults: {
diff --git a/packages/core/src/amazonq/webview/ui/tabs/generator.ts b/packages/core/src/amazonq/webview/ui/tabs/generator.ts
index 8865d00e400..b3263218c1d 100644
--- a/packages/core/src/amazonq/webview/ui/tabs/generator.ts
+++ b/packages/core/src/amazonq/webview/ui/tabs/generator.ts
@@ -47,7 +47,7 @@ export class TabDataGenerator {
const tabData: MynahUIDataModel = {
tabTitle: taskName ?? TabTypeDataMap[tabType].title,
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: TabTypeDataMap[tabType].placeholder,
contextCommands: TabTypeDataMap[tabType].contextCommands,
diff --git a/packages/core/src/amazonq/webview/ui/texts/disclaimer.ts b/packages/core/src/amazonq/webview/ui/texts/disclaimer.ts
new file mode 100644
index 00000000000..fc666796272
--- /dev/null
+++ b/packages/core/src/amazonq/webview/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'
+
+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/packages/core/src/shared/globalState.ts b/packages/core/src/shared/globalState.ts
index bbdb03b7cd5..5cce9ff6f84 100644
--- a/packages/core/src/shared/globalState.ts
+++ b/packages/core/src/shared/globalState.ts
@@ -34,6 +34,7 @@ export type globalKey =
| 'aws.amazonq.securityIssueFilters'
| 'aws.amazonq.notifications'
| 'aws.amazonq.welcomeChatShowCount'
+ | 'aws.amazonq.disclaimerAcknowledged'
| 'aws.notifications'
| 'aws.notifications.dev' // keys to store notifications for testing
| 'aws.downloadPath'