Skip to content

Commit

Permalink
Merge branch 'master' into dmsUpdates
Browse files Browse the repository at this point in the history
  • Loading branch information
dhasani23 authored Nov 14, 2024
2 parents f4d82a4 + 1d86309 commit 63322df
Show file tree
Hide file tree
Showing 44 changed files with 562 additions and 254 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

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

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
},
"dependencies": {
"@types/node": "^22.7.5",
"@aws-toolkits/telemetry": "^1.0.242",
"vscode-nls": "^5.2.0",
"vscode-nls-dev": "^4.0.4"
}
Expand Down
22 changes: 22 additions & 0 deletions packages/amazonq/.changes/1.36.0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"date": "2024-11-14",
"version": "1.36.0",
"entries": [
{
"type": "Bug Fix",
"description": "Fix broken inline suggestion auto-trigger on Systemverfilog files if users dont have systemverilog extension installed and enabled"
},
{
"type": "Bug Fix",
"description": "tutorial always showing on start"
},
{
"type": "Feature",
"description": "Enable default `@workspace` context of Amazon Q chat for certain users"
},
{
"type": "Feature",
"description": "Amazon Q /dev: Add an action to accept individual files"
}
]
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

7 changes: 7 additions & 0 deletions packages/amazonq/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 1.36.0 2024-11-14

- **Bug Fix** Fix broken inline suggestion auto-trigger on Systemverfilog files if users dont have systemverilog extension installed and enabled
- **Bug Fix** tutorial always showing on start
- **Feature** Enable default `@workspace` context of Amazon Q chat for certain users
- **Feature** Amazon Q /dev: Add an action to accept individual files

## 1.35.0 2024-11-11

- **Breaking Change** Change focus chat keybind to win+alt+i on Windows, cmd+alt+i on macOS, and meta+alt+i on Linux
Expand Down
2 changes: 1 addition & 1 deletion packages/amazonq/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "amazon-q-vscode",
"displayName": "Amazon Q",
"description": "Amazon Q is your generative AI-powered assistant across the software development lifecycle.",
"version": "1.36.0-SNAPSHOT",
"version": "1.37.0-SNAPSHOT",
"extensionKind": [
"workspace"
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from 'aws-core-vscode/test'
import { areEqual, normalize } from 'aws-core-vscode/shared'
import * as path from 'path'
import { LspController } from 'aws-core-vscode/amazonq'

let tempFolder: string

Expand All @@ -39,8 +40,12 @@ describe('crossFileContextUtil', function () {
tempFolder = (await createTestWorkspaceFolder()).uri.fsPath
})

it('opentabs context should fetch 3 chunks and each chunk should contains 50 lines', async function () {
sinon.stub(FeatureConfigProvider.instance, 'isNewProjectContextGroup').alwaysReturned(false)
afterEach(async function () {
sinon.restore()
})

it('for control group, should return opentabs context where there will be 3 chunks and each chunk should contains 50 lines', async function () {
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('control')
await toTextEditor(aStringWithLineCount(200), 'CrossFile.java', tempFolder, { preview: false })
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
preview: false,
Expand All @@ -53,6 +58,110 @@ describe('crossFileContextUtil', function () {
assert.strictEqual(actual.supplementalContextItems[1].content.split('\n').length, 50)
assert.strictEqual(actual.supplementalContextItems[2].content.split('\n').length, 50)
})

it('for t1 group, should return repomap + opentabs context', async function () {
await toTextEditor(aStringWithLineCount(200), 'CrossFile.java', tempFolder, { preview: false })
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
preview: false,
})
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('t1')
sinon
.stub(LspController.instance, 'queryInlineProjectContext')
.withArgs(sinon.match.any, sinon.match.any, 'codemap')
.resolves([
{
content: 'foo',
score: 0,
filePath: 'q-inline',
},
])

const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
assert.ok(actual)
assert.ok(actual.supplementalContextItems.length === 4)
assert.strictEqual(actual?.strategy, 'codemap')
assert.deepEqual(actual?.supplementalContextItems[0], {
content: 'foo',
score: 0,
filePath: 'q-inline',
})

assert.strictEqual(actual.supplementalContextItems[1].content.split('\n').length, 50)
assert.strictEqual(actual.supplementalContextItems[2].content.split('\n').length, 50)
assert.strictEqual(actual.supplementalContextItems[3].content.split('\n').length, 50)
})

it('for t2 group, should return global bm25 context and no repomap', async function () {
await toTextEditor(aStringWithLineCount(200), 'CrossFile.java', tempFolder, { preview: false })
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
preview: false,
})
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('t2')
sinon
.stub(LspController.instance, 'queryInlineProjectContext')
.withArgs(sinon.match.any, sinon.match.any, 'bm25')
.resolves([
{
content: 'foo',
score: 5,
filePath: 'foo.java',
},
{
content: 'bar',
score: 4,
filePath: 'bar.java',
},
{
content: 'baz',
score: 3,
filePath: 'baz.java',
},
{
content: 'qux',
score: 2,
filePath: 'qux.java',
},
{
content: 'quux',
score: 1,
filePath: 'quux.java',
},
])

const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
assert.ok(actual)
assert.ok(actual.supplementalContextItems.length === 5)
assert.strictEqual(actual?.strategy, 'bm25')

assert.deepEqual(actual?.supplementalContextItems[0], {
content: 'foo',
score: 5,
filePath: 'foo.java',
})

assert.deepEqual(actual?.supplementalContextItems[1], {
content: 'bar',
score: 4,
filePath: 'bar.java',
})
assert.deepEqual(actual?.supplementalContextItems[2], {
content: 'baz',
score: 3,
filePath: 'baz.java',
})

assert.deepEqual(actual?.supplementalContextItems[3], {
content: 'qux',
score: 2,
filePath: 'qux.java',
})

assert.deepEqual(actual?.supplementalContextItems[4], {
content: 'quux',
score: 1,
filePath: 'quux.java',
})
})
})

describe('non supported language should return undefined', function () {
Expand Down Expand Up @@ -212,7 +321,7 @@ describe('crossFileContextUtil', function () {

fileExtLists.forEach((fileExt) => {
it('should be non empty', async function () {
sinon.stub(FeatureConfigProvider.instance, 'isNewProjectContextGroup').alwaysReturned(false)
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('control')
const editor = await toTextEditor('content-1', `file-1.${fileExt}`, tempFolder)
await toTextEditor('content-2', `file-2.${fileExt}`, tempFolder, { preview: false })
await toTextEditor('content-3', `file-3.${fileExt}`, tempFolder, { preview: false })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('supplementalContextUtil', function () {

beforeEach(async function () {
testFolder = await TestFolder.create()
sinon.stub(FeatureConfigProvider.instance, 'isNewProjectContextGroup').alwaysReturned(false)
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').alwaysReturned('control')
})

afterEach(function () {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/amazonq/lsp/lspClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,12 @@ export class LspClient {
}
}

async queryInlineProjectContext(query: string, path: string) {
async queryInlineProjectContext(query: string, path: string, target: 'default' | 'codemap' | 'bm25') {
try {
const request = JSON.stringify({
query: query,
filePath: path,
target,
})
const encrypted = await this.encrypt(request)
const resp: any = await this.client?.sendRequest(QueryInlineProjectContextRequestType, encrypted)
Expand Down
9 changes: 6 additions & 3 deletions packages/core/src/amazonq/lsp/lspController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export interface Manifest {
}
const manifestUrl = 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json'
// this LSP client in Q extension is only going to work with these LSP server versions
const supportedLspServerVersions = ['0.1.27']
const supportedLspServerVersions = ['0.1.28']

const nodeBinName = process.platform === 'win32' ? 'node.exe' : 'node'

Expand Down Expand Up @@ -308,10 +308,13 @@ export class LspController {
return resp
}

async queryInlineProjectContext(query: string, path: string) {
async queryInlineProjectContext(query: string, path: string, target: 'bm25' | 'codemap' | 'default') {
try {
return await LspClient.instance.queryInlineProjectContext(query, path)
return await LspClient.instance.queryInlineProjectContext(query, path, target)
} catch (e) {
if (e instanceof Error) {
getLogger().error(`unexpected error while querying inline project context, e=${e.message}`)
}
return []
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/amazonq/lsp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type QueryInlineProjectContextRequest = string
export type QueryInlineProjectContextRequestPayload = {
query: string
filePath: string
target: string
}
export const QueryInlineProjectContextRequestType: RequestType<QueryInlineProjectContextRequest, any, any> =
new RequestType('lsp/queryInlineProjectContext')
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/auth/sso/ssoAccessTokenProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export abstract class SsoAccessTokenProvider {
awsRegion: this.profile.region,
ssoRegistrationExpiresAt: args?.registrationExpiresAt,
ssoRegistrationClientId: args?.registrationClientId,
sessionDuration: getSessionDuration(this.tokenCacheKey),
})

// Reset source in case there is a case where browser login was called but we forgot to set the source.
Expand Down Expand Up @@ -396,7 +397,7 @@ async function pollForTokenWithProgress<T extends { requestId?: string }>(
*/
function getSessionDuration(id: string) {
const creationDate = globals.globalState.getSsoSessionCreationDate(id)
return creationDate !== undefined ? Date.now() - creationDate : undefined
return creationDate !== undefined ? globals.clock.Date.now() - creationDate : undefined
}

/**
Expand Down
15 changes: 2 additions & 13 deletions packages/core/src/awsService/appBuilder/explorer/nodes/appNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { getSamCliContext } from '../../../../shared/sam/cli/samCliContext'
import { SamCliListResourcesParameters } from '../../../../shared/sam/cli/samCliListResources'
import { getDeployedResources, StackResource } from '../../../../lambda/commands/listSamResources'
import * as path from 'path'
import fs from '../../../../shared/fs/fs'
import { generateStackNode } from './deployedStack'

export class AppNode implements TreeNode {
Expand Down Expand Up @@ -61,19 +60,9 @@ export class AppNode implements TreeNode {

// indicate that App exists, but it is empty
if (resources.length === 0) {
if (await fs.exists(this.location.samTemplateUri)) {
return [
createPlaceholderItem(
localize(
'AWS.appBuilder.explorerNode.app.noResource',
'[No resource found in IaC template]'
)
),
]
}
return [
createPlaceholderItem(
localize('AWS.appBuilder.explorerNode.app.noTemplate', '[No IaC templates found in Workspaces]')
localize('AWS.appBuilder.explorerNode.app.noResource', '[No resource found in SAM template]')
),
]
}
Expand All @@ -84,7 +73,7 @@ export class AppNode implements TreeNode {
createPlaceholderItem(
localize(
'AWS.appBuilder.explorerNode.app.noResourceTree',
'[Unable to load Resource tree for this App. Update IaC template]'
'[Unable to load Resource tree for this App. Update SAM template]'
)
),
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export async function getAppNodes(): Promise<TreeNode[]> {
if (appsFound.length === 0) {
return [
createPlaceholderItem(
localize('AWS.appBuilder.explorerNode.noApps', '[No IaC templates found in Workspaces]')
localize('AWS.appBuilder.explorerNode.noApps', '[No SAM templates found in Workspaces]')
),
]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/codewhisperer/activation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export async function activate(context: ExtContext): Promise<void> {

// TODO: this is already done in packages/core/src/extensionCommon.ts, why doesn't amazonq use that?
registerWebviewErrorHandler((error: unknown, webviewId: string, command: string) => {
logAndShowWebviewError(localize, error, webviewId, command)
return logAndShowWebviewError(localize, error, webviewId, command)
})

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/codewhisperer/models/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export const vsCodeState: VsCodeState = {

export type UtgStrategy = 'ByName' | 'ByContent'

export type CrossFileStrategy = 'OpenTabs_BM25'
export type CrossFileStrategy = 'opentabs' | 'codemap' | 'bm25' | 'default'

export type SupplementalContextStrategy = CrossFileStrategy | UtgStrategy | 'Empty' | 'LSP'
export type SupplementalContextStrategy = CrossFileStrategy | UtgStrategy | 'Empty'

export interface CodeWhispererSupplementalContext {
isUtg: boolean
Expand Down
Loading

0 comments on commit 63322df

Please sign in to comment.