Skip to content
Closed
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
20 changes: 16 additions & 4 deletions docs/build.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
# Build

The AmazonQ features rely on the `codewhisperer-streaming` service, who's client
is generated from the service's smithy models and placed in
`src.gen/@amzn/codewhisperer-streaming` (For more
information about this client and how it is generated, please see this
The AmazonQ features rely on the `codewhisperer-streaming` service, to support both Sigv4 and Bearer token modes of this service,
two clients are generated from the service's smithy models and placed in
`src.gen/@amzn/amazon-q-developer-streaming-client` and `src.gen/@amzn/codewhisperer-streaming` respectively (For more
information about these clients and how they are generated, please see this
[quip document](https://quip-amazon.com/2dAWAvTIYXXr/Build-instructions-for-AWS-CodeWhisperer-Streaming-Typescript-client)).

## @amzn/amazon-q-developer-streaming client

This client is a standalone npm project in typescript, and it is added to
the project as a workspace in the project's root `package.json` with the line `"workspaces": [ ..., "src.gen/@amzn/amazon-q-developer-streaming" ]`.
The client may be manually built using `npm run build -w @amzn/amazon-q-developer-streaming"`.
The `generateClients` run script ensures that this dependency is
built before the toolkit project itself. Workspaces are automatically ready to
be imported in the root toolkit project by their declared package.json name,
(`@amzn/amazon-q-developer-streaming` in this case).

## @amzn/codewhisperer-streaming client

This client is a standalone npm project in typescript, and it is added to
the project as a workspace in the project's root `package.json` with the line `"workspaces": [ ..., "src.gen/@amzn/codewhisperer-streaming" ]`.
The client may be manually built using `npm run build -w @amzn/codewhisperer-streaming"`.
Expand Down
20,231 changes: 10,544 additions & 9,687 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
"scripts": {
"prepare": "ts-node ./scripts/prepare.ts",
"preinstall": "cd src.gen/@amzn/codewhisperer-streaming && npm i",
"preinstall": "cd src.gen/@amzn/codewhisperer-streaming && npm i && cd ../amazon-q-developer-streaming-client && npm i",
"postinstall": "npm run buildCustomLintPlugin && npm run postinstall -ws --if-present",
"buildCustomLintPlugin": "npm run build -w plugins/eslint-plugin-aws-toolkits",
"compile": "npm run compile -w packages/",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Use Sagemaker environment IAM Credentials for Code Completion when they're available"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Inline: Code completion not working for Sagemaker Pro Tier users."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Disable /transform and /dev commands for sagemaker users as they're not supported"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Feature",
"description": "Enable Free Tier Chat for IAM users"
}
4 changes: 2 additions & 2 deletions packages/amazonq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,13 @@
"type": "webview",
"id": "aws.amazonq.AmazonCommonAuth",
"name": "%AWS.amazonq.login%",
"when": "!aws.isSageMaker && !aws.isWebExtHost && aws.amazonq.showLoginView"
"when": "!aws.isWebExtHost && aws.amazonq.showLoginView"
},
{
"type": "webview",
"id": "aws.AmazonQChatView",
"name": "%AWS.amazonq.chat%",
"when": "!aws.isSageMaker && !aws.isWebExtHost && !aws.amazonq.showLoginView"
"when": "!aws.isWebExtHost && !aws.amazonq.showLoginView"
},
{
"id": "aws.AmazonQNeverShowBadge",
Expand Down
7 changes: 6 additions & 1 deletion packages/amazonq/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { SendMessageCommandOutput, SendMessageRequest } from '@amzn/amazon-q-developer-streaming-client'
import { GenerateAssistantResponseCommandOutput, GenerateAssistantResponseRequest } from '@amzn/codewhisperer-streaming'
import { AuthUtil } from 'aws-core-vscode/codewhisperer'
import { ChatSession } from 'aws-core-vscode/codewhispererChat'
Expand All @@ -12,7 +13,11 @@ export default {
chatApi: {
async chat(request: GenerateAssistantResponseRequest): Promise<GenerateAssistantResponseCommandOutput> {
const chatSession = new ChatSession()
return chatSession.chat(request)
return chatSession.chatSso(request)
},
async chatIam(request: SendMessageRequest): Promise<SendMessageCommandOutput> {
const chatSession = new ChatSession()
return chatSession.chatIam(request)
},
},
authApi: {
Expand Down
3 changes: 2 additions & 1 deletion packages/amazonq/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
setContext,
setupUninstallHandler,
maybeShowMinVscodeWarning,
isSageMaker,
} from 'aws-core-vscode/shared'
import { ExtStartUpSources, telemetry } from 'aws-core-vscode/telemetry'
import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils'
Expand Down Expand Up @@ -193,7 +194,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
}
}
const currConn = AuthUtil.instance.conn
if (currConn !== undefined && !isAnySsoConnection(currConn)) {
if (currConn !== undefined && !(isAnySsoConnection(currConn) || isSageMaker())) {
getLogger().error(`Current Amazon Q connection is not SSO, type is: %s`, currConn?.type)
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@
"webfont": "^11.2.26"
},
"dependencies": {
"@amzn/amazon-q-developer-streaming-client": "file:../../src.gen/@amzn/amazon-q-developer-streaming-client",
"@amzn/codewhisperer-streaming": "file:../../src.gen/@amzn/codewhisperer-streaming",
"@aws-sdk/client-cognito-identity": "^3.637.0",
"@aws-sdk/client-lambda": "^3.637.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/amazonq/extApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import vscode from 'vscode'
import { VSCODE_EXTENSION_ID } from '../shared/utilities'
import { SendMessageCommandOutput, SendMessageRequest } from '@amzn/amazon-q-developer-streaming-client'
import { GenerateAssistantResponseCommandOutput, GenerateAssistantResponseRequest } from '@amzn/codewhisperer-streaming'
import { FeatureAuthState } from '../codewhisperer/util/authUtil'
import { ToolkitError } from '../shared'
Expand All @@ -16,6 +17,7 @@ import { ToolkitError } from '../shared'
export interface api {
chatApi: {
chat(request: GenerateAssistantResponseRequest): Promise<GenerateAssistantResponseCommandOutput>
chatIam(request: SendMessageRequest): Promise<SendMessageCommandOutput>
}
authApi: {
reauthIfNeeded(): Promise<void>
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/amazonq/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ import { FeatureContext } from '../shared'
export function createMynahUI(
ideApi: any,
amazonQEnabled: boolean,
featureConfigsSerialized: [string, FeatureContext][]
featureConfigsSerialized: [string, FeatureContext][],
disabledCommands?: string[]
) {
if (typeof window !== 'undefined') {
const mynahUI = require('./webview/ui/main')
return mynahUI.createMynahUI(ideApi, amazonQEnabled, featureConfigsSerialized)
return mynahUI.createMynahUI(ideApi, amazonQEnabled, featureConfigsSerialized, disabledCommands)
}
throw new Error('Not implemented for node')
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import path from 'path'
import { Uri, Webview } from 'vscode'
import { AuthUtil } from '../../../codewhisperer/util/authUtil'
import { FeatureConfigProvider, FeatureContext, globals } from '../../../shared'
import { FeatureConfigProvider, FeatureContext, globals, isSageMaker } from '../../../shared'

export class WebViewContentGenerator {
private async generateFeatureConfigsData(): Promise<string> {
Expand Down Expand Up @@ -77,14 +77,16 @@ export class WebViewContentGenerator {
// Fetch featureConfigs and use it within the script
const featureConfigsString = await this.generateFeatureConfigsData()

const disabledCommandsString = isSageMaker() ? `['/dev', '/transform']` : '[]'

return `
<script type="text/javascript" src="${javascriptEntrypoint.toString()}" defer onload="init()"></script>
${cssLinks}
<script type="text/javascript">
const init = () => {
createMynahUI(acquireVsCodeApi(), ${
(await AuthUtil.instance.getChatAuthState()).amazonQ === 'connected'
},${featureConfigsString});
},${featureConfigsString},${disabledCommandsString});
}
</script>
`
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/amazonq/webview/ui/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import { tryNewMap } from '../../util/functionUtils'
export const createMynahUI = (
ideApi: any,
amazonQEnabled: boolean,
featureConfigsSerialized: [string, FeatureContext][]
featureConfigsSerialized: [string, FeatureContext][],
disabledCommands?: string[]
) => {
// eslint-disable-next-line prefer-const
let mynahUI: MynahUI
Expand Down Expand Up @@ -77,6 +78,7 @@ export const createMynahUI = (
let tabDataGenerator = new TabDataGenerator({
isFeatureDevEnabled,
isGumbyEnabled,
disabledCommands,
})

// eslint-disable-next-line prefer-const
Expand Down Expand Up @@ -118,11 +120,13 @@ export const createMynahUI = (
tabsStorage,
isFeatureDevEnabled,
isGumbyEnabled,
disabledCommands,
})

tabDataGenerator = new TabDataGenerator({
isFeatureDevEnabled,
isGumbyEnabled,
disabledCommands,
})

featureConfigs = tryNewMap(featureConfigsSerialized)
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/amazonq/webview/ui/messages/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface MessageControllerProps {
tabsStorage: TabsStorage
isFeatureDevEnabled: boolean
isGumbyEnabled: boolean
disabledCommands?: string[]
}

export class MessageController {
Expand All @@ -30,6 +31,7 @@ export class MessageController {
this.tabDataGenerator = new TabDataGenerator({
isFeatureDevEnabled: props.isFeatureDevEnabled,
isGumbyEnabled: props.isGumbyEnabled,
disabledCommands: props.disabledCommands,
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ import { TabType } from '../storages/tabsStorage'
export interface QuickActionGeneratorProps {
isFeatureDevEnabled: boolean
isGumbyEnabled: boolean
disableCommands?: string[]
}

export class QuickActionGenerator {
public isFeatureDevEnabled: boolean
private isGumbyEnabled: boolean
private disabledCommands: string[]

constructor(props: QuickActionGeneratorProps) {
this.isFeatureDevEnabled = props.isFeatureDevEnabled
this.isGumbyEnabled = props.isGumbyEnabled
this.disabledCommands = props.disableCommands ?? []
}

public generateForTab(tabType: TabType): QuickActionCommandGroup[] {
const quickActionCommands = [
{
commands: [
...(this.isFeatureDevEnabled
...(this.isFeatureDevEnabled && !this.disabledCommands.includes('/dev')
? [
{
command: '/dev',
Expand All @@ -33,7 +36,7 @@ export class QuickActionGenerator {
},
]
: []),
...(this.isGumbyEnabled
...(this.isGumbyEnabled && !this.disabledCommands.includes('/transform')
? [
{
command: '/transform',
Expand All @@ -55,7 +58,7 @@ export class QuickActionGenerator {
},
],
},
]
].filter((section) => section.commands.length > 0)

const commandUnavailability: Record<
TabType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface QuickActionsHandlerProps {
tabsStorage: TabsStorage
isFeatureDevEnabled: boolean
isGumbyEnabled: boolean
disabledCommands?: string[]
}

export class QuickActionHandler {
Expand All @@ -32,6 +33,7 @@ export class QuickActionHandler {
this.tabDataGenerator = new TabDataGenerator({
isFeatureDevEnabled: props.isFeatureDevEnabled,
isGumbyEnabled: props.isGumbyEnabled,
disabledCommands: props.disabledCommands,
})
this.isFeatureDevEnabled = props.isFeatureDevEnabled
this.isGumbyEnabled = props.isGumbyEnabled
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/amazonq/webview/ui/tabs/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { TabTypeDataMap } from './constants'
export interface TabDataGeneratorProps {
isFeatureDevEnabled: boolean
isGumbyEnabled: boolean
disabledCommands?: string[]
}

export class TabDataGenerator {
Expand All @@ -23,6 +24,7 @@ export class TabDataGenerator {
this.quickActionsGenerator = new QuickActionGenerator({
isFeatureDevEnabled: props.isFeatureDevEnabled,
isGumbyEnabled: props.isGumbyEnabled,
disableCommands: props.disabledCommands,
})
}

Expand Down
16 changes: 14 additions & 2 deletions packages/core/src/auth/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@
* SPDX-License-Identifier: Apache-2.0
*/

import * as vscode from 'vscode'
import { Auth } from './auth'
import { LoginManager } from './deprecated/loginManager'
import { fromString } from './providers/credentials'
import { getLogger } from '../shared/logger'
import { ExtensionUse } from './utils'
import { isCloud9 } from '../shared/extensionUtilities'
import { ExtensionUse, initializeCredentialsProviderManager } from './utils'
import { isAmazonQ, isCloud9, isSageMaker } from '../shared/extensionUtilities'
import { isInDevEnv } from '../shared/vscode/env'
import { isWeb } from '../shared/extensionGlobals'

interface SagemakerCookie {
authMode?: 'Sso' | 'Iam'
}

export async function initialize(loginManager: LoginManager): Promise<void> {
if (isAmazonQ() && isSageMaker()) {
// The command `sagemaker.parseCookies` is registered in VS Code Sagemaker environment.
const result = (await vscode.commands.executeCommand('sagemaker.parseCookies')) as SagemakerCookie
if (result.authMode !== 'Sso') {
initializeCredentialsProviderManager()
}
}
Auth.instance.onDidChangeActiveConnection(async (conn) => {
// This logic needs to be moved to `Auth.useConnection` to correctly record `passive`
if (conn?.type === 'iam' && conn.state === 'valid') {
Expand Down
11 changes: 11 additions & 0 deletions packages/core/src/auth/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ import { ExtStartUpSources } from '../shared/telemetry'
import { CommonAuthWebview } from '../login/webview/vue/backend'
import { AuthSource } from '../login/webview/util'
import { setContext } from '../shared/vscode/setContext'
import { CredentialsProviderManager } from './providers/credentialsProviderManager'
import { SharedCredentialsProviderFactory } from './providers/sharedCredentialsProviderFactory'
import { Ec2CredentialsProvider } from './providers/ec2CredentialsProvider'
import { EcsCredentialsProvider } from './providers/ecsCredentialsProvider'
import { EnvVarsCredentialsProvider } from './providers/envVarsCredentialsProvider'

// iam-only excludes Builder ID and IAM Identity Center from the list of valid connections
// TODO: Understand if "iam" should include these from the list at all
Expand Down Expand Up @@ -731,3 +736,9 @@ export function getAuthFormIdsFromConnection(conn?: Connection): AuthFormId[] {

return authIds
}

export function initializeCredentialsProviderManager() {
const manager = CredentialsProviderManager.getInstance()
manager.addProviderFactory(new SharedCredentialsProviderFactory())
manager.addProviders(new Ec2CredentialsProvider(), new EcsCredentialsProvider(), new EnvVarsCredentialsProvider())
}
Loading
Loading