Skip to content

Commit be976e1

Browse files
aws-toolkit-automationnkomonen-amazonHweinstock
authored
Merge master into feature/hybridChat (#7166)
## Automatic merge failed - Resolve conflicts and push to this PR branch. - **Do not squash-merge** this PR. Use the "Create a merge commit" option to do a regular merge. ## Command line hint To perform the merge from the command line, you could do something like the following (where "origin" is the name of the remote in your local git repo): ``` git stash git fetch --all git checkout origin/feature/hybridChat git merge origin/master git commit git push origin HEAD:refs/heads/autoMerge/feature/hybridChat ``` --------- Signed-off-by: nkomonen-amazon <nkomonen@amazon.com> Co-authored-by: Nikolas Komonen <118216176+nkomonen-amazon@users.noreply.github.com> Co-authored-by: Hweinstock <42325418+Hweinstock@users.noreply.github.com> Co-authored-by: nkomonen-amazon <nkomonen@amazon.com>
1 parent 6db5eda commit be976e1

File tree

13 files changed

+148
-43
lines changed

13 files changed

+148
-43
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Bug Fix",
3+
"description": "Toast message to warn users if Developer Profile is not selected"
4+
}

packages/amazonq/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@
135135
"amazonQChatPairProgramming": {
136136
"type": "boolean",
137137
"default": false
138+
},
139+
"amazonQSelectDeveloperProfile": {
140+
"type": "boolean",
141+
"default": false
138142
}
139143
},
140144
"additionalProperties": false

packages/amazonq/test/e2e/inline/inline.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ describe('Amazon Q Inline', async function () {
122122
.query({
123123
metricName: 'codewhisperer_userTriggerDecision',
124124
})
125-
.map((e) => collectionUtil.partialClone(e, 3, ['credentialStartUrl'], '[omitted]'))
125+
.map((e) => collectionUtil.partialClone(e, 3, ['credentialStartUrl'], { replacement: '[omitted]' }))
126126
}
127127

128128
for (const [name, invokeCompletion] of [

packages/core/src/auth/sso/clients.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ function addLoggingMiddleware(client: SSOOIDCClient) {
258258
args.input as unknown as Record<string, unknown>,
259259
3,
260260
['clientSecret', 'accessToken', 'refreshToken'],
261-
'[omitted]'
261+
{ replacement: '[omitted]' }
262262
)
263263
getLogger().debug('API request (%s %s): %O', hostname, path, input)
264264
}
@@ -288,7 +288,7 @@ function addLoggingMiddleware(client: SSOOIDCClient) {
288288
result.output as unknown as Record<string, unknown>,
289289
3,
290290
['clientSecret', 'accessToken', 'refreshToken'],
291-
'[omitted]'
291+
{ replacement: '[omitted]' }
292292
)
293293
getLogger().debug('API response (%s %s): %O', hostname, path, output)
294294
}

packages/core/src/codewhisperer/activation.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ import { SecurityIssueTreeViewProvider } from './service/securityIssueTreeViewPr
9595
import { setContext } from '../shared/vscode/setContext'
9696
import { syncSecurityIssueWebview } from './views/securityIssue/securityIssueWebview'
9797
import { detectCommentAboveLine } from '../shared/utilities/commentUtils'
98+
import { notifySelectDeveloperProfile } from './region/utils'
9899

99100
let localize: nls.LocalizeFunc
100101

@@ -380,6 +381,10 @@ export async function activate(context: ExtContext): Promise<void> {
380381
await auth.notifySessionConfiguration()
381382
}
382383
}
384+
385+
if (auth.requireProfileSelection()) {
386+
await notifySelectDeveloperProfile()
387+
}
383388
},
384389
{ emit: false, functionId: { name: 'activateCwCore' } }
385390
)

packages/core/src/codewhisperer/commands/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const firstStartUpSource = ExtStartUpSources.firstStartUp
1818
export const cwEllipsesMenu = 'ellipsesMenu'
1919
/** Indicates a CodeWhisperer command was executed from the command palette */
2020
export const commandPalette = 'commandPalette'
21+
/** Indicates a CodeWhisperer command was executed as a result of a toast message interaction */
22+
export const toastMessage = 'toastMessage'
2123

2224
/**
2325
* Indicates what caused the CodeWhisperer command to be executed, since a command can be executed from different "sources"
@@ -35,3 +37,4 @@ export type CodeWhispererSource =
3537
| typeof firstStartUpSource
3638
| typeof cwEllipsesMenu
3739
| typeof commandPalette
40+
| typeof toastMessage
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
import * as nls from 'vscode-nls'
6+
const localize = nls.loadMessageBundle()
7+
import { AmazonQPromptSettings } from '../../shared/settings'
8+
import { telemetry } from '../../shared/telemetry/telemetry'
9+
import vscode from 'vscode'
10+
import { selectRegionProfileCommand } from '../commands/basicCommands'
11+
import { placeholder } from '../../shared/vscode/commands2'
12+
import { toastMessage } from '../commands/types'
13+
14+
/**
15+
* Creates a toast message telling the user they need to select a Developer Profile
16+
*/
17+
export async function notifySelectDeveloperProfile() {
18+
const suppressId = 'amazonQSelectDeveloperProfile'
19+
const settings = AmazonQPromptSettings.instance
20+
const shouldShow = settings.isPromptEnabled(suppressId)
21+
if (!shouldShow) {
22+
return
23+
}
24+
25+
const message = localize(
26+
'aws.amazonq.profile.mustSelectMessage',
27+
'You must select a Q Developer Profile for Amazon Q features to work.'
28+
)
29+
const selectProfile = 'Select Profile'
30+
const dontShowAgain = 'Dont Show Again'
31+
32+
await telemetry.toolkit_showNotification.run(async () => {
33+
telemetry.record({ id: 'mustSelectDeveloperProfileMessage' })
34+
void vscode.window.showWarningMessage(message, selectProfile, dontShowAgain).then(async (resp) => {
35+
await telemetry.toolkit_invokeAction.run(async () => {
36+
if (resp === selectProfile) {
37+
// Show Profile
38+
telemetry.record({ action: 'select' })
39+
void selectRegionProfileCommand.execute(placeholder, toastMessage)
40+
} else if (resp === dontShowAgain) {
41+
telemetry.record({ action: 'dontShowAgain' })
42+
await settings.disablePrompt(suppressId)
43+
} else {
44+
telemetry.record({ action: 'ignore' })
45+
}
46+
})
47+
})
48+
})
49+
}

packages/core/src/codewhisperer/util/authUtil.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { withTelemetryContext } from '../../shared/telemetry/util'
4646
import { focusAmazonQPanel } from '../../codewhispererChat/commands/registerCommands'
4747
import { throttle } from 'lodash'
4848
import { RegionProfileManager } from '../region/regionProfileManager'
49+
4950
/** Backwards compatibility for connections w pre-chat scopes */
5051
export const codeWhispererCoreScopes = [...scopesCodeWhispererCore]
5152
export const codeWhispererChatScopes = [...codeWhispererCoreScopes, ...scopesCodeWhispererChat]

packages/core/src/shared/settings-amazonq.gen.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ export const amazonqSettings = {
2222
"amazonQLspManifestMessage": {},
2323
"amazonQWorkspaceLspManifestMessage": {},
2424
"amazonQChatDisclaimer": {},
25-
"amazonQChatPairProgramming": {}
25+
"amazonQChatPairProgramming": {},
26+
"amazonQSelectDeveloperProfile": {}
2627
},
2728
"amazonQ.showCodeWithReferences": {},
2829
"amazonQ.allowFeatureDevelopmentToRunCodeAndTests": {},

packages/core/src/shared/utilities/collectionUtils.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { isWeb } from '../extensionGlobals'
77
import { inspect as nodeInspect } from 'util'
88
import { AsyncCollection, toCollection } from './asyncCollection'
99
import { SharedProp, AccumulableKeys, Coalesce, isNonNullable } from './tsUtils'
10+
import { truncate } from './textUtilities'
1011

1112
export function union<T>(a: Iterable<T>, b: Iterable<T>): Set<T> {
1213
const result = new Set<T>()
@@ -304,26 +305,38 @@ export function assign<T extends Record<any, any>, U extends Partial<T>>(data: T
304305
* @param depth
305306
* @param omitKeys Omit properties matching these names (at any depth).
306307
* @param replacement Replacement for object whose fields extend beyond `depth`, and properties matching `omitKeys`.
308+
* @param maxStringLength truncates string values that exceed this threshold (includes values in nested arrays)
307309
*/
308-
export function partialClone(obj: any, depth: number = 3, omitKeys: string[] = [], replacement?: any): any {
310+
export function partialClone(
311+
obj: any,
312+
depth: number = 3,
313+
omitKeys: string[] = [],
314+
options?: {
315+
replacement?: any
316+
maxStringLength?: number
317+
}
318+
): any {
309319
// Base case: If input is not an object or has no children, return it.
310320
if (typeof obj !== 'object' || obj === null || 0 === Object.getOwnPropertyNames(obj).length) {
321+
if (typeof obj === 'string' && options?.maxStringLength) {
322+
return truncate(obj, options?.maxStringLength, '...')
323+
}
311324
return obj
312325
}
313326

314327
// Create a new object of the same type as the input object.
315328
const clonedObj = Array.isArray(obj) ? [] : {}
316329

317330
if (depth === 0) {
318-
return replacement ? replacement : clonedObj
331+
return options?.replacement ? options.replacement : clonedObj
319332
}
320333

321334
// Recursively clone properties of the input object
322335
for (const key in obj) {
323336
if (omitKeys.includes(key)) {
324-
;(clonedObj as any)[key] = replacement ? replacement : Array.isArray(obj) ? [] : {}
337+
;(clonedObj as any)[key] = options?.replacement ? options.replacement : Array.isArray(obj) ? [] : {}
325338
} else if (Object.prototype.hasOwnProperty.call(obj, key)) {
326-
;(clonedObj as any)[key] = partialClone(obj[key], depth - 1, omitKeys, replacement)
339+
;(clonedObj as any)[key] = partialClone(obj[key], depth - 1, omitKeys, options)
327340
}
328341
}
329342

0 commit comments

Comments
 (0)