diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 44f972717e..442f49a1b8 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -136,6 +136,10 @@ "type": "boolean", "default": false }, + "amazonQChatDeprecationNotice": { + "type": "boolean", + "default": false + }, "amazonQSelectDeveloperProfile": { "type": "boolean", "default": false diff --git a/packages/amazonq/src/lsp/chat/messages.ts b/packages/amazonq/src/lsp/chat/messages.ts index 8c9f3d940b..6309ffc963 100644 --- a/packages/amazonq/src/lsp/chat/messages.ts +++ b/packages/amazonq/src/lsp/chat/messages.ts @@ -255,6 +255,11 @@ export function registerMessageListeners( switch (acknowledgedMessage.params.messageId) { case 'programmerModeCardId': { void AmazonQPromptSettings.instance.disablePrompt('amazonQChatPairProgramming') + break + } + case 'client-deprecation-notice': { + void AmazonQPromptSettings.instance.disablePrompt('amazonQChatDeprecationNotice') + break } } break diff --git a/packages/amazonq/src/lsp/chat/webviewProvider.ts b/packages/amazonq/src/lsp/chat/webviewProvider.ts index 45f01dbd58..99a3029596 100644 --- a/packages/amazonq/src/lsp/chat/webviewProvider.ts +++ b/packages/amazonq/src/lsp/chat/webviewProvider.ts @@ -96,6 +96,8 @@ export class AmazonQChatViewProvider implements WebviewViewProvider { const disclaimerAcknowledged = !AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatDisclaimer') const pairProgrammingAcknowledged = !AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatPairProgramming') + const deprecationNoticeAcknowledged = + !AmazonQPromptSettings.instance.isPromptEnabled('amazonQChatDeprecationNotice') const welcomeCount = globals.globalState.tryGet('aws.amazonq.welcomeChatShowCount', Number, 0) const modelSelectionEnabled = this.languageClient.initializeResult?.awsServerCapabilities?.chatOptions?.modelSelection ?? false @@ -147,7 +149,7 @@ export class AmazonQChatViewProvider implements WebviewViewProvider { const vscodeApi = acquireVsCodeApi() const hybridChatConnector = new HybridChatAdapter(${(await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'},${featureConfigData},${welcomeCount},${disclaimerAcknowledged},${regionProfileString},${disabledCommands},${isSMUS},${isSM},vscodeApi.postMessage) const commands = [hybridChatConnector.initialQuickActions[0]] - qChat = amazonQChat.createChat(vscodeApi, {os: "${os.platform()}", disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, agenticMode: true, quickActionCommands: commands, modelSelectionEnabled: ${modelSelectionEnabled}}, hybridChatConnector, ${JSON.stringify(featureConfigData)}); + qChat = amazonQChat.createChat(vscodeApi, {os: "${os.platform()}", disclaimerAcknowledged: ${disclaimerAcknowledged}, pairProgrammingAcknowledged: ${pairProgrammingAcknowledged}, deprecationNoticeAcknowledged: ${deprecationNoticeAcknowledged}, agenticMode: true, quickActionCommands: commands, modelSelectionEnabled: ${modelSelectionEnabled}}, hybridChatConnector, ${JSON.stringify(featureConfigData)}); } window.addEventListener('message', (event) => { /** diff --git a/packages/amazonq/test/unit/amazonq/lsp/chat/messages.test.ts b/packages/amazonq/test/unit/amazonq/lsp/chat/messages.test.ts index 4c412a1767..a48b7ff647 100644 --- a/packages/amazonq/test/unit/amazonq/lsp/chat/messages.test.ts +++ b/packages/amazonq/test/unit/amazonq/lsp/chat/messages.test.ts @@ -9,7 +9,7 @@ import { AuthUtil } from 'aws-core-vscode/codewhisperer' import { registerMessageListeners } from '../../../../../src/lsp/chat/messages' import { AmazonQChatViewProvider } from '../../../../../src/lsp/chat/webviewProvider' import { secondaryAuth, authConnection, AuthFollowUpType } from 'aws-core-vscode/amazonq' -import { messages } from 'aws-core-vscode/shared' +import { AmazonQPromptSettings, messages } from 'aws-core-vscode/shared' describe('registerMessageListeners', () => { let languageClient: BaseLanguageClient @@ -160,4 +160,39 @@ describe('registerMessageListeners', () => { sinon.assert.calledWith(errorStub, `[VSCode Client] Failed to copy to clipboard: ${errorMessage}`) }) }) + + describe('CHAT_PROMPT_OPTION_ACKNOWLEDGED', () => { + let disablePromptStub: sinon.SinonStub + + beforeEach(() => { + disablePromptStub = sandbox.stub().resolves() + sandbox.replaceGetter(AmazonQPromptSettings, 'instance', () => { + return { + disablePrompt: disablePromptStub, + } as unknown as AmazonQPromptSettings + }) + }) + + it('persists the pair programming acknowledgement', async () => { + await messageHandler({ + command: 'chatPromptOptionAcknowledged', + params: { + messageId: 'programmerModeCardId', + }, + }) + + sinon.assert.calledOnceWithExactly(disablePromptStub, 'amazonQChatPairProgramming') + }) + + it('persists the deprecation notice acknowledgement separately', async () => { + await messageHandler({ + command: 'chatPromptOptionAcknowledged', + params: { + messageId: 'client-deprecation-notice', + }, + }) + + sinon.assert.calledOnceWithExactly(disablePromptStub, 'amazonQChatDeprecationNotice') + }) + }) }) diff --git a/packages/amazonq/test/unit/amazonq/lsp/chat/webviewProvider.test.ts b/packages/amazonq/test/unit/amazonq/lsp/chat/webviewProvider.test.ts new file mode 100644 index 0000000000..1670805a38 --- /dev/null +++ b/packages/amazonq/test/unit/amazonq/lsp/chat/webviewProvider.test.ts @@ -0,0 +1,72 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as sinon from 'sinon' +import { BaseLanguageClient } from 'vscode-languageclient' +import { AuthUtil } from 'aws-core-vscode/codewhisperer' +import { featureConfig } from 'aws-core-vscode/amazonq' +import { AmazonQPromptSettings, globals } from 'aws-core-vscode/shared' +import { AmazonQChatViewProvider } from '../../../../../src/lsp/chat/webviewProvider' + +describe('AmazonQChatViewProvider', () => { + let sandbox: sinon.SinonSandbox + + beforeEach(() => { + sandbox = sinon.createSandbox() + sandbox.stub(featureConfig, 'getFeatureConfigs').resolves('{}') + sandbox.stub(globals.globalState, 'tryGet').returns(0) + sandbox.replaceGetter(AuthUtil, 'instance', () => { + return { + getChatAuthState: sandbox.stub().resolves({ amazonQ: 'connected' }), + regionProfileManager: { + activeRegionProfile: undefined, + profiles: [], + }, + } as unknown as AuthUtil + }) + }) + + afterEach(() => { + sandbox.restore() + }) + + it('forwards the old and new prompt acknowledgements independently', async () => { + const isPromptEnabled = sandbox.stub() + isPromptEnabled.withArgs('amazonQChatDisclaimer').returns(false) + isPromptEnabled.withArgs('amazonQChatPairProgramming').returns(false) + isPromptEnabled.withArgs('amazonQChatDeprecationNotice').returns(true) + sandbox.replaceGetter(AmazonQPromptSettings, 'instance', () => { + return { + isPromptEnabled, + } as unknown as AmazonQPromptSettings + }) + + const provider = new AmazonQChatViewProvider('', {} as BaseLanguageClient) + const content = await (provider as any).getWebviewContent() + + sinon.assert.match(content, 'disclaimerAcknowledged: true') + sinon.assert.match(content, 'pairProgrammingAcknowledged: true') + sinon.assert.match(content, 'deprecationNoticeAcknowledged: false') + }) + + it('forwards an acknowledged deprecation notice independently from the old feature card', async () => { + const isPromptEnabled = sandbox.stub() + isPromptEnabled.withArgs('amazonQChatDisclaimer').returns(false) + isPromptEnabled.withArgs('amazonQChatPairProgramming').returns(true) + isPromptEnabled.withArgs('amazonQChatDeprecationNotice').returns(false) + sandbox.replaceGetter(AmazonQPromptSettings, 'instance', () => { + return { + isPromptEnabled, + } as unknown as AmazonQPromptSettings + }) + + const provider = new AmazonQChatViewProvider('', {} as BaseLanguageClient) + const content = await (provider as any).getWebviewContent() + + sinon.assert.match(content, 'disclaimerAcknowledged: true') + sinon.assert.match(content, 'pairProgrammingAcknowledged: false') + sinon.assert.match(content, 'deprecationNoticeAcknowledged: true') + }) +}) diff --git a/packages/core/src/shared/settings-amazonq.gen.ts b/packages/core/src/shared/settings-amazonq.gen.ts index 0bcf5e95c2..f94217367c 100644 --- a/packages/core/src/shared/settings-amazonq.gen.ts +++ b/packages/core/src/shared/settings-amazonq.gen.ts @@ -23,6 +23,7 @@ export const amazonqSettings = { "amazonQWorkspaceLspManifestMessage": {}, "amazonQChatDisclaimer": {}, "amazonQChatPairProgramming": {}, + "amazonQChatDeprecationNotice": {}, "amazonQSelectDeveloperProfile": {} }, "amazonQ.showCodeWithReferences": {},