Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions docs/lsp.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ sequenceDiagram

## Language Server Debugging

1. Clone https://github.com/aws/language-servers.git and set it up in the same workspace as this project by cmd+shift+p and "add folder to workspace" and selecting the language-servers folder that you just cloned. Your VS code folder structure should look like below.


1. Clone https://github.com/aws/language-servers.git and set it up in the same workspace as this project by cmd+shift+p and "add folder to workspace" and selecting the language-servers folder that you just cloned. Your VS code folder structure should look like below.

```
/aws-toolkit-vscode
Expand All @@ -48,7 +46,6 @@ sequenceDiagram
3. Enable the lsp experiment:
```
"aws.experiments": {
"amazonqLSP": true,
"amazonqLSPInline": true, // optional: enables inline completion from flare
"amazonqLSPChat": true // optional: enables chat from flare
}
Expand Down
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Fix Error: 'Amazon Q service is not signed in'"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Fix Error: 'Amazon Q Profile is not selected for IDC connection type'"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Previous and subsequent cells are used as context for completion in a Jupyter notebook"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "Add inline completion support for abap language"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "bugfix",
"description": "/review: disable auto-review by default"
}
1 change: 0 additions & 1 deletion packages/amazonq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"watch": "npm run clean && npm run buildScripts && tsc -watch -p ./",
"testCompile": "npm run clean && npm run buildScripts && npm run compileOnly",
"test": "npm run testCompile && c8 --allowExternal ts-node ../core/scripts/test/launchTest.ts unit dist/test/unit/index.js ../core/dist/src/testFixtures/workspaceFolder",
"testE2E": "npm run testCompile && c8 --allowExternal ts-node ../core/scripts/test/launchTest.ts e2e dist/test/e2e/index.js ../core/dist/src/testFixtures/workspaceFolder",
"testWeb": "npm run compileDev && c8 --allowExternal ts-node ../core/scripts/test/launchTest.ts web dist/test/web/testRunnerWebCore.js",
"webRun": "npx @vscode/test-web --open-devtools --browserOption=--disable-web-security --waitForDebugger=9222 --extensionDevelopmentPath=. .",
"webWatch": "npm run clean && npm run buildScripts && webpack --mode development --watch",
Expand Down
20 changes: 19 additions & 1 deletion packages/amazonq/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GenerateAssistantResponseCommandOutput, GenerateAssistantResponseReques
import { AuthUtil } from 'aws-core-vscode/codewhisperer'
import { ChatSession } from 'aws-core-vscode/codewhispererChat'
import { api } from 'aws-core-vscode/amazonq'
import { getLogger } from 'aws-core-vscode/shared'

export default {
chatApi: {
Expand All @@ -26,8 +27,25 @@ export default {
await AuthUtil.instance.showReauthenticatePrompt()
}
},
/**
* @deprecated use getAuthState() instead
*
* Legacy function for callers who expect auth state to be granular amongst Q features.
* Auth state is consistent between features, so getAuthState() can be consumed safely for all features.
*
*/
async getChatAuthState() {
return AuthUtil.instance.getChatAuthState()
getLogger().warn('Warning: getChatAuthState() is deprecated. Use getAuthState() instead.')
const state = AuthUtil.instance.getAuthState()
const convertedState = state === 'notConnected' ? 'disconnected' : state
return {
codewhispererCore: convertedState,
codewhispererChat: convertedState,
amazonQ: convertedState,
}
},
getAuthState() {
return AuthUtil.instance.getAuthState()
},
},
} satisfies api
5 changes: 3 additions & 2 deletions packages/amazonq/src/app/amazonqScan/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Messenger } from './chat/controller/messenger/messenger'
import { UIMessageListener } from './chat/views/actions/uiMessageListener'
import { debounce } from 'lodash'
import { Commands, placeholder } from 'aws-core-vscode/shared'
import { auth2 } from 'aws-core-vscode/auth'

export function init(appContext: AmazonQAppInitContext) {
const scanChatControllerEventEmitters: ScanChatControllerEventEmitters = {
Expand Down Expand Up @@ -52,7 +53,7 @@ export function init(appContext: AmazonQAppInitContext) {
appContext.registerWebViewToAppMessagePublisher(new MessagePublisher<any>(scanChatUIInputEventEmitter), 'review')

const debouncedEvent = debounce(async () => {
const authenticated = (await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'
const authenticated = AuthUtil.instance.getAuthState() === 'connected'
let authenticatingSessionID = ''

if (authenticated) {
Expand All @@ -67,7 +68,7 @@ export function init(appContext: AmazonQAppInitContext) {
messenger.sendAuthenticationUpdate(authenticated, [authenticatingSessionID])
}, 500)

AuthUtil.instance.secondaryAuth.onDidChangeActiveConnection(() => {
AuthUtil.instance.onDidChangeConnectionState((e: auth2.AuthStateEvent) => {
return debouncedEvent()
})
AuthUtil.instance.regionProfileManager.onDidChangeRegionProfile(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class ScanController {
telemetry.amazonq_feedback.emit({
featureId: 'amazonQReview',
amazonqConversationId: this.sessionStorage.getSession().scanUuid,
credentialStartUrl: AuthUtil.instance.startUrl,
credentialStartUrl: AuthUtil.instance.connection?.startUrl,
interactionType: data.vote,
})
})
Expand All @@ -122,8 +122,8 @@ export class ScanController {
try {
getLogger().debug(`Q - Review: Session created with id: ${session.tabID}`)

const authState = await AuthUtil.instance.getChatAuthState()
if (authState.amazonQ !== 'connected') {
const authState = AuthUtil.instance.getAuthState()
if (authState !== 'connected') {
void this.messenger.sendAuthNeededExceptionMessage(authState, tabID)
session.isAuthenticating = true
return
Expand Down Expand Up @@ -161,8 +161,8 @@ export class ScanController {
return
}
// check that the session is authenticated
const authState = await AuthUtil.instance.getChatAuthState()
if (authState.amazonQ !== 'connected') {
const authState = AuthUtil.instance.getAuthState()
if (authState !== 'connected') {
void this.messenger.sendAuthNeededExceptionMessage(authState, message.tabID)
session.isAuthenticating = true
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import { AuthFollowUpType, AuthMessageDataMap } from 'aws-core-vscode/amazonq'
import {
FeatureAuthState,
SecurityScanError,
CodeWhispererConstants,
SecurityScanStep,
Expand All @@ -34,6 +33,7 @@ import {
import { i18n } from 'aws-core-vscode/shared'
import { ScanAction, scanProgressMessage } from '../../../models/constants'
import path from 'path'
import { auth2 } from 'aws-core-vscode/auth'

export type UnrecoverableErrorType = 'no-project-found' | 'no-open-file-found' | 'invalid-file-type'

Expand Down Expand Up @@ -78,19 +78,15 @@ export class Messenger {
this.dispatcher.sendUpdatePromptProgress(new UpdatePromptProgressMessage(tabID, progressField))
}

public async sendAuthNeededExceptionMessage(credentialState: FeatureAuthState, tabID: string) {
public async sendAuthNeededExceptionMessage(credentialState: auth2.AuthState, tabID: string) {
let authType: AuthFollowUpType = 'full-auth'
let message = AuthMessageDataMap[authType].message

switch (credentialState.amazonQ) {
case 'disconnected':
switch (credentialState) {
case 'notConnected':
authType = 'full-auth'
message = AuthMessageDataMap[authType].message
break
case 'unsupported':
authType = 'use-supported-auth'
message = AuthMessageDataMap[authType].message
break
case 'expired':
authType = 're-auth'
message = AuthMessageDataMap[authType].message
Expand Down
2 changes: 1 addition & 1 deletion packages/amazonq/src/app/chat/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function activate(context: ExtensionContext) {

const setupLsp = funcUtil.debounce(async () => {
void amazonq.LspController.instance.trySetupLsp(context, {
startUrl: AuthUtil.instance.startUrl,
startUrl: AuthUtil.instance.connection?.startUrl,
maxIndexSize: CodeWhispererSettings.instance.getMaxIndexSize(),
isVectorIndexEnabled: false,
})
Expand Down
25 changes: 12 additions & 13 deletions packages/amazonq/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Auth, AuthUtils, CredentialsStore, LoginManager, initializeAuth } from 'aws-core-vscode/auth'
import { authUtils, CredentialsStore, LoginManager, initializeAuth } from 'aws-core-vscode/auth'
import { activate as activateCodeWhisperer, shutdown as shutdownCodeWhisperer } from 'aws-core-vscode/codewhisperer'
import { makeEndpointsProvider, registerGenericCommands } from 'aws-core-vscode'
import { CommonAuthWebview } from 'aws-core-vscode/login'
Expand Down Expand Up @@ -33,7 +33,7 @@ import {
maybeShowMinVscodeWarning,
Experiments,
isSageMaker,
isAmazonLinux2,
Commands,
} from 'aws-core-vscode/shared'
import { ExtStartUpSources } from 'aws-core-vscode/telemetry'
import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
Expand All @@ -44,7 +44,6 @@ import { registerCommands } from './commands'
import { focusAmazonQPanel } from 'aws-core-vscode/codewhispererChat'
import { activate as activateAmazonqLsp } from './lsp/activation'
import { activate as activateInlineCompletion } from './app/inline/activation'
import { hasGlibcPatch } from './lsp/client'

export const amazonQContextPrefix = 'amazonq'

Expand Down Expand Up @@ -119,23 +118,23 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
const extContext = {
extensionContext: context,
}

// Auth is dependent on LSP, needs to be activated before CW and Inline
await activateAmazonqLsp(context)

// This contains every lsp agnostic things (auth, security scan, code scan)
await activateCodeWhisperer(extContext as ExtContext)
if (
(Experiments.instance.get('amazonqLSP', true) || Auth.instance.isInternalAmazonUser()) &&
(!isAmazonLinux2() || hasGlibcPatch())
) {
// start the Amazon Q LSP for internal users first
// for AL2, start LSP if glibc patch is found
await activateAmazonqLsp(context)
}
if (!Experiments.instance.get('amazonqLSPInline', false)) {
await activateInlineCompletion()
}

// Generic extension commands
registerGenericCommands(context, amazonQContextPrefix)

// Create status bar and reference log UI elements
void Commands.tryExecute('aws.amazonq.refreshStatusBar')
void Commands.tryExecute('aws.amazonq.updateReferenceLog')

// Amazon Q specific commands
registerCommands(context)

Expand All @@ -162,7 +161,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
// reload webviews
await vscode.commands.executeCommand('workbench.action.webview.reloadWebviewAction')

if (AuthUtils.ExtensionUse.instance.isFirstUse()) {
if (authUtils.ExtensionUse.instance.isFirstUse()) {
// Give time for the extension to finish initializing.
globals.clock.setTimeout(async () => {
CommonAuthWebview.authSource = ExtStartUpSources.firstStartUp
Expand All @@ -172,7 +171,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is

context.subscriptions.push(
Experiments.instance.onDidChange(async (event) => {
if (event.key === 'amazonqLSP' || event.key === 'amazonqChatLSP' || event.key === 'amazonqLSPInline') {
if (event.key === 'amazonqChatLSP' || event.key === 'amazonqLSPInline') {
await vscode.window
.showInformationMessage(
'Amazon Q LSP setting has changed. Reload VS Code for the changes to take effect.',
Expand Down
58 changes: 14 additions & 44 deletions packages/amazonq/src/extensionNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,20 @@ import * as vscode from 'vscode'
import { activateAmazonQCommon, amazonQContextPrefix, deactivateCommon } from './extension'
import { DefaultAmazonQAppInitContext, AmazonQChatViewProvider } from 'aws-core-vscode/amazonq'
import { activate as activateTransformationHub } from 'aws-core-vscode/amazonqGumby'
import {
ExtContext,
globals,
CrashMonitoring,
getLogger,
isNetworkError,
isSageMaker,
Experiments,
} from 'aws-core-vscode/shared'
import { ExtContext, globals, CrashMonitoring, getLogger, isSageMaker, Experiments } from 'aws-core-vscode/shared'
import { filetypes, SchemaService } from 'aws-core-vscode/sharedNode'
import { updateDevMode } from 'aws-core-vscode/dev'
import { CommonAuthViewProvider } from 'aws-core-vscode/login'
import { isExtensionActive, VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
import { registerSubmitFeedback } from 'aws-core-vscode/feedback'
import { DevOptions } from 'aws-core-vscode/dev'
import { Auth, AuthUtils, getTelemetryMetadataForConn, isAnySsoConnection } from 'aws-core-vscode/auth'
import { Auth, authUtils } from 'aws-core-vscode/auth'
import api from './api'
import { activate as activateCWChat } from './app/chat/activation'
import { activate as activateInlineChat } from './inlineChat/activation'
import { beta } from 'aws-core-vscode/dev'
import { activate as activateNotifications, NotificationsController } from 'aws-core-vscode/notifications'
import { AuthState, AuthUtil } from 'aws-core-vscode/codewhisperer'
import { AuthUtil } from 'aws-core-vscode/codewhisperer'
import { telemetry, AuthUserState } from 'aws-core-vscode/telemetry'
import { activateAgents } from './app/chat/node/activateAgents'

Expand Down Expand Up @@ -95,52 +87,30 @@ async function activateAmazonQNode(context: vscode.ExtensionContext) {
await setupDevMode(context)
await beta.activate(context)

// TODO: Should probably emit for web as well.
// Will the web metric look the same?
await getAuthState()
telemetry.auth_userState.emit({
passive: true,
result: 'Succeeded',
source: AuthUtils.ExtensionUse.instance.sourceForTelemetry(),
...(await getAuthState()),
source: authUtils.ExtensionUse.instance.sourceForTelemetry(),
authStatus: AuthUtil.instance.getAuthState(),
authEnabledConnections: (await AuthUtil.instance.getAuthFormIds()).join(','),
})

void activateNotifications(context, getAuthState)
}

async function getAuthState(): Promise<Omit<AuthUserState, 'source'>> {
let authState: AuthState = 'disconnected'
try {
// May call connection validate functions that try to refresh the token.
// This could result in network errors.
authState = (await AuthUtil.instance._getChatAuthState(false)).codewhispererChat
} catch (err) {
if (
isNetworkError(err) &&
AuthUtil.instance.conn &&
AuthUtil.instance.auth.getConnectionState(AuthUtil.instance.conn) === 'valid'
) {
authState = 'connectedWithNetworkError'
} else {
throw err
}
}
const currConn = AuthUtil.instance.conn
if (currConn !== undefined && !(isAnySsoConnection(currConn) || isSageMaker())) {
getLogger().error(`Current Amazon Q connection is not SSO, type is: %s`, currConn?.type)
}
const state = AuthUtil.instance.getAuthState()

// Pending profile selection state means users already log in with Sso service
if (authState === 'pendingProfileSelection') {
authState = 'connected'
if (AuthUtil.instance.isConnected() && !(AuthUtil.instance.isSsoSession() || isSageMaker())) {
getLogger().error('Current Amazon Q connection is not SSO')
}

return {
authStatus:
authState === 'connected' || authState === 'expired' || authState === 'connectedWithNetworkError'
? authState
: 'notConnected',
authEnabledConnections: AuthUtils.getAuthFormIdsFromConnection(currConn).join(','),
...(await getTelemetryMetadataForConn(currConn)),
// @ts-ignore
authStatus: (state ?? 'notConnected') as AuthStatus,
authEnabledConnections: (await AuthUtil.instance.getAuthFormIds()).join(','),
...AuthUtil.instance.getTelemetryMetadata(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,8 @@ export class InlineChatProvider {

const tabID = triggerEvent.tabID

const credentialsState = await AuthUtil.instance.getChatAuthState()
if (
!(credentialsState.codewhispererChat === 'connected' && credentialsState.codewhispererCore === 'connected')
) {
const credentialsState = AuthUtil.instance.getAuthState()
if (credentialsState !== 'connected') {
const { message } = extractAuthFollowUp(credentialsState)
this.errorEmitter.fire()
throw new ToolkitError(message)
Expand Down
4 changes: 2 additions & 2 deletions packages/amazonq/src/lsp/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { startLanguageServer } from './client'
import { AmazonQLspInstaller } from './lspInstaller'
import { lspSetupStage, ToolkitError, messages } from 'aws-core-vscode/shared'

export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
export async function activate(ctx: vscode.ExtensionContext) {
try {
await lspSetupStage('all', async () => {
const installResult = await new AmazonQLspInstaller().resolve()
await lspSetupStage('launch', async () => await startLanguageServer(ctx, installResult.resourcePaths))
return await lspSetupStage('launch', () => startLanguageServer(ctx, installResult.resourcePaths))
})
} catch (err) {
const e = err as ToolkitError
Expand Down
Loading
Loading