From c0c47641a542ef24cde765488174de93d740ddf2 Mon Sep 17 00:00:00 2001 From: Yuxian Zhang Date: Fri, 1 Aug 2025 14:08:22 -0400 Subject: [PATCH 1/5] disable inline chat, fix other bugs, autofill access key --- packages/amazonq/src/extensionNode.ts | 4 +- .../inlineChat/provider/inlineChatProvider.ts | 9 ++- .../unit/codewhisperer/util/authUtil.test.ts | 2 +- .../codewhisperer/ui/codeWhispererNodes.ts | 6 +- .../core/src/codewhisperer/util/authUtil.ts | 2 +- .../core/src/login/webview/vue/backend.ts | 12 +++- packages/core/src/login/webview/vue/login.vue | 55 ++++++++++++++----- packages/core/src/shared/featureConfig.ts | 2 +- packages/core/src/shared/globalState.ts | 1 + packages/core/src/shared/settings.ts | 1 + packages/core/src/test/amazonq/utils.ts | 14 ++--- 11 files changed, 79 insertions(+), 29 deletions(-) diff --git a/packages/amazonq/src/extensionNode.ts b/packages/amazonq/src/extensionNode.ts index 576757c36e2..dbc669909c8 100644 --- a/packages/amazonq/src/extensionNode.ts +++ b/packages/amazonq/src/extensionNode.ts @@ -100,8 +100,8 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) { async function getAuthState(): Promise> { const state = AuthUtil.instance.getAuthState() - if (AuthUtil.instance.isConnected() && !(AuthUtil.instance.isSsoSession() || isSageMaker())) { - getLogger().error('Current Amazon Q connection is not SSO') + if (AuthUtil.instance.isConnected() && !(AuthUtil.instance.isSsoSession() || AuthUtil.instance.isIamSession() || isSageMaker())) { + getLogger().error('Current Amazon Q connection is not SSO nor IAM') } return { diff --git a/packages/amazonq/src/inlineChat/provider/inlineChatProvider.ts b/packages/amazonq/src/inlineChat/provider/inlineChatProvider.ts index 64a67224a2e..6c22cb06b84 100644 --- a/packages/amazonq/src/inlineChat/provider/inlineChatProvider.ts +++ b/packages/amazonq/src/inlineChat/provider/inlineChatProvider.ts @@ -143,7 +143,7 @@ export class InlineChatProvider { private async generateResponse( triggerPayload: TriggerPayload & { projectContextQueryLatencyMs?: number }, triggerID: string - ) { + ): Promise { const triggerEvent = this.triggerEventsStorage.getTriggerEvent(triggerID) if (triggerEvent === undefined) { return @@ -182,7 +182,12 @@ export class InlineChatProvider { let response: GenerateAssistantResponseCommandOutput | undefined = undefined session.createNewTokenSource() try { - response = await session.chatSso(request) + if (AuthUtil.instance.isSsoSession()) { + response = await session.chatSso(request) + } else { + // Call sendMessage because Q Developer Streaming Client does not have generateAssistantResponse + throw new ToolkitError('Inline chat is only available with SSO authentication') + } getLogger().info( `response to tab: ${tabID} conversationID: ${session.sessionIdentifier} requestID: ${response.$metadata.requestId} metadata: %O`, response.$metadata diff --git a/packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts b/packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts index d835427006c..62ca4002f43 100644 --- a/packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/util/authUtil.test.ts @@ -483,7 +483,7 @@ describe('AuthUtil', async function () { await auth.getIamCredential() assert.fail('Should have thrown an error') } catch (err) { - assert.strictEqual((err as Error).message, 'Cannot get token with SSO session') + assert.strictEqual((err as Error).message, 'Cannot get credential with SSO session') } }) diff --git a/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts b/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts index 1d0dc8c51f0..ed50a8ba09c 100644 --- a/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts +++ b/packages/core/src/codewhisperer/ui/codeWhispererNodes.ts @@ -192,7 +192,11 @@ export function createManageSubscription(): DataQuickPickItem<'manageSubscriptio export function createSignout(): DataQuickPickItem<'signout'> { const label = localize('AWS.codewhisperer.signoutNode.label', 'Sign Out') const icon = getIcon('vscode-export') - const connection = AuthUtil.instance.isBuilderIdConnection() ? 'AWS Builder ID' : 'IAM Identity Center' + const connection = AuthUtil.instance.isIamConnection() + ? 'IAM Credentials' + : AuthUtil.instance.isBuilderIdConnection() + ? 'AWS Builder ID' + : 'IAM Identity Center' return { data: 'signout', diff --git a/packages/core/src/codewhisperer/util/authUtil.ts b/packages/core/src/codewhisperer/util/authUtil.ts index 8745d6739aa..68d01e51e15 100644 --- a/packages/core/src/codewhisperer/util/authUtil.ts +++ b/packages/core/src/codewhisperer/util/authUtil.ts @@ -219,7 +219,7 @@ export class AuthUtil implements IAuthProvider { if (this.session) { const credential = (await this.session.getCredential()).credential if (typeof credential !== 'object') { - throw new ToolkitError('Cannot get token with SSO session') + throw new ToolkitError('Cannot get credential with SSO session') } return credential } else { diff --git a/packages/core/src/login/webview/vue/backend.ts b/packages/core/src/login/webview/vue/backend.ts index edb1980a8c0..bbc33ebb544 100644 --- a/packages/core/src/login/webview/vue/backend.ts +++ b/packages/core/src/login/webview/vue/backend.ts @@ -33,6 +33,7 @@ import { getLogger } from '../../../shared/logger/logger' import { isValidUrl } from '../../../shared/utilities/uriUtils' import { RegionProfile } from '../../../codewhisperer/models/model' import { ProfileSwitchIntent } from '../../../codewhisperer/region/regionProfileManager' +import { showMessage } from '../../../shared/utilities/messages' export abstract class CommonAuthWebview extends VueWebview { private readonly className = 'CommonAuthWebview' @@ -183,7 +184,7 @@ export abstract class CommonAuthWebview extends VueWebview { abstract fetchConnections(): Promise async errorNotification(e: AuthError) { - void vscode.window.showInformationMessage(`${e.text}`) + showMessage('error', e.text) } abstract quitLoginScreen(): Promise @@ -296,6 +297,15 @@ export abstract class CommonAuthWebview extends VueWebview { return globals.globalState.tryGet('recentSso', Object, { startUrl: '', region: 'us-east-1' }) } + getDefaultIamKeys(): { accessKey: string } { + const devSettings = DevSettings.instance.get('autofillAccessKey', '') + if (devSettings) { + return { accessKey: devSettings } + } + + return globals.globalState.tryGet('recentIamKeys', Object, { accessKey: '' }) + } + cancelAuthFlow() { AuthSSOServer.lastInstance?.cancelCurrentFlow() } diff --git a/packages/core/src/login/webview/vue/login.vue b/packages/core/src/login/webview/vue/login.vue index c61e7c1dabd..90eabc09db4 100644 --- a/packages/core/src/login/webview/vue/login.vue +++ b/packages/core/src/login/webview/vue/login.vue @@ -230,7 +230,7 @@