From 22fbd166ea1e60206b1b2fb7b8bff5a2e93707da Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Tue, 1 Apr 2025 14:58:30 -0700 Subject: [PATCH 1/7] formatting the stderr --- packages/core/src/codewhispererChat/tools/executeBash.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/codewhispererChat/tools/executeBash.ts b/packages/core/src/codewhispererChat/tools/executeBash.ts index 73aa52e3762..8c42d1dd205 100644 --- a/packages/core/src/codewhispererChat/tools/executeBash.ts +++ b/packages/core/src/codewhispererChat/tools/executeBash.ts @@ -75,6 +75,7 @@ export class ExecuteBash { const stderrBuffer: string[] = [] let firstChunk = true + let firstStderrChunk = true const childProcessOptions: ChildProcessOptions = { spawnOptions: { cwd: this.workingDirectory, @@ -87,7 +88,8 @@ export class ExecuteBash { firstChunk = false }, onStderr: (chunk: string) => { - ExecuteBash.handleChunk(chunk, stderrBuffer, updates) + ExecuteBash.handleChunk(firstStderrChunk ? '```console\n' + chunk : chunk, stderrBuffer, updates) + firstStderrChunk = false }, } From 68a18b44b8af7f9be19f2615c3d02c31a9776214 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Thu, 3 Apr 2025 17:17:27 -0700 Subject: [PATCH 2/7] fix the no spinner for writig a file & change the UI on console & update mynahUI version --- packages/core/package.json | 2 +- .../codewhispererChat/controllers/chat/messenger/messenger.ts | 4 ++++ packages/core/src/codewhispererChat/tools/executeBash.ts | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 7d64a740305..12d5154bfb0 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -522,7 +522,7 @@ "@aws-sdk/s3-request-presigner": "<3.731.0", "@aws-sdk/smithy-client": "<3.731.0", "@aws-sdk/util-arn-parser": "<3.731.0", - "@aws/mynah-ui": "^4.26.1", + "@aws/mynah-ui": "^4.28.0", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^5.0.1", diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index d19e88c0b47..ba878a6582e 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -235,6 +235,10 @@ export class Messenger { } else { // TODO: Handle the error } + } else if (cwChatEvent.toolUseEvent?.stop === undefined) { + if (toolUseInput !== '') { + this.sendInitalStream(tabID, triggerID, undefined) + } } if ( diff --git a/packages/core/src/codewhispererChat/tools/executeBash.ts b/packages/core/src/codewhispererChat/tools/executeBash.ts index 8c42d1dd205..d4d28bedca0 100644 --- a/packages/core/src/codewhispererChat/tools/executeBash.ts +++ b/packages/core/src/codewhispererChat/tools/executeBash.ts @@ -208,7 +208,7 @@ export class ExecuteBash { public queueDescription(updates: Writable): void { updates.write(`I will run the following shell command:\n`) - updates.write('```bash\n' + this.command + '\n```') + updates.write('```shell\n' + this.command + '\n```') updates.end() } } From ce978c6550b4ff9c1c877d565925e00cd6fa9810 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Thu, 3 Apr 2025 19:43:27 -0700 Subject: [PATCH 3/7] add lock file --- package-lock.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4fd4035f62d..36d993de7b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11966,10 +11966,11 @@ } }, "node_modules/@aws/mynah-ui": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.26.1.tgz", - "integrity": "sha512-qUgQ6NVmiCSp6qF43cM6522U8QtBTBbqDv5yKS/5tl9cEQuZJSfKDq2zFUstQNZmsw0GE8p/NboTDo3mRv4sSQ==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/@aws/mynah-ui/-/mynah-ui-4.28.0.tgz", + "integrity": "sha512-HKL65KBOMap7ZZrQs/Ol08zfj48A7paPWzm/vNsAYeL/dE25EmXYkkS3YIZSveaYF0ltYUt7hzyQnNWl/18KKA==", "hasInstallScript": true, + "license": "Apache License 2.0", "dependencies": { "escape-html": "^1.0.3", "highlight.js": "^11.11.0", @@ -26744,7 +26745,7 @@ "@aws-sdk/s3-request-presigner": "<3.731.0", "@aws-sdk/smithy-client": "<3.731.0", "@aws-sdk/util-arn-parser": "<3.731.0", - "@aws/mynah-ui": "^4.26.1", + "@aws/mynah-ui": "^4.28.0", "@gerhobbelt/gitignore-parser": "^0.2.0-9", "@iarna/toml": "^2.2.5", "@smithy/fetch-http-handler": "^5.0.1", From 799a84e1790c1bf7358ac8c03cf97280ff5cfc99 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Thu, 3 Apr 2025 22:33:39 -0700 Subject: [PATCH 4/7] adress comment --- .../controllers/chat/messenger/messenger.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index 45f502329b3..71d086c0a89 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -262,10 +262,8 @@ export class Messenger { } else { // TODO: Handle the error } - } else if (cwChatEvent.toolUseEvent?.stop === undefined) { - if (toolUseInput !== '') { - this.sendInitalStream(tabID, triggerID, undefined) - } + } else if (cwChatEvent.toolUseEvent?.stop === undefined && toolUseInput !== '') { + this.sendInitalStream(tabID, triggerID, undefined) } if ( From cc2fa97c811f71f67ae61a09d46b7a12d6f70030 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Fri, 4 Apr 2025 12:14:53 -0700 Subject: [PATCH 5/7] add comment for the fix --- .../codewhispererChat/controllers/chat/messenger/messenger.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index 71d086c0a89..ceca2650534 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -263,6 +263,7 @@ export class Messenger { // TODO: Handle the error } } else if (cwChatEvent.toolUseEvent?.stop === undefined && toolUseInput !== '') { + // This is for the case when writing tool is executed. The toolUseEvent is non stop but in toolUseInput is not empty. In this case we need show user the current spinner UI. this.sendInitalStream(tabID, triggerID, undefined) } From 583174552397178bfb0a5279841b0af03e958f74 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Fri, 4 Apr 2025 15:03:53 -0700 Subject: [PATCH 6/7] fix the duplication --- .../chat/controller/messenger/messenger.ts | 24 ++++++-------- .../controllers/chat/messenger/messenger.ts | 24 ++++++-------- .../core/src/shared/utilities/messageUtil.ts | 31 +++++++++++++++++++ 3 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 packages/core/src/shared/utilities/messageUtil.ts diff --git a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts index 5541ef389c5..433d0d8b280 100644 --- a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts @@ -39,6 +39,7 @@ import { keys } from '../../../../shared/utilities/tsUtils' import { cancellingProgressField, testGenCompletedField } from '../../../models/constants' import { testGenState } from '../../../../codewhisperer/models/model' import { TelemetryHelper } from '../../../../codewhisperer/util/telemetryHelper' +import { extractErrorInfo } from '../../../../shared/utilities/messageUtil' export type UnrecoverableErrorType = 'no-project-found' | 'no-open-file-found' | 'invalid-file-type' @@ -249,26 +250,19 @@ export class Messenger { { timeout: 60000, truthy: true } ) .catch((error: any) => { - let errorMessage = 'Error reading chat stream.' - let statusCode = undefined - let requestID = undefined - if (error instanceof CodeWhispererStreamingServiceException) { - errorMessage = error.message - statusCode = getHttpStatusCode(error) ?? 0 - requestID = getRequestId(error) - } + const errorInfo = extractErrorInfo(error) let message = 'This error is reported to the team automatically. Please try sending your message again.' - if (errorMessage !== undefined) { - message += `\n\nDetails: ${errorMessage}` + if (errorInfo.errorMessage !== undefined) { + message += `\n\nDetails: ${errorInfo.errorMessage}` } - if (statusCode !== undefined) { - message += `\n\nStatus Code: ${statusCode}` + if (errorInfo.statusCode !== undefined) { + message += `\n\nStatus Code: ${errorInfo.statusCode}` } - if (requestID !== undefined) { - messageId = requestID - message += `\n\nRequest ID: ${requestID}` + if (errorInfo.requestId !== undefined) { + messageId = errorInfo.requestId + message += `\n\nRequest ID: ${errorInfo.requestId}` } this.sendMessage(message.trim(), tabID, 'answer') }) diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index ceca2650534..b035dbf6dcf 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -47,6 +47,7 @@ import { ChatStream } from '../../../tools/chatStream' import { getWorkspaceForFile } from '../../../../shared/utilities/workspaceUtils' import path from 'path' import { CommandValidation } from '../../../tools/executeBash' +import { extractErrorInfo } from '../../../../shared/utilities/messageUtil' export type StaticTextResponseType = 'quick-action-help' | 'onboarding-help' | 'transform' | 'help' @@ -326,26 +327,21 @@ export class Messenger { { timeout: 60000, truthy: true } ) .catch((error: any) => { - let errorMessage = 'Error reading chat stream.' - let statusCode = undefined - let requestID = undefined - - if (error instanceof CodeWhispererStreamingServiceException) { - errorMessage = error.message - statusCode = getHttpStatusCode(error) ?? 0 - requestID = getRequestId(error) - } - + const errorInfo = extractErrorInfo(error) this.showChatExceptionMessage( - { errorMessage, statusCode: statusCode?.toString(), sessionID: undefined }, + { + errorMessage: errorInfo.errorMessage, + statusCode: errorInfo.statusCode?.toString(), + sessionID: undefined, + }, tabID, - requestID + errorInfo.requestId ) - getLogger().error(`error: ${errorMessage} tabID: ${tabID} requestID: ${requestID}`) + getLogger().error(`error: ${errorInfo.errorMessage} tabID: ${tabID} requestID: ${errorInfo.requestId}`) followUps = [] relatedSuggestions = [] - this.telemetryHelper.recordMessageResponseError(triggerPayload, tabID, statusCode ?? 0) + this.telemetryHelper.recordMessageResponseError(triggerPayload, tabID, errorInfo.statusCode ?? 0) }) .finally(async () => { if ( diff --git a/packages/core/src/shared/utilities/messageUtil.ts b/packages/core/src/shared/utilities/messageUtil.ts new file mode 100644 index 00000000000..f2cefe824de --- /dev/null +++ b/packages/core/src/shared/utilities/messageUtil.ts @@ -0,0 +1,31 @@ +/*! + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { CodeWhispererStreamingServiceException } from '@amzn/codewhisperer-streaming' +import { getHttpStatusCode, getRequestId } from '../errors' + +export interface MessageErrorInfo { + errorMessage: string + statusCode?: number + requestId?: string +} + +export function extractErrorInfo(error: any): MessageErrorInfo { + let errorMessage = 'Error reading chat stream.' + let statusCode = undefined + let requestId = undefined + + if (error instanceof CodeWhispererStreamingServiceException) { + errorMessage = error.message + statusCode = getHttpStatusCode(error) ?? 0 + requestId = getRequestId(error) + } + + return { + errorMessage, + statusCode, + requestId, + } +} From 06864a9c9339a33dd9831823effa13298f238909 Mon Sep 17 00:00:00 2001 From: Randall-Jiang Date: Fri, 4 Apr 2025 17:18:21 -0700 Subject: [PATCH 7/7] fix linter --- package-lock.json | 55 ++++++++++++------- package.json | 2 +- .../chat/controller/messenger/messenger.ts | 7 +-- .../controllers/chat/messenger/messenger.ts | 3 +- 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/package-lock.json b/package-lock.json index 191fc6203ad..5ece1a81273 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "husky": "^9.0.7", "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", - "pretty-quick": "^4.0.0", + "pretty-quick": "^4.1.1", "ts-node": "^10.9.1", "typescript": "^5.0.4", "webpack": "^5.95.0", @@ -22512,7 +22512,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { @@ -22849,17 +22851,19 @@ } }, "node_modules/pretty-quick": { - "version": "4.0.0", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-4.1.1.tgz", + "integrity": "sha512-9Ud0l/CspNTmyIdYac9X7Inb3o8fuUsw+1zJFvCGn+at0t1UwUcUdo2RSZ41gcmfLv1fxgWQxWEfItR7CBwugg==", "dev": true, "license": "MIT", "dependencies": { - "execa": "^5.1.1", "find-up": "^5.0.0", - "ignore": "^5.3.0", + "ignore": "^7.0.3", "mri": "^1.2.0", - "picocolors": "^1.0.0", - "picomatch": "^3.0.1", - "tslib": "^2.6.2" + "picocolors": "^1.1.1", + "picomatch": "^4.0.2", + "tinyexec": "^0.3.2", + "tslib": "^2.8.1" }, "bin": { "pretty-quick": "lib/cli.mjs" @@ -22871,12 +22875,24 @@ "prettier": "^3.0.0" } }, + "node_modules/pretty-quick/node_modules/ignore": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/pretty-quick/node_modules/picomatch": { - "version": "3.0.1", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -24915,6 +24931,13 @@ "next-tick": "1" } }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.2.1", "dev": true, @@ -25061,7 +25084,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, "node_modules/tsscmp": { @@ -30278,10 +30303,6 @@ "tree-kill": "cli.js" } }, - "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/tslib": { - "version": "2.8.1", - "license": "0BSD" - }, "src.gen/@amzn/amazon-q-developer-streaming-client/node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -31845,10 +31866,6 @@ "tree-kill": "cli.js" } }, - "src.gen/@amzn/codewhisperer-streaming/node_modules/tslib": { - "version": "2.8.1", - "license": "0BSD" - }, "src.gen/@amzn/codewhisperer-streaming/node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", diff --git a/package.json b/package.json index d33ff4f4f51..0719860c2b0 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "husky": "^9.0.7", "prettier": "^3.3.3", "prettier-plugin-sh": "^0.14.0", - "pretty-quick": "^4.0.0", + "pretty-quick": "^4.1.1", "ts-node": "^10.9.1", "typescript": "^5.0.4", "webpack": "^5.95.0", diff --git a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts index 433d0d8b280..c5359a2bfb8 100644 --- a/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts +++ b/packages/core/src/amazonqTest/chat/controller/messenger/messenger.ts @@ -27,13 +27,10 @@ import { ChatItemType } from '../../../../amazonq/commons/model' import { ChatItemAction, ChatItemButton, ProgressField } from '@aws/mynah-ui' import * as CodeWhispererConstants from '../../../../codewhisperer/models/constants' import { TriggerPayload } from '../../../../codewhispererChat/controllers/chat/model' -import { - CodeWhispererStreamingServiceException, - GenerateAssistantResponseCommandOutput, -} from '@amzn/codewhisperer-streaming' +import { GenerateAssistantResponseCommandOutput } from '@amzn/codewhisperer-streaming' import { Session } from '../../session/session' import { CodeReference } from '../../../../amazonq/webview/ui/apps/amazonqCommonsConnector' -import { getHttpStatusCode, getRequestId, getTelemetryReasonDesc, ToolkitError } from '../../../../shared/errors' +import { getTelemetryReasonDesc, ToolkitError } from '../../../../shared/errors' import { sleep, waitUntil } from '../../../../shared/utilities/timeoutUtils' import { keys } from '../../../../shared/utilities/tsUtils' import { cancellingProgressField, testGenCompletedField } from '../../../models/constants' diff --git a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts index b035dbf6dcf..e993bd49ca0 100644 --- a/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts +++ b/packages/core/src/codewhispererChat/controllers/chat/messenger/messenger.ts @@ -20,7 +20,6 @@ import { EditorContextCommandType } from '../../../commands/registerCommands' import { ChatResponseStream as qdevChatResponseStream } from '@amzn/amazon-q-developer-streaming-client' import { ChatResponseStream as cwChatResponseStream, - CodeWhispererStreamingServiceException, SupplementaryWebLink, ToolUse, } from '@amzn/codewhisperer-streaming' @@ -29,7 +28,7 @@ import { ChatSession } from '../../../clients/chat/v0/chat' import { ChatException } from './model' import { CWCTelemetryHelper } from '../telemetryHelper' import { ChatPromptCommandType, DocumentReference, TriggerPayload } from '../model' -import { getHttpStatusCode, getRequestId, ToolkitError } from '../../../../shared/errors' +import { ToolkitError } from '../../../../shared/errors' import { keys } from '../../../../shared/utilities/tsUtils' import { getLogger } from '../../../../shared/logger/logger' import { FeatureAuthState } from '../../../../codewhisperer/util/authUtil'