From 9f44fa6bb8dfad737df4f33240a0131e0275f4d1 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Tue, 6 May 2025 18:40:07 +0000 Subject: [PATCH 01/19] Release 3.60.0 --- package-lock.json | 4 ++-- packages/toolkit/.changes/3.60.0.json | 5 +++++ packages/toolkit/CHANGELOG.md | 4 ++++ packages/toolkit/package.json | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 packages/toolkit/.changes/3.60.0.json diff --git a/package-lock.json b/package-lock.json index 50e66f18b6c..c91bf2b987f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", "pretty-quick": "^4.0.0", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "typescript": "^5.0.4", "webpack": "^5.95.0", "webpack-cli": "^5.1.4", @@ -28098,7 +28098,7 @@ }, "packages/toolkit": { "name": "aws-toolkit-vscode", - "version": "3.60.0-SNAPSHOT", + "version": "3.60.0", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" diff --git a/packages/toolkit/.changes/3.60.0.json b/packages/toolkit/.changes/3.60.0.json new file mode 100644 index 00000000000..2464e57a4b0 --- /dev/null +++ b/packages/toolkit/.changes/3.60.0.json @@ -0,0 +1,5 @@ +{ + "date": "2025-05-06", + "version": "3.60.0", + "entries": [] +} \ No newline at end of file diff --git a/packages/toolkit/CHANGELOG.md b/packages/toolkit/CHANGELOG.md index 215c7c68cba..e21988fcd50 100644 --- a/packages/toolkit/CHANGELOG.md +++ b/packages/toolkit/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.60.0 2025-05-06 + +- Miscellaneous non-user-facing changes + ## 3.59.0 2025-05-05 - Miscellaneous non-user-facing changes diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index cffb69d0c1a..107245f54f2 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -2,7 +2,7 @@ "name": "aws-toolkit-vscode", "displayName": "AWS Toolkit", "description": "Including CodeCatalyst, Infrastructure Composer, and support for Lambda, S3, CloudWatch Logs, CloudFormation, and many other services.", - "version": "3.60.0-SNAPSHOT", + "version": "3.60.0", "extensionKind": [ "workspace" ], From 734bd989cec31e715f89bcd2f544397dada798c4 Mon Sep 17 00:00:00 2001 From: Tom Zu <138054255+tomcat323@users.noreply.github.com> Date: Thu, 8 May 2025 13:40:07 -0400 Subject: [PATCH 02/19] fix(nep): truncate editor state (#7256) ## Problem We introduced `editorState` in data instrumentation launch. The service has a requirement of 40k character limit for the `text` field. ## Solution Implement a check on text length. If the text length exceeds 40k characters, section 20k max characters from the left and right side of current cursor position, so the final text is always less than 40k. validated prod endpoint inline working for files > 40k characters. Example request id: `57bbbe65-fbe7-47fc-81c4-c65262f47ce8` --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- ...-75375702-36b5-4e89-af57-4afe983a7238.json | 4 ++++ .../src/codewhisperer/models/constants.ts | 3 +++ .../src/codewhisperer/util/editorContext.ts | 21 +++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json b/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json new file mode 100644 index 00000000000..83796afaa55 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Avoid inline completion 'Improperly formed request' errors when file is too large" +} diff --git a/packages/core/src/codewhisperer/models/constants.ts b/packages/core/src/codewhisperer/models/constants.ts index dc0426376ce..73b0b475a2b 100644 --- a/packages/core/src/codewhisperer/models/constants.ts +++ b/packages/core/src/codewhisperer/models/constants.ts @@ -87,6 +87,9 @@ export const lineBreakWin = '\r\n' export const supplementalContextTimeoutInMs = 100 export const supplementalContextMaxTotalLength = 20480 + +export const editorStateMaxLength = 40000 + /** * Ux of recommendations */ diff --git a/packages/core/src/codewhisperer/util/editorContext.ts b/packages/core/src/codewhisperer/util/editorContext.ts index 0861b982d13..58301e176f6 100644 --- a/packages/core/src/codewhisperer/util/editorContext.ts +++ b/packages/core/src/codewhisperer/util/editorContext.ts @@ -8,10 +8,11 @@ import * as codewhispererClient from '../client/codewhisperer' import * as path from 'path' import * as CodeWhispererConstants from '../models/constants' import { getTabSizeSetting } from '../../shared/utilities/editorUtilities' +import { truncate } from '../../shared/utilities/textUtilities' import { getLogger } from '../../shared/logger/logger' import { runtimeLanguageContext } from './runtimeLanguageContext' import { fetchSupplementalContext } from './supplementalContext/supplementalContextUtil' -import { supplementalContextTimeoutInMs } from '../models/constants' +import { editorStateMaxLength, supplementalContextTimeoutInMs } from '../models/constants' import { getSelectedCustomization } from './customizationUtil' import { selectFrom } from '../../shared/utilities/tsUtils' import { checkLeftContextKeywordsForJson } from './commonUtil' @@ -216,13 +217,29 @@ export function getTabSize(): number { export function getEditorState(editor: vscode.TextEditor, fileContext: codewhispererClient.FileContext): any { try { + const cursorPosition = editor.selection.active + const cursorOffset = editor.document.offsetAt(cursorPosition) + const documentText = editor.document.getText() + + // Truncate if document content is too large (defined in constants.ts) + let fileText = documentText + if (documentText.length > editorStateMaxLength) { + const halfLength = Math.floor(editorStateMaxLength / 2) + + // Use truncate function to get the text around the cursor position + const leftPart = truncate(documentText.substring(0, cursorOffset), -halfLength, '') + const rightPart = truncate(documentText.substring(cursorOffset), halfLength, '') + + fileText = leftPart + rightPart + } + return { document: { programmingLanguage: { languageName: fileContext.programmingLanguage.languageName, }, relativeFilePath: fileContext.filename, - text: editor.document.getText(), + text: fileText, }, cursorState: { position: { From 529f833454dc29fddd68511f84266f9015215f4c Mon Sep 17 00:00:00 2001 From: Will Lo <96078566+Will-ShaoHua@users.noreply.github.com> Date: Thu, 8 May 2025 13:58:02 -0700 Subject: [PATCH 03/19] fix(amazonq): Revert refactor(amazonq): reduce extra call of listAvailableCustomization (#7242) (#7266) This reverts commit 98b0d5d1e9b1ea594e6ce0a76045072528b5fc7a. ## Problem It regress #7181 and make 7181 not working: profile will be changed, but customization will be swapped to default always. ## Solution --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- .../src/codewhisperer/util/customizationUtil.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/core/src/codewhisperer/util/customizationUtil.ts b/packages/core/src/codewhisperer/util/customizationUtil.ts index d989fadf05c..600317c53e0 100644 --- a/packages/core/src/codewhisperer/util/customizationUtil.ts +++ b/packages/core/src/codewhisperer/util/customizationUtil.ts @@ -59,7 +59,7 @@ export const onProfileChangedListener: (event: ProfileChangedEvent) => any = asy if (event.intent === 'customization') { return } - + const logger = getLogger() if (!event.profile) { await setSelectedCustomization(baseCustomization) return @@ -69,7 +69,16 @@ export const onProfileChangedListener: (event: ProfileChangedEvent) => any = asy const selectedCustomization = getSelectedCustomization() // No need to validate base customization which has empty arn. if (selectedCustomization.arn.length > 0) { - await switchToBaseCustomizationAndNotify() + const customizationProvider = await CustomizationProvider.init(event.profile) + const customizations = await customizationProvider.listAvailableCustomizations() + + const r = customizations.find((it) => it.arn === selectedCustomization.arn) + if (!r) { + logger.debug( + `profile ${event.profile.name} doesnt have access to customization ${selectedCustomization.name} but has access to ${customizations.map((it) => it.name)}` + ) + await switchToBaseCustomizationAndNotify() + } } } From 8a02d60b5c0ba292bcf2c8026b2417a034086be5 Mon Sep 17 00:00:00 2001 From: Tai Lai Date: Thu, 8 May 2025 14:09:21 -0700 Subject: [PATCH 04/19] fix(amazonq): agent tabs open with prompt options (#7265) ## Problem Inconsistent behavior when opening agent tabs (/review, /doc, etc). When the tab is reused it keeps the prompt input options visible, but when a new tab is created it doesn't. https://github.com/user-attachments/assets/2ff7264f-f7a3-46f6-9a34-e29835768833 ## Solution Set `promptInputOptions` to empty when an existing tab is reused. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- .../Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json | 4 ++++ packages/core/src/amazonq/webview/ui/quickActions/handler.ts | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json b/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json new file mode 100644 index 00000000000..02c9a67d136 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Named agent tabs sometimes open with unnecessary input options" +} diff --git a/packages/core/src/amazonq/webview/ui/quickActions/handler.ts b/packages/core/src/amazonq/webview/ui/quickActions/handler.ts index fe124d1fc0c..f0d707247e9 100644 --- a/packages/core/src/amazonq/webview/ui/quickActions/handler.ts +++ b/packages/core/src/amazonq/webview/ui/quickActions/handler.ts @@ -355,6 +355,8 @@ export class QuickActionHandler { loadingChat: true, cancelButtonWhenLoading: false, }) + } else { + this.mynahUI.updateStore(affectedTabId, { promptInputOptions: [] }) } if (affectedTabId && this.isHybridChatEnabled) { From 4369fb507fa79f2f6a56b8c5f3dd5b34f272733e Mon Sep 17 00:00:00 2001 From: Josh Pinkney <103940141+jpinkney-aws@users.noreply.github.com> Date: Thu, 8 May 2025 21:09:13 -0400 Subject: [PATCH 05/19] fix(amazonq): flare clientId changes on every instance (#7273) ## Problem clientId from `clientParams.initializationOptions?.aws?.clientInfo?.clientId` is random on every restart ## Solution use the client id from telemetry utils --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- packages/amazonq/src/lsp/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index 5cbf174e577..e3b58455d77 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -5,7 +5,6 @@ import vscode, { env, version } from 'vscode' import * as nls from 'vscode-nls' -import * as crypto from 'crypto' import { LanguageClient, LanguageClientOptions, RequestType, State } from 'vscode-languageclient' import { InlineCompletionManager } from '../app/inline/completion' import { AmazonQLspAuth, encryptionKey, notificationTypes } from './auth' @@ -34,6 +33,7 @@ import { getOptOutPreference, isAmazonInternalOs, fs, + getClientId, } from 'aws-core-vscode/shared' import { processUtils } from 'aws-core-vscode/shared' import { activate } from './chat/activation' @@ -120,7 +120,7 @@ export async function startLanguageServer( name: 'AmazonQ-For-VSCode', version: '0.0.1', }, - clientId: crypto.randomUUID(), + clientId: getClientId(globals.globalState), }, awsClientCapabilities: { q: { From 0d97988720489dfecd59991c449988ab760b6824 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Fri, 9 May 2025 01:16:29 +0000 Subject: [PATCH 06/19] Release 1.66.0 --- package-lock.json | 4 ++-- packages/amazonq/.changes/1.66.0.json | 14 ++++++++++++++ ...g Fix-75375702-36b5-4e89-af57-4afe983a7238.json | 4 ---- ...g Fix-b873a959-2742-4440-badc-c90c6ac754c3.json | 4 ---- packages/amazonq/CHANGELOG.md | 5 +++++ packages/amazonq/package.json | 2 +- 6 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 packages/amazonq/.changes/1.66.0.json delete mode 100644 packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json delete mode 100644 packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json diff --git a/package-lock.json b/package-lock.json index c5a890c2260..5c66ecf29e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", "pretty-quick": "^4.0.0", - "ts-node": "^10.9.1", + "ts-node": "^10.9.2", "typescript": "^5.0.4", "webpack": "^5.95.0", "webpack-cli": "^5.1.4", @@ -26384,7 +26384,7 @@ }, "packages/amazonq": { "name": "amazon-q-vscode", - "version": "1.66.0-SNAPSHOT", + "version": "1.66.0", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" diff --git a/packages/amazonq/.changes/1.66.0.json b/packages/amazonq/.changes/1.66.0.json new file mode 100644 index 00000000000..ab4a819b85a --- /dev/null +++ b/packages/amazonq/.changes/1.66.0.json @@ -0,0 +1,14 @@ +{ + "date": "2025-05-09", + "version": "1.66.0", + "entries": [ + { + "type": "Bug Fix", + "description": "Avoid inline completion 'Improperly formed request' errors when file is too large" + }, + { + "type": "Bug Fix", + "description": "Named agent tabs sometimes open with unnecessary input options" + } + ] +} \ No newline at end of file diff --git a/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json b/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json deleted file mode 100644 index 83796afaa55..00000000000 --- a/packages/amazonq/.changes/next-release/Bug Fix-75375702-36b5-4e89-af57-4afe983a7238.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "Bug Fix", - "description": "Avoid inline completion 'Improperly formed request' errors when file is too large" -} diff --git a/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json b/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json deleted file mode 100644 index 02c9a67d136..00000000000 --- a/packages/amazonq/.changes/next-release/Bug Fix-b873a959-2742-4440-badc-c90c6ac754c3.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "Bug Fix", - "description": "Named agent tabs sometimes open with unnecessary input options" -} diff --git a/packages/amazonq/CHANGELOG.md b/packages/amazonq/CHANGELOG.md index b5ceba33c7c..197aecdfdf6 100644 --- a/packages/amazonq/CHANGELOG.md +++ b/packages/amazonq/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.66.0 2025-05-09 + +- **Bug Fix** Avoid inline completion 'Improperly formed request' errors when file is too large +- **Bug Fix** Named agent tabs sometimes open with unnecessary input options + ## 1.65.0 2025-05-05 - **Feature** Support selecting customizations across all Q profiles with automatic profile switching for enterprise users diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 0553b16a973..4197556075d 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -2,7 +2,7 @@ "name": "amazon-q-vscode", "displayName": "Amazon Q", "description": "The most capable generative AI-powered assistant for building, operating, and transforming software, with advanced capabilities for managing data and AI", - "version": "1.66.0-SNAPSHOT", + "version": "1.66.0", "extensionKind": [ "workspace" ], From dcaeb535747bb694a4637d155823aa8e800aab72 Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Fri, 9 May 2025 13:56:54 +0000 Subject: [PATCH 07/19] Update version to snapshot version: 3.61.0-SNAPSHOT --- package-lock.json | 4 ++-- packages/toolkit/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c91bf2b987f..dcdfcc8b0d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", "pretty-quick": "^4.0.0", - "ts-node": "^10.9.2", + "ts-node": "^10.9.1", "typescript": "^5.0.4", "webpack": "^5.95.0", "webpack-cli": "^5.1.4", @@ -28098,7 +28098,7 @@ }, "packages/toolkit": { "name": "aws-toolkit-vscode", - "version": "3.60.0", + "version": "3.61.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 107245f54f2..077030c66cb 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -2,7 +2,7 @@ "name": "aws-toolkit-vscode", "displayName": "AWS Toolkit", "description": "Including CodeCatalyst, Infrastructure Composer, and support for Lambda, S3, CloudWatch Logs, CloudFormation, and many other services.", - "version": "3.60.0", + "version": "3.61.0-SNAPSHOT", "extensionKind": [ "workspace" ], From 91e5039d2d2127fedfbdafc9b212e1984c64326b Mon Sep 17 00:00:00 2001 From: aws-toolkit-automation <> Date: Fri, 9 May 2025 13:58:47 +0000 Subject: [PATCH 08/19] Update version to snapshot version: 1.67.0-SNAPSHOT --- package-lock.json | 4 ++-- packages/amazonq/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5c66ecf29e7..4c9375c6b7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", "pretty-quick": "^4.0.0", - "ts-node": "^10.9.2", + "ts-node": "^10.9.1", "typescript": "^5.0.4", "webpack": "^5.95.0", "webpack-cli": "^5.1.4", @@ -26384,7 +26384,7 @@ }, "packages/amazonq": { "name": "amazon-q-vscode", - "version": "1.66.0", + "version": "1.67.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "aws-core-vscode": "file:../core/" diff --git a/packages/amazonq/package.json b/packages/amazonq/package.json index 4197556075d..f9d466f5767 100644 --- a/packages/amazonq/package.json +++ b/packages/amazonq/package.json @@ -2,7 +2,7 @@ "name": "amazon-q-vscode", "displayName": "Amazon Q", "description": "The most capable generative AI-powered assistant for building, operating, and transforming software, with advanced capabilities for managing data and AI", - "version": "1.66.0", + "version": "1.67.0-SNAPSHOT", "extensionKind": [ "workspace" ], From 1085a8de0d19e2989693fa4616cb265f9705ecc6 Mon Sep 17 00:00:00 2001 From: Nikolas Komonen <118216176+nkomonen-amazon@users.noreply.github.com> Date: Fri, 9 May 2025 12:22:46 -0400 Subject: [PATCH 09/19] telemetry(amazonq): Emit metric on server crash (#7278) When the server crashes and then restarts again, we will emit a metric to indicate it crashed. When querying look for: `metadata.metricName: languageServer_crash` & `metadata.id: AmazonQ` --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. Signed-off-by: nkomonen-amazon --- packages/amazonq/src/lsp/client.ts | 7 +++++++ packages/core/src/shared/telemetry/vscodeTelemetry.json | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index e3b58455d77..4735d9cbc8c 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -39,6 +39,7 @@ import { processUtils } from 'aws-core-vscode/shared' import { activate } from './chat/activation' import { AmazonQResourcePaths } from './lspInstaller' import { ConfigSection, isValidConfigSection, toAmazonQLSPLogLevel } from './config' +import { telemetry } from 'aws-core-vscode/telemetry' const localize = nls.loadMessageBundle() const logger = getLogger('amazonqLsp.lspClient') @@ -288,6 +289,12 @@ function onServerRestartHandler(client: LanguageClient, auth: AmazonQLspAuth) { return } + // Emit telemetry that a crash was detected. + // It is not guaranteed to 100% be a crash since somehow the server may have been intentionally restarted, + // but most of the time it probably will have been due to a crash. + // TODO: Port this metric override to common definitions + telemetry.languageServer_crash.emit({ id: 'AmazonQ' }) + // Need to set the auth token in the again await auth.refreshConnection(true) }) diff --git a/packages/core/src/shared/telemetry/vscodeTelemetry.json b/packages/core/src/shared/telemetry/vscodeTelemetry.json index 4a5117ee252..b28aeec4847 100644 --- a/packages/core/src/shared/telemetry/vscodeTelemetry.json +++ b/packages/core/src/shared/telemetry/vscodeTelemetry.json @@ -1019,6 +1019,15 @@ } ] }, + { + "name": "languageServer_crash", + "description": "Called when a language server crash is detected. TODO: Port this to common", + "metadata": [ + { + "type": "id" + } + ] + }, { "name": "ide_heartbeat", "description": "A heartbeat sent by the extension", From a14b9a215b63144f63745299fd0f6c74bbe68150 Mon Sep 17 00:00:00 2001 From: Adam Khamis <110852798+akhamis-amzn@users.noreply.github.com> Date: Fri, 9 May 2025 15:52:44 -0400 Subject: [PATCH 10/19] telemetry(amazonq): expose FileCreationFailed exceptions #7260 ## Problem FileCreationFailed exceptions are displayed as UnknownException in telemetry. This exception is new and we want to separate this out from other unknown exceptions. ## Solution Return API service error with `FileCreationFailedException` --- .../core/src/amazonqFeatureDev/session/sessionState.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/core/src/amazonqFeatureDev/session/sessionState.ts b/packages/core/src/amazonqFeatureDev/session/sessionState.ts index 5890539409f..5879c16493f 100644 --- a/packages/core/src/amazonqFeatureDev/session/sessionState.ts +++ b/packages/core/src/amazonqFeatureDev/session/sessionState.ts @@ -205,6 +205,14 @@ export class FeatureDevCodeGenState extends BaseCodeGenState { 429 ) } + case codegenResult.codeGenerationStatusDetail?.includes('FileCreationFailed'): { + return new ApiServiceError( + i18n('AWS.amazonq.featureDev.error.codeGen.default'), + 'GetTaskAssistCodeGeneration', + 'FileCreationFailedException', + 500 + ) + } default: { return new ApiServiceError( i18n('AWS.amazonq.featureDev.error.codeGen.default'), From 05cde57b3d526d3b69727b3f7a40c1ca585fb6ba Mon Sep 17 00:00:00 2001 From: Na Yue Date: Fri, 9 May 2025 15:15:14 -0700 Subject: [PATCH 11/19] fix(lsp): send extension version to Q LSP #7279 ## Problem Extension version sent to Q LSP is hardcoded. ## Solution Ssend the actual extension version BEFORE: aws-sdk-nodejs/2.1692.0 darwin/v23.10.0 AWS-Language-Servers AWS-CodeWhisperer/0.1.0 AmazonQ-For-VSCode/0.0.1 Visual-Studio-Code---Insiders/1.100.0-insider ClientId/c342ab45-6aba-4118-b48c-44dcedb10a78 promise AFTER aws-sdk-nodejs/2.1692.0 darwin/v23.10.0 AWS-Language-Servers AWS-CodeWhisperer/0.1.0 AmazonQ-For-VSCode/testPluginVersion Visual-Studio-Code---Insiders/1.100.0-insider ClientId/c342ab45-6aba-4118-b48c-44dcedb10a78 promise --- packages/amazonq/src/lsp/client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index 4735d9cbc8c..d20f8067103 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -34,6 +34,7 @@ import { isAmazonInternalOs, fs, getClientId, + extensionVersion, } from 'aws-core-vscode/shared' import { processUtils } from 'aws-core-vscode/shared' import { activate } from './chat/activation' @@ -119,7 +120,7 @@ export async function startLanguageServer( version: version, extension: { name: 'AmazonQ-For-VSCode', - version: '0.0.1', + version: extensionVersion, }, clientId: getClientId(globals.globalState), }, From 4b091678205c84954735a2a1ff1f5c087c4f7116 Mon Sep 17 00:00:00 2001 From: Laxman Reddy <141967714+laileni-aws@users.noreply.github.com> Date: Fri, 9 May 2025 16:00:28 -0700 Subject: [PATCH 12/19] fix(amazonq): adding logs for the agentic chat telemetry events (#7276) ## Problem - No logs is being emitted for telemetry events. ## Solution - Adding logs if telemetry events are emitted. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- packages/amazonq/src/lsp/chat/messages.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/amazonq/src/lsp/chat/messages.ts b/packages/amazonq/src/lsp/chat/messages.ts index 9578858b708..38a52f72f9c 100644 --- a/packages/amazonq/src/lsp/chat/messages.ts +++ b/packages/amazonq/src/lsp/chat/messages.ts @@ -94,6 +94,7 @@ export function registerLanguageServerEventListener(languageClient: LanguageClie const telemetryName: string = e.name if (telemetryName in telemetry) { + languageClient.info(`[Telemetry] Emitting ${telemetryName} telemetry: ${JSON.stringify(e.data)}`) telemetry[telemetryName as keyof TelemetryBase].emit(e.data) } }) From ffc0cb47cfd017a6ec033613a6d453f4cd433eb3 Mon Sep 17 00:00:00 2001 From: Jiatong Li Date: Mon, 12 May 2025 14:34:05 -0700 Subject: [PATCH 13/19] fix(amazonq): pass uri.path as workspaceIdentifier when initializing #7291 ## Problem `workspaceIdentifier` should be a string: - https://github.com/aws/language-server-runtimes/pull/497 ## Solution Pass `extensionContext.storageUri?.path`. --- packages/amazonq/src/lsp/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index d20f8067103..4af113b13c4 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -134,7 +134,7 @@ export async function startLanguageServer( }, }, contextConfiguration: { - workspaceIdentifier: extensionContext.storageUri, + workspaceIdentifier: extensionContext.storageUri?.path, }, logLevel: toAmazonQLSPLogLevel(globals.logOutputChannel.logLevel), }, From 2d898fbac0bb0418ffc51b22d38202617bff2bfa Mon Sep 17 00:00:00 2001 From: Avi Alpert <131792194+avi-alpert@users.noreply.github.com> Date: Mon, 12 May 2025 17:36:08 -0400 Subject: [PATCH 14/19] deps: bump @aws-toolkits/telemetry to 1.0.318 #7290 ## Problem New telemetry metrics were [added](https://github.com/aws/aws-toolkit-common/pull/1023) to aws-toolkit-common ## Solution Consume latest version of aws-toolkit-common package --- package-lock.json | 9 ++++----- package.json | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a36cb6df6a..e5f1e7e7a70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "vscode-nls-dev": "^4.0.4" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.317", + "@aws-toolkits/telemetry": "^1.0.318", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", @@ -10760,11 +10760,10 @@ } }, "node_modules/@aws-toolkits/telemetry": { - "version": "1.0.317", - "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.317.tgz", - "integrity": "sha512-QFLBFfHZjuB2pBd1p0Tn/GMKTYYQu3/nrlj0Co7EkqozvDNDG0nTjxtkXxotbwjrqVD5Sv8i46gEdgsyQ7at3w==", + "version": "1.0.318", + "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.318.tgz", + "integrity": "sha512-L64GJ+KRN0fdTIx1CPIbbgBeFcg9DilsIxfjeZyod7ld0mw6he70rPopBtK4jP+pTEkfUE4wTRsaco1nWXz3+w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "ajv": "^6.12.6", "cross-spawn": "^7.0.6", diff --git a/package.json b/package.json index 30f0497cdb2..f4b31c22d83 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "skippedTestReport": "ts-node ./scripts/skippedTestReport.ts ./packages/amazonq/test/e2e/" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.317", + "@aws-toolkits/telemetry": "^1.0.318", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", From 8e85476708e0d2e9467cc7afe13a42661de78f1d Mon Sep 17 00:00:00 2001 From: Brad Skaggs <126105424+brdskggs@users.noreply.github.com> Date: Tue, 13 May 2025 11:54:16 -0400 Subject: [PATCH 15/19] fix(amazonq): use neighbor cells as completion context in Notebook #7086 ## Problem VS Code treats each cell in a notebook as a separate editor. As a result, when building the left- and right-contexts for the completion from the current editor, we were limited to just the current cell, which might be very small and/or reference variables and functions defined in other cells. That meant that completions never used the context of other cells when making suggestions, and were often _very_ generic. https://github.com/aws/aws-toolkit-vscode/issues/7031 ## Solution The `extractContextForCodeWhisperer` function now checks if it is being called in a cell in a Jupyter notebook. If so, it collects the surrounding cells to use as context, respecting the maximum context length. During this process, Markdown cells have each line prefixed with a language-specific comment character. --- ...-9b0e6490-39a8-445f-9d67-9d762de7421c.json | 4 + .../codewhisperer/util/editorContext.test.ts | 219 ++++++++++++++++++ .../util/runtimeLanguageContext.test.ts | 34 +++ .../src/codewhisperer/util/editorContext.ts | 125 +++++++++- .../util/runtimeLanguageContext.ts | 50 ++++ 5 files changed, 429 insertions(+), 3 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-9b0e6490-39a8-445f-9d67-9d762de7421c.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-9b0e6490-39a8-445f-9d67-9d762de7421c.json b/packages/amazonq/.changes/next-release/Bug Fix-9b0e6490-39a8-445f-9d67-9d762de7421c.json new file mode 100644 index 00000000000..f17516bb8f4 --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-9b0e6490-39a8-445f-9d67-9d762de7421c.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Previous and subsequent cells are used as context for completion in a Jupyter notebook" +} diff --git a/packages/amazonq/test/unit/codewhisperer/util/editorContext.test.ts b/packages/amazonq/test/unit/codewhisperer/util/editorContext.test.ts index d5085e4db0c..f8265a4fa86 100644 --- a/packages/amazonq/test/unit/codewhisperer/util/editorContext.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/util/editorContext.test.ts @@ -6,6 +6,7 @@ import assert from 'assert' import * as codewhispererClient from 'aws-core-vscode/codewhisperer' import * as EditorContext from 'aws-core-vscode/codewhisperer' import { + createMockDocument, createMockTextEditor, createMockClientRequest, resetCodeWhispererGlobalVariables, @@ -15,6 +16,27 @@ import { } from 'aws-core-vscode/test' import { globals } from 'aws-core-vscode/shared' import { GenerateCompletionsRequest } from 'aws-core-vscode/codewhisperer' +import * as vscode from 'vscode' + +export function createNotebookCell( + document: vscode.TextDocument = createMockDocument('def example():\n return "test"'), + kind: vscode.NotebookCellKind = vscode.NotebookCellKind.Code, + notebook: vscode.NotebookDocument = {} as any, + index: number = 0, + outputs: vscode.NotebookCellOutput[] = [], + metadata: { readonly [key: string]: any } = {}, + executionSummary?: vscode.NotebookCellExecutionSummary +): vscode.NotebookCell { + return { + document, + kind, + notebook, + index, + outputs, + metadata, + executionSummary, + } +} describe('editorContext', function () { let telemetryEnabledDefault: boolean @@ -63,6 +85,44 @@ describe('editorContext', function () { } assert.deepStrictEqual(actual, expected) }) + + it('in a notebook, includes context from other cells', async function () { + const cells: vscode.NotebookCellData[] = [ + new vscode.NotebookCellData(vscode.NotebookCellKind.Markup, 'Previous cell', 'python'), + new vscode.NotebookCellData( + vscode.NotebookCellKind.Code, + 'import numpy as np\nimport pandas as pd\n\ndef analyze_data(df):\n # Current cell with cursor here', + 'python' + ), + new vscode.NotebookCellData( + vscode.NotebookCellKind.Code, + '# Process the data\nresult = analyze_data(df)\nprint(result)', + 'python' + ), + ] + + const document = await vscode.workspace.openNotebookDocument( + 'jupyter-notebook', + new vscode.NotebookData(cells) + ) + const editor: any = { + document: document.cellAt(1).document, + selection: { active: new vscode.Position(4, 13) }, + } + + const actual = EditorContext.extractContextForCodeWhisperer(editor) + const expected: codewhispererClient.FileContext = { + filename: 'Untitled-1.py', + programmingLanguage: { + languageName: 'python', + }, + leftFileContent: + '# Previous cell\nimport numpy as np\nimport pandas as pd\n\ndef analyze_data(df):\n # Current', + rightFileContent: + ' cell with cursor here\n# Process the data\nresult = analyze_data(df)\nprint(result)\n', + } + assert.deepStrictEqual(actual, expected) + }) }) describe('getFileName', function () { @@ -115,6 +175,165 @@ describe('editorContext', function () { }) }) + describe('getNotebookCellContext', function () { + it('Should return cell text for python code cells when language is python', function () { + const mockCodeCell = createNotebookCell(createMockDocument('def example():\n return "test"')) + const result = EditorContext.getNotebookCellContext(mockCodeCell, 'python') + assert.strictEqual(result, 'def example():\n return "test"') + }) + + it('Should return java comments for python code cells when language is java', function () { + const mockCodeCell = createNotebookCell(createMockDocument('def example():\n return "test"')) + const result = EditorContext.getNotebookCellContext(mockCodeCell, 'java') + assert.strictEqual(result, '// def example():\n// return "test"') + }) + + it('Should return python comments for java code cells when language is python', function () { + const mockCodeCell = createNotebookCell(createMockDocument('println(1 + 1);', 'somefile.ipynb', 'java')) + const result = EditorContext.getNotebookCellContext(mockCodeCell, 'python') + assert.strictEqual(result, '# println(1 + 1);') + }) + + it('Should add python comment prefixes for markdown cells when language is python', function () { + const mockMarkdownCell = createNotebookCell( + createMockDocument('# Heading\nThis is a markdown cell'), + vscode.NotebookCellKind.Markup + ) + const result = EditorContext.getNotebookCellContext(mockMarkdownCell, 'python') + assert.strictEqual(result, '# # Heading\n# This is a markdown cell') + }) + + it('Should add java comment prefixes for markdown cells when language is java', function () { + const mockMarkdownCell = createNotebookCell( + createMockDocument('# Heading\nThis is a markdown cell'), + vscode.NotebookCellKind.Markup + ) + const result = EditorContext.getNotebookCellContext(mockMarkdownCell, 'java') + assert.strictEqual(result, '// # Heading\n// This is a markdown cell') + }) + }) + + describe('getNotebookCellsSliceContext', function () { + it('Should extract content from cells in reverse order up to maxLength from prefix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('First cell content')), + createNotebookCell(createMockDocument('Second cell content')), + createNotebookCell(createMockDocument('Third cell content')), + ] + + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', false) + assert.strictEqual(result, 'First cell content\nSecond cell content\nThird cell content\n') + }) + + it('Should extract content from cells in reverse order up to maxLength from suffix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('First cell content')), + createNotebookCell(createMockDocument('Second cell content')), + createNotebookCell(createMockDocument('Third cell content')), + ] + + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', true) + assert.strictEqual(result, 'First cell content\nSecond cell content\nThird cell content\n') + }) + + it('Should respect maxLength parameter from prefix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('First')), + createNotebookCell(createMockDocument('Second')), + createNotebookCell(createMockDocument('Third')), + createNotebookCell(createMockDocument('Fourth')), + ] + // Should only include part of second cell and the last two cells + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 15, 'python', false) + assert.strictEqual(result, 'd\nThird\nFourth\n') + }) + + it('Should respect maxLength parameter from suffix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('First')), + createNotebookCell(createMockDocument('Second')), + createNotebookCell(createMockDocument('Third')), + createNotebookCell(createMockDocument('Fourth')), + ] + + // Should only include first cell and part of second cell + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 15, 'python', true) + assert.strictEqual(result, 'First\nSecond\nTh') + }) + + it('Should handle empty cells array from prefix cells', function () { + const result = EditorContext.getNotebookCellsSliceContext([], 100, 'python', false) + assert.strictEqual(result, '') + }) + + it('Should handle empty cells array from suffix cells', function () { + const result = EditorContext.getNotebookCellsSliceContext([], 100, 'python', true) + assert.strictEqual(result, '') + }) + + it('Should add python comments to markdown prefix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('# Heading\nThis is markdown'), vscode.NotebookCellKind.Markup), + createNotebookCell(createMockDocument('def example():\n return "test"')), + ] + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', false) + assert.strictEqual(result, '# # Heading\n# This is markdown\ndef example():\n return "test"\n') + }) + + it('Should add python comments to markdown suffix cells', function () { + const mockCells = [ + createNotebookCell(createMockDocument('# Heading\nThis is markdown'), vscode.NotebookCellKind.Markup), + createNotebookCell(createMockDocument('def example():\n return "test"')), + ] + + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', true) + assert.strictEqual(result, '# # Heading\n# This is markdown\ndef example():\n return "test"\n') + }) + + it('Should add java comments to markdown and python prefix cells when language is java', function () { + const mockCells = [ + createNotebookCell(createMockDocument('# Heading\nThis is markdown'), vscode.NotebookCellKind.Markup), + createNotebookCell(createMockDocument('def example():\n return "test"')), + ] + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'java', false) + assert.strictEqual(result, '// # Heading\n// This is markdown\n// def example():\n// return "test"\n') + }) + + it('Should add java comments to markdown and python suffix cells when language is java', function () { + const mockCells = [ + createNotebookCell(createMockDocument('# Heading\nThis is markdown'), vscode.NotebookCellKind.Markup), + createNotebookCell(createMockDocument('println(1 + 1);', 'somefile.ipynb', 'java')), + ] + + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'java', true) + assert.strictEqual(result, '// # Heading\n// This is markdown\nprintln(1 + 1);\n') + }) + + it('Should handle code prefix cells with different languages', function () { + const mockCells = [ + createNotebookCell( + createMockDocument('println(1 + 1);', 'somefile.ipynb', 'java'), + vscode.NotebookCellKind.Code + ), + createNotebookCell(createMockDocument('def example():\n return "test"')), + ] + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', false) + assert.strictEqual(result, '# println(1 + 1);\ndef example():\n return "test"\n') + }) + + it('Should handle code suffix cells with different languages', function () { + const mockCells = [ + createNotebookCell( + createMockDocument('println(1 + 1);', 'somefile.ipynb', 'java'), + vscode.NotebookCellKind.Code + ), + createNotebookCell(createMockDocument('def example():\n return "test"')), + ] + const result = EditorContext.getNotebookCellsSliceContext(mockCells, 100, 'python', true) + assert.strictEqual(result, '# println(1 + 1);\ndef example():\n return "test"\n') + }) + }) + describe('validateRequest', function () { it('Should return false if request filename.length is invalid', function () { const req = createMockClientRequest() diff --git a/packages/amazonq/test/unit/codewhisperer/util/runtimeLanguageContext.test.ts b/packages/amazonq/test/unit/codewhisperer/util/runtimeLanguageContext.test.ts index 59c3771abb4..a5cc430a5a9 100644 --- a/packages/amazonq/test/unit/codewhisperer/util/runtimeLanguageContext.test.ts +++ b/packages/amazonq/test/unit/codewhisperer/util/runtimeLanguageContext.test.ts @@ -333,6 +333,40 @@ describe('runtimeLanguageContext', function () { } }) + describe('getSingleLineCommentPrefix', function () { + it('should return the correct comment prefix for supported languages', function () { + assert.strictEqual(languageContext.getSingleLineCommentPrefix('java'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('javascript'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('jsonc'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('kotlin'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('lua'), '-- ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('python'), '# ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('ruby'), '# ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('sql'), '-- ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('tf'), '# ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('typescript'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('vue'), '') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('yaml'), '# ') + }) + + it('should normalize language ID before getting comment prefix', function () { + assert.strictEqual(languageContext.getSingleLineCommentPrefix('hcl'), '# ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('javascriptreact'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('shellscript'), '# ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('typescriptreact'), '// ') + assert.strictEqual(languageContext.getSingleLineCommentPrefix('yml'), '# ') + }) + + it('should return empty string for unsupported languages', function () { + assert.strictEqual(languageContext.getSingleLineCommentPrefix('nonexistent'), '') + assert.strictEqual(languageContext.getSingleLineCommentPrefix(undefined), '') + }) + + it('should return empty string for plaintext', function () { + assert.strictEqual(languageContext.getSingleLineCommentPrefix('plaintext'), '') + }) + }) + // for now we will only jsx mapped to javascript, tsx mapped to typescript, all other language should remain the same describe('test covertCwsprRequest', function () { const leftFileContent = 'left' diff --git a/packages/core/src/codewhisperer/util/editorContext.ts b/packages/core/src/codewhisperer/util/editorContext.ts index 58301e176f6..a3f787af6c6 100644 --- a/packages/core/src/codewhisperer/util/editorContext.ts +++ b/packages/core/src/codewhisperer/util/editorContext.ts @@ -25,19 +25,125 @@ import { predictionTracker } from '../nextEditPrediction/activation' let tabSize: number = getTabSizeSetting() +function getEnclosingNotebook(editor: vscode.TextEditor): vscode.NotebookDocument | undefined { + // For notebook cells, find the existing notebook with a cell that matches the current editor. + return vscode.workspace.notebookDocuments.find( + (nb) => + nb.notebookType === 'jupyter-notebook' && nb.getCells().some((cell) => cell.document === editor.document) + ) +} + +export function getNotebookContext( + notebook: vscode.NotebookDocument, + editor: vscode.TextEditor, + languageName: string, + caretLeftFileContext: string, + caretRightFileContext: string +) { + // Expand the context for a cell inside of a noteboo with whatever text fits from the preceding and subsequent cells + const allCells = notebook.getCells() + const cellIndex = allCells.findIndex((cell) => cell.document === editor.document) + // Extract text from prior cells if there is enough room in left file context + if (caretLeftFileContext.length < CodeWhispererConstants.charactersLimit - 1) { + const leftCellsText = getNotebookCellsSliceContext( + allCells.slice(0, cellIndex), + CodeWhispererConstants.charactersLimit - (caretLeftFileContext.length + 1), + languageName, + true + ) + if (leftCellsText.length > 0) { + caretLeftFileContext = addNewlineIfMissing(leftCellsText) + caretLeftFileContext + } + } + // Extract text from subsequent cells if there is enough room in right file context + if (caretRightFileContext.length < CodeWhispererConstants.charactersLimit - 1) { + const rightCellsText = getNotebookCellsSliceContext( + allCells.slice(cellIndex + 1), + CodeWhispererConstants.charactersLimit - (caretRightFileContext.length + 1), + languageName, + false + ) + if (rightCellsText.length > 0) { + caretRightFileContext = addNewlineIfMissing(caretRightFileContext) + rightCellsText + } + } + return { caretLeftFileContext, caretRightFileContext } +} + +export function getNotebookCellContext(cell: vscode.NotebookCell, referenceLanguage?: string): string { + // Extract the text verbatim if the cell is code and the cell has the same language. + // Otherwise, add the correct comment string for the reference language + const cellText = cell.document.getText() + if ( + cell.kind === vscode.NotebookCellKind.Markup || + (runtimeLanguageContext.normalizeLanguage(cell.document.languageId) ?? cell.document.languageId) !== + referenceLanguage + ) { + const commentPrefix = runtimeLanguageContext.getSingleLineCommentPrefix(referenceLanguage) + if (commentPrefix === '') { + return cellText + } + return cell.document + .getText() + .split('\n') + .map((line) => `${commentPrefix}${line}`) + .join('\n') + } + return cellText +} + +export function getNotebookCellsSliceContext( + cells: vscode.NotebookCell[], + maxLength: number, + referenceLanguage: string, + fromStart: boolean +): string { + // Extract context from array of notebook cells that fits inside `maxLength` characters, + // from either the start or the end of the array. + let output: string[] = [] + if (!fromStart) { + cells = cells.reverse() + } + cells.some((cell) => { + const cellText = addNewlineIfMissing(getNotebookCellContext(cell, referenceLanguage)) + if (cellText.length > 0) { + if (cellText.length >= maxLength) { + if (fromStart) { + output.push(cellText.substring(0, maxLength)) + } else { + output.push(cellText.substring(cellText.length - maxLength)) + } + return true + } + output.push(cellText) + maxLength -= cellText.length + } + }) + if (!fromStart) { + output = output.reverse() + } + return output.join('') +} + +export function addNewlineIfMissing(text: string): string { + if (text.length > 0 && !text.endsWith('\n')) { + text += '\n' + } + return text +} + export function extractContextForCodeWhisperer(editor: vscode.TextEditor): codewhispererClient.FileContext { const document = editor.document const curPos = editor.selection.active const offset = document.offsetAt(curPos) - const caretLeftFileContext = editor.document.getText( + let caretLeftFileContext = editor.document.getText( new vscode.Range( document.positionAt(offset - CodeWhispererConstants.charactersLimit), document.positionAt(offset) ) ) - - const caretRightFileContext = editor.document.getText( + let caretRightFileContext = editor.document.getText( new vscode.Range( document.positionAt(offset), document.positionAt(offset + CodeWhispererConstants.charactersLimit) @@ -48,6 +154,19 @@ export function extractContextForCodeWhisperer(editor: vscode.TextEditor): codew languageName = runtimeLanguageContext.normalizeLanguage(editor.document.languageId) ?? editor.document.languageId } + if (editor.document.uri.scheme === 'vscode-notebook-cell') { + const notebook = getEnclosingNotebook(editor) + if (notebook) { + ;({ caretLeftFileContext, caretRightFileContext } = getNotebookContext( + notebook, + editor, + languageName, + caretLeftFileContext, + caretRightFileContext + )) + } + } + return { filename: getFileRelativePath(editor), programmingLanguage: { diff --git a/packages/core/src/codewhisperer/util/runtimeLanguageContext.ts b/packages/core/src/codewhisperer/util/runtimeLanguageContext.ts index 9a495cf5356..3a1403b453e 100644 --- a/packages/core/src/codewhisperer/util/runtimeLanguageContext.ts +++ b/packages/core/src/codewhisperer/util/runtimeLanguageContext.ts @@ -58,6 +58,13 @@ export class RuntimeLanguageContext { */ private supportedLanguageExtensionMap: ConstantMap + /** + * A map storing single-line comment prefixes for different languages + * Key: CodewhispererLanguage + * Value: Comment prefix string + */ + private languageSingleLineCommentPrefixMap: ConstantMap + constructor() { this.supportedLanguageMap = createConstantMap< CodeWhispererConstants.PlatformLanguageId | CodewhispererLanguage, @@ -146,6 +153,39 @@ export class RuntimeLanguageContext { psm1: 'powershell', r: 'r', }) + this.languageSingleLineCommentPrefixMap = createConstantMap({ + c: '// ', + cpp: '// ', + csharp: '// ', + dart: '// ', + go: '// ', + hcl: '# ', + java: '// ', + javascript: '// ', + json: '// ', + jsonc: '// ', + jsx: '// ', + kotlin: '// ', + lua: '-- ', + php: '// ', + plaintext: '', + powershell: '# ', + python: '# ', + r: '# ', + ruby: '# ', + rust: '// ', + scala: '// ', + shell: '# ', + sql: '-- ', + swift: '// ', + systemVerilog: '// ', + tf: '# ', + tsx: '// ', + typescript: '// ', + vue: '', // vue lacks a single-line comment prefix + yaml: '# ', + yml: '# ', + }) } /** @@ -159,6 +199,16 @@ export class RuntimeLanguageContext { return this.supportedLanguageMap.get(languageId) } + /** + * Get the comment prefix for a given language + * @param language The language to get comment prefix for + * @returns The comment prefix string, or empty string if not found + */ + public getSingleLineCommentPrefix(language?: string): string { + const normalizedLanguage = this.normalizeLanguage(language) + return normalizedLanguage ? (this.languageSingleLineCommentPrefixMap.get(normalizedLanguage) ?? '') : '' + } + /** * Normalize client side language id to service aware language id (service is not aware of jsx/tsx) * Only used when invoking CodeWhisperer service API, for client usage please use normalizeLanguage From c97740e8ea85be21a42067566cf33ed30a82708c Mon Sep 17 00:00:00 2001 From: Zoe Lin <60411978+zixlin7@users.noreply.github.com> Date: Tue, 13 May 2025 10:21:34 -0700 Subject: [PATCH 16/19] feat(amazonq): import userWrittenCode configuration for inline with lsp (#7281) ## Problem Add importAdder and userWrittenCode configuration to inline with LSP ## Solution --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- packages/amazonq/src/lsp/client.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index 4af113b13c4..0b32a6b57ae 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -333,6 +333,8 @@ function getConfigSection(section: ConfigSection) { includeSuggestionsWithCodeReferences: CodeWhispererSettings.instance.isSuggestionsWithCodeReferencesEnabled(), shareCodeWhispererContentWithAWS: !CodeWhispererSettings.instance.isOptoutEnabled(), + includeImportsWithSuggestions: CodeWhispererSettings.instance.isImportRecommendationEnabled(), + sendUserWrittenCodeMetrics: true, }, ] case 'aws.logLevel': From 143e35ced83bbe2caa96817ff0a70db7b24217fc Mon Sep 17 00:00:00 2001 From: Nikolas Komonen <118216176+nkomonen-amazon@users.noreply.github.com> Date: Tue, 13 May 2025 18:30:23 -0400 Subject: [PATCH 17/19] fix(amazonq): push customizations on startup (#7297) ## Problem At the startup of the extension, the customization that a user already decided previously was not being pushed to flare. The only time we would push the customization to flare was if the customization was changed. Otherwise everything else works as expected. ## Solution On startup, push the customization to flare (if it already exists) --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. Signed-off-by: nkomonen-amazon --- packages/amazonq/src/lsp/chat/activation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/amazonq/src/lsp/chat/activation.ts b/packages/amazonq/src/lsp/chat/activation.ts index 9dd1d31c3de..3a36377b9b5 100644 --- a/packages/amazonq/src/lsp/chat/activation.ts +++ b/packages/amazonq/src/lsp/chat/activation.ts @@ -25,6 +25,11 @@ export async function activate(languageClient: LanguageClient, encryptionKey: Bu type: 'profile', profileArn: AuthUtil.instance.regionProfileManager.activeRegionProfile?.arn, }) + // We need to push the cached customization on startup explicitly + await pushConfigUpdate(languageClient, { + type: 'customization', + customization: getSelectedCustomization(), + }) const provider = new AmazonQChatViewProvider(mynahUIPath) From 3f5fa1783297d5cd13b25b1243ec65dd5142664b Mon Sep 17 00:00:00 2001 From: chungjac Date: Tue, 13 May 2025 17:05:25 -0700 Subject: [PATCH 18/19] deps: bump @aws-toolkits/telemetry to 1.0.319 (#7300) ## Problem - Added new metrics in aws-toolkit-common package: https://github.com/aws/aws-toolkit-common/pull/1024 ## Solution - Consume latest version of aws-toolkit-common package --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index e5f1e7e7a70..f2e583508b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "vscode-nls-dev": "^4.0.4" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.318", + "@aws-toolkits/telemetry": "^1.0.319", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", @@ -10760,10 +10760,11 @@ } }, "node_modules/@aws-toolkits/telemetry": { - "version": "1.0.318", - "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.318.tgz", - "integrity": "sha512-L64GJ+KRN0fdTIx1CPIbbgBeFcg9DilsIxfjeZyod7ld0mw6he70rPopBtK4jP+pTEkfUE4wTRsaco1nWXz3+w==", + "version": "1.0.319", + "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-1.0.319.tgz", + "integrity": "sha512-NMydYKj2evnYGQuVFoR1pHkyjimu/f5NYiMT4BJBUaKWsaUyxuFoYs497PXtg4ZlJx/sxj11rLLgjZR/ciIVQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "ajv": "^6.12.6", "cross-spawn": "^7.0.6", diff --git a/package.json b/package.json index f4b31c22d83..493327237eb 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "skippedTestReport": "ts-node ./scripts/skippedTestReport.ts ./packages/amazonq/test/e2e/" }, "devDependencies": { - "@aws-toolkits/telemetry": "^1.0.318", + "@aws-toolkits/telemetry": "^1.0.319", "@playwright/browser-chromium": "^1.43.1", "@stylistic/eslint-plugin": "^2.11.0", "@types/he": "^1.2.3", From 6081f890bdbb91fcd8b60c4cc0abb65b15d4a38d Mon Sep 17 00:00:00 2001 From: Lei Gao <97199248+leigaol@users.noreply.github.com> Date: Tue, 13 May 2025 18:22:39 -0700 Subject: [PATCH 19/19] fix(amazonq):support chat in al2 aarch64 and CDM (#7270) ## Problem LSP cannot start without GLIBC>=2.28 in AL2 aarch64 and CloudDevMachine ## Solution --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --- ...-bb976b5f-7697-42d8-89a9-8e96310a23f4.json | 4 ++++ packages/amazonq/src/extension.ts | 4 ++-- packages/amazonq/src/lsp/client.ts | 19 ++++++++----------- .../core/src/amazonq/lsp/lspController.ts | 4 ++-- packages/core/src/shared/index.ts | 2 +- packages/core/src/shared/telemetry/util.ts | 4 ++-- packages/core/src/shared/vscode/env.ts | 14 ++++++-------- .../core/src/test/shared/vscode/env.test.ts | 17 +++++++---------- 8 files changed, 32 insertions(+), 36 deletions(-) create mode 100644 packages/amazonq/.changes/next-release/Bug Fix-bb976b5f-7697-42d8-89a9-8e96310a23f4.json diff --git a/packages/amazonq/.changes/next-release/Bug Fix-bb976b5f-7697-42d8-89a9-8e96310a23f4.json b/packages/amazonq/.changes/next-release/Bug Fix-bb976b5f-7697-42d8-89a9-8e96310a23f4.json new file mode 100644 index 00000000000..988fb2bcc7b --- /dev/null +++ b/packages/amazonq/.changes/next-release/Bug Fix-bb976b5f-7697-42d8-89a9-8e96310a23f4.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "Support chat in AL2 aarch64" +} diff --git a/packages/amazonq/src/extension.ts b/packages/amazonq/src/extension.ts index 5ae9e397119..45641b37440 100644 --- a/packages/amazonq/src/extension.ts +++ b/packages/amazonq/src/extension.ts @@ -33,7 +33,7 @@ import { maybeShowMinVscodeWarning, Experiments, isSageMaker, - isAmazonInternalOs, + isAmazonLinux2, } from 'aws-core-vscode/shared' import { ExtStartUpSources } from 'aws-core-vscode/telemetry' import { VSCODE_EXTENSION_ID } from 'aws-core-vscode/utils' @@ -123,7 +123,7 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is await activateCodeWhisperer(extContext as ExtContext) if ( (Experiments.instance.get('amazonqLSP', true) || Auth.instance.isInternalAmazonUser()) && - (!isAmazonInternalOs() || (await hasGlibcPatch())) + (!isAmazonLinux2() || hasGlibcPatch()) ) { // start the Amazon Q LSP for internal users first // for AL2, start LSP if glibc patch is found diff --git a/packages/amazonq/src/lsp/client.ts b/packages/amazonq/src/lsp/client.ts index 0b32a6b57ae..5559afb9f1d 100644 --- a/packages/amazonq/src/lsp/client.ts +++ b/packages/amazonq/src/lsp/client.ts @@ -31,8 +31,7 @@ import { getLogger, undefinedIfEmpty, getOptOutPreference, - isAmazonInternalOs, - fs, + isAmazonLinux2, getClientId, extensionVersion, } from 'aws-core-vscode/shared' @@ -45,8 +44,11 @@ import { telemetry } from 'aws-core-vscode/telemetry' const localize = nls.loadMessageBundle() const logger = getLogger('amazonqLsp.lspClient') -export async function hasGlibcPatch(): Promise { - return await fs.exists('/opt/vsc-sysroot/lib64/ld-linux-x86-64.so.2') +export const glibcLinker: string = process.env.VSCODE_SERVER_CUSTOM_GLIBC_LINKER || '' +export const glibcPath: string = process.env.VSCODE_SERVER_CUSTOM_GLIBC_PATH || '' + +export function hasGlibcPatch(): boolean { + return glibcLinker.length > 0 && glibcPath.length > 0 } export async function startLanguageServer( @@ -71,13 +73,8 @@ export async function startLanguageServer( const traceServerEnabled = Settings.instance.isSet(`${clientId}.trace.server`) let executable: string[] = [] // apply the GLIBC 2.28 path to node js runtime binary - if (isAmazonInternalOs() && (await hasGlibcPatch())) { - executable = [ - '/opt/vsc-sysroot/lib64/ld-linux-x86-64.so.2', - '--library-path', - '/opt/vsc-sysroot/lib64', - resourcePaths.node, - ] + if (isAmazonLinux2() && hasGlibcPatch()) { + executable = [glibcLinker, '--library-path', glibcPath, resourcePaths.node] getLogger('amazonqLsp').info(`Patched node runtime with GLIBC to ${executable}`) } else { executable = [resourcePaths.node] diff --git a/packages/core/src/amazonq/lsp/lspController.ts b/packages/core/src/amazonq/lsp/lspController.ts index 3b7bd98a61d..5a1b84b7c49 100644 --- a/packages/core/src/amazonq/lsp/lspController.ts +++ b/packages/core/src/amazonq/lsp/lspController.ts @@ -11,7 +11,7 @@ import { activate as activateLsp, LspClient } from './lspClient' import { telemetry } from '../../shared/telemetry/telemetry' import { isCloud9 } from '../../shared/extensionUtilities' import globals, { isWeb } from '../../shared/extensionGlobals' -import { isAmazonInternalOs } from '../../shared/vscode/env' +import { isAmazonLinux2 } from '../../shared/vscode/env' import { WorkspaceLspInstaller } from './workspaceInstaller' import { lspSetupStage } from '../../shared/lsp/utils/setupStage' import { RelevantTextDocumentAddition } from '../../codewhispererChat/controllers/chat/model' @@ -165,7 +165,7 @@ export class LspController { } async trySetupLsp(context: vscode.ExtensionContext, buildIndexConfig: BuildIndexConfig) { - if (isCloud9() || isWeb() || isAmazonInternalOs()) { + if (isCloud9() || isWeb() || isAmazonLinux2()) { this.logger.warn('Skipping LSP setup. LSP is not compatible with the current environment. ') // do not do anything if in Cloud9 or Web mode or in AL2 (AL2 does not support node v18+) return diff --git a/packages/core/src/shared/index.ts b/packages/core/src/shared/index.ts index 4cda5285f69..f4c78e2093c 100644 --- a/packages/core/src/shared/index.ts +++ b/packages/core/src/shared/index.ts @@ -18,7 +18,7 @@ export * from './extensionUtilities' export * from './extensionStartup' export { RegionProvider } from './regions/regionProvider' export { Commands } from './vscode/commands2' -export { getMachineId, getServiceEnvVarConfig, isAmazonInternalOs } from './vscode/env' +export { getMachineId, getServiceEnvVarConfig, isAmazonLinux2 } from './vscode/env' export { getLogger } from './logger/logger' export { activateExtension, openUrl } from './utilities/vsCodeUtils' export { waitUntil, sleep, Timeout } from './utilities/timeoutUtils' diff --git a/packages/core/src/shared/telemetry/util.ts b/packages/core/src/shared/telemetry/util.ts index 4d136bc96f0..310c36b82d6 100644 --- a/packages/core/src/shared/telemetry/util.ts +++ b/packages/core/src/shared/telemetry/util.ts @@ -15,7 +15,7 @@ import { isAutomation, isRemoteWorkspace, isCloudDesktop, - isAmazonInternalOs, + isAmazonLinux2, } from '../vscode/env' import { addTypeName } from '../utilities/typeConstructors' import globals, { isWeb } from '../extensionGlobals' @@ -290,7 +290,7 @@ export async function getComputeEnvType(): Promise { } else if (isSageMaker()) { return web ? 'sagemaker-web' : 'sagemaker' } else if (isRemoteWorkspace()) { - if (isAmazonInternalOs()) { + if (isAmazonLinux2()) { if (await isCloudDesktop()) { return 'cloudDesktop-amzn' } diff --git a/packages/core/src/shared/vscode/env.ts b/packages/core/src/shared/vscode/env.ts index 004db0efc27..02d46ae6695 100644 --- a/packages/core/src/shared/vscode/env.ts +++ b/packages/core/src/shared/vscode/env.ts @@ -125,23 +125,21 @@ export function isRemoteWorkspace(): boolean { } /** - * There is Amazon Linux 2, but additionally an Amazon Linux 2 Internal. - * The internal version is for Amazon employees only. And this version can - * be used by either EC2 OR CloudDesktop. It is not exclusive to either. + * There is Amazon Linux 2. * - * Use {@link isCloudDesktop()} to know if we are specifically using it. + * Use {@link isCloudDesktop()} to know if we are specifically using internal Amazon Linux 2. * - * Example: `5.10.220-188.869.amzn2int.x86_64` + * Example: `5.10.220-188.869.amzn2int.x86_64` or `5.10.236-227.928.amzn2.x86_64` (Cloud Dev Machine) */ -export function isAmazonInternalOs() { - return os.release().includes('amzn2int') && process.platform === 'linux' +export function isAmazonLinux2() { + return (os.release().includes('.amzn2int.') || os.release().includes('.amzn2.')) && process.platform === 'linux' } /** * Returns true if we are in an internal Amazon Cloud Desktop */ export async function isCloudDesktop() { - if (!isAmazonInternalOs()) { + if (!isAmazonLinux2()) { return false } diff --git a/packages/core/src/test/shared/vscode/env.test.ts b/packages/core/src/test/shared/vscode/env.test.ts index ef81bdf05ab..cf09d085e68 100644 --- a/packages/core/src/test/shared/vscode/env.test.ts +++ b/packages/core/src/test/shared/vscode/env.test.ts @@ -5,13 +5,7 @@ import assert from 'assert' import path from 'path' -import { - isCloudDesktop, - getEnvVars, - getServiceEnvVarConfig, - isAmazonInternalOs as isAmazonInternalOS, - isBeta, -} from '../../../shared/vscode/env' +import { isCloudDesktop, getEnvVars, getServiceEnvVarConfig, isAmazonLinux2, isBeta } from '../../../shared/vscode/env' import { ChildProcess } from '../../../shared/utilities/processUtils' import * as sinon from 'sinon' import os from 'os' @@ -103,13 +97,16 @@ describe('env', function () { assert.strictEqual(isBeta(), expected) }) - it('isAmazonInternalOS', function () { + it('isAmazonLinux2', function () { sandbox.stub(process, 'platform').value('linux') const versionStub = stubOsVersion('5.10.220-188.869.amzn2int.x86_64') - assert.strictEqual(isAmazonInternalOS(), true) + assert.strictEqual(isAmazonLinux2(), true) + + versionStub.returns('5.10.236-227.928.amzn2.x86_64') + assert.strictEqual(isAmazonLinux2(), true) versionStub.returns('5.10.220-188.869.NOT_INTERNAL.x86_64') - assert.strictEqual(isAmazonInternalOS(), false) + assert.strictEqual(isAmazonLinux2(), false) }) it('isCloudDesktop', async function () {