Skip to content

Commit 6cf7bcc

Browse files
committed
Merge branch 'master' into jscpd/changedlines
2 parents e5e175f + ccba819 commit 6cf7bcc

File tree

42 files changed

+627
-298
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+627
-298
lines changed

docs/telemetry.md

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -142,20 +142,23 @@ Finally, if `setupStep2()` was the thing that failed we would see a metric like:
142142

143143
## Adding a "Stack Trace" to your metric
144144

145-
### Problem
145+
When errors are thrown we do not attach the stack trace in telemetry. We only know about the error itself, but
146+
not the path it took to get there. We sometimes need this stack trace to debug, and only have telemetry to get insight on what happened since we do not have access to logs.
147+
148+
### Scenario
146149

147150
Common example: _"I have a function, `thisFailsSometimes()` that is called in multiple places. The function sometimes fails, I know from telemetry, but I do not know if it is failing when it is a specific caller. If I knew the call stack/trace that it took to call my function that would help me debug."_
148151

149152
```typescript
150-
function outerA() {
153+
function runsSuccessfully() {
151154
thisFailsSometimes(1) // this succeeds
152155
}
153156

154-
function outerB() {
157+
function thisThrows() {
155158
thisFailsSometimes(0) // this fails
156159
}
157160

158-
function thisFailsSometimes(num: number) {
161+
function failsDependingOnInput(num: number) {
159162
return telemetry.my_Metric.run(() => {
160163
if (number === 0) {
161164
throw Error('Cannot be 0')
@@ -167,31 +170,61 @@ function thisFailsSometimes(num: number) {
167170

168171
### Solution
169172

170-
Add a value to `function` in the options of a `run()`. This will result in a stack of functions identifiers that were previously called
171-
before `thisFailsSometimes()` was run. You can then retrieve the stack in the `run()` of your final metric using `getFunctionStack()`.
173+
On class methods, use the `@withTelemetryContext()` decorator to add context to the execution. Depending on the args set, it provides features like emitting the result, or adding it's context to errors.
174+
175+
> NOTE: Decorators are currently only supported for methods and not functions
176+
177+
```typescript
178+
class MyClass {
179+
@withTelemetryContext({ name: 'runsSuccessfully', class: 'MyClass' })
180+
public runsSuccessfully() {
181+
failsDependingOnInput(1)
182+
}
183+
184+
@withTelemetryContext({ name: 'thisThrows', class: 'MyClass', errorCtx: true })
185+
public thisThrows() {
186+
failsDependingOnInput(0)
187+
}
188+
189+
@withTelemetryContext({ name: 'failsDependingOnInput' class: 'MyClass', emit: true, errorCtx: true})
190+
private failsDependingOnInput(num: number) {
191+
if (number === 0) {
192+
throw Error('Cannot be 0')
193+
}
194+
...
195+
}
196+
}
197+
198+
// Results in a metric: { source: 'MyClass#thisThrows,failsDependingOnInput', result: 'Failed' }
199+
// Results in an error that has context about the methods that lead up to it.
200+
new MyClass().thisThrows()
201+
```
202+
203+
Separately if you must use a function, add a value to `function` in the options of a `run()`. This will result in a stack of functions identifiers that were previously called
204+
before `failsDependingOnInput()` was run. You can then retrieve the stack in the `run()` of your final metric using `getFunctionStack()`.
172205

173206
```typescript
174-
function outerA() {
175-
telemetry.my_Metric.run(() => thisFailsSometimes(1), { functionId: { name: 'outerA' }})
207+
function runsSuccessfully() {
208+
telemetry.my_Metric.run(() => failsDependingOnInput(1), { functionId: { name: 'runsSuccessfully' }})
176209
}
177210

178-
function outerB() {
179-
telemetry.my_Metric.run(() => thisFailsSometimes(0), { functionId: { source: 'outerB' }})
211+
function thisThrows() {
212+
telemetry.my_Metric.run(() => failsDependingOnInput(0), { functionId: { source: 'thisThrows' }})
180213
}
181214

182-
function thisFailsSometimes(num: number) {
215+
function failsDependingOnInput(num: number) {
183216
return telemetry.my_Metric.run(() => {
184217
telemetry.record({ theCallStack: asStringifiedStack(telemetry.getFunctionStack())})
185218
if (number === 0) {
186219
throw Error('Cannot be 0')
187220
}
188221
...
189-
}, { functionId: { name: 'thisFailsSometimes' }})
222+
}, { functionId: { name: 'failsDependingOnInput' }})
190223
}
191224

192-
// Results in a metric: { theCallStack: 'outerB:thisFailsSometimes', result: 'Failed' }
193-
// { theCallStack: 'outerB:thisFailsSometimes' } implies 'outerB' was run first, then 'thisFailsSometimes'. See docstrings for more info.
194-
outerB()
225+
// Results in a metric: { theCallStack: 'thisThrows:failsDependingOnInput', result: 'Failed' }
226+
// { theCallStack: 'thisThrows:failsDependingOnInput' } implies 'thisThrows' was run first, then 'failsDependingOnInput'. See docstrings for more info.
227+
thisThrows()
195228
```
196229

197230
### Important Notes
@@ -216,25 +249,6 @@ outerB()
216249
c() // result: 'a:c', note that 'b' is not included
217250
```
218251

219-
- If you are using `run()` with a class method, you can also add the class to the entry for more context
220-
221-
```typescript
222-
class A {
223-
a() {
224-
return telemetry.my_Metric.run(() => this.b(), { functionId: { name: 'a', class: 'A' } })
225-
}
226-
227-
b() {
228-
return telemetry.my_Metric.run(() => asStringifiedStack(telemetry.getFunctionStack()), {
229-
functionId: { name: 'b', class: 'A' },
230-
})
231-
}
232-
}
233-
234-
const inst = new A()
235-
inst.a() // 'A#a,b'
236-
```
237-
238252
- If you do not want your `run()` to emit telemetry, set `emit: false` in the options
239253

240254
```typescript
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": "Amazon Q chat: `@workspace` command shown in all tab types"
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "Code Transform: Enable support for Java 17 projects."
4+
}

packages/amazonq/test/unit/codewhisperer/util/crossFileContextUtil.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ describe('crossFileContextUtil', function () {
5050
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
5151
preview: false,
5252
})
53+
54+
await assertTabCount(2)
55+
5356
const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
5457
assert.ok(actual)
55-
assert.ok(actual.supplementalContextItems.length === 3)
56-
58+
assert.strictEqual(actual.supplementalContextItems.length, 3)
5759
assert.strictEqual(actual.supplementalContextItems[0].content.split('\n').length, 50)
5860
assert.strictEqual(actual.supplementalContextItems[1].content.split('\n').length, 50)
5961
assert.strictEqual(actual.supplementalContextItems[2].content.split('\n').length, 50)
@@ -64,6 +66,9 @@ describe('crossFileContextUtil', function () {
6466
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
6567
preview: false,
6668
})
69+
70+
await assertTabCount(2)
71+
6772
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('t1')
6873
sinon
6974
.stub(LspController.instance, 'queryInlineProjectContext')
@@ -78,7 +83,7 @@ describe('crossFileContextUtil', function () {
7883

7984
const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
8085
assert.ok(actual)
81-
assert.ok(actual.supplementalContextItems.length === 4)
86+
assert.strictEqual(actual.supplementalContextItems.length, 4)
8287
assert.strictEqual(actual?.strategy, 'codemap')
8388
assert.deepEqual(actual?.supplementalContextItems[0], {
8489
content: 'foo',
@@ -96,6 +101,9 @@ describe('crossFileContextUtil', function () {
96101
const myCurrentEditor = await toTextEditor('', 'TargetFile.java', tempFolder, {
97102
preview: false,
98103
})
104+
105+
await assertTabCount(2)
106+
99107
sinon.stub(FeatureConfigProvider.instance, 'getProjectContextGroup').returns('t2')
100108
sinon
101109
.stub(LspController.instance, 'queryInlineProjectContext')
@@ -130,7 +138,7 @@ describe('crossFileContextUtil', function () {
130138

131139
const actual = await crossFile.fetchSupplementalContextForSrc(myCurrentEditor, fakeCancellationToken)
132140
assert.ok(actual)
133-
assert.ok(actual.supplementalContextItems.length === 5)
141+
assert.strictEqual(actual.supplementalContextItems.length, 5)
134142
assert.strictEqual(actual?.strategy, 'bm25')
135143

136144
assert.deepEqual(actual?.supplementalContextItems[0], {

packages/amazonq/test/unit/codewhisperer/util/supplemetalContextUtil.test.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import assert from 'assert'
77
import * as vscode from 'vscode'
88
import * as sinon from 'sinon'
99
import * as crossFile from 'aws-core-vscode/codewhisperer'
10-
import { TestFolder } from 'aws-core-vscode/test'
10+
import { TestFolder, assertTabCount } from 'aws-core-vscode/test'
1111
import { FeatureConfigProvider } from 'aws-core-vscode/codewhisperer'
1212
import { toTextEditor } from 'aws-core-vscode/test'
1313

@@ -39,6 +39,8 @@ describe('supplementalContextUtil', function () {
3939
preview: false,
4040
})
4141

42+
await assertTabCount(4)
43+
4244
const actual = await crossFile.fetchSupplementalContext(editor, fakeCancellationToken)
4345
assert.ok(actual?.supplementalContextItems.length === 3)
4446
})
@@ -53,6 +55,8 @@ describe('supplementalContextUtil', function () {
5355
preview: false,
5456
})
5557

58+
await assertTabCount(4)
59+
5660
const actual = await crossFile.fetchSupplementalContext(editor, fakeCancellationToken)
5761
assert.ok(actual?.supplementalContextItems.length === 0)
5862
})

packages/core/src/amazonq/webview/ui/tabs/constants.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,23 @@
44
*/
55
import { isSQLTransformReady } from '../../../../dev/config'
66
import { TabType } from '../storages/tabsStorage'
7+
import { QuickActionCommandGroup } from '@aws/mynah-ui'
78

89
export type TabTypeData = {
910
title: string
1011
placeholder: string
1112
welcome: string
13+
contextCommands?: QuickActionCommandGroup[]
14+
}
15+
16+
const workspaceCommand: QuickActionCommandGroup = {
17+
groupName: 'Mention code',
18+
commands: [
19+
{
20+
command: '@workspace',
21+
description: '(BETA) Reference all code in workspace.',
22+
},
23+
],
1224
}
1325

1426
const commonTabData: TabTypeData = {
@@ -17,6 +29,7 @@ const commonTabData: TabTypeData = {
1729
welcome: `Hi, I'm Amazon Q. I can answer your software development questions.
1830
Ask me to explain, debug, or optimize your code.
1931
You can enter \`/\` to see a list of quick actions. Add @workspace to beginning of your message to include your entire workspace as context.`,
32+
contextCommands: [workspaceCommand],
2033
}
2134

2235
export const TabTypeDataMap: Record<TabType, TabTypeData> = {
@@ -42,8 +55,6 @@ I can help you with the following tasks:
4255
- Convert embedded SQL from Oracle databases to PostgreSQL
4356
4457
What would you like to do? You can enter 'language upgrade' or 'SQL conversion'.`
45-
: `Welcome to code transformation!
46-
47-
I can help you upgrade your Java 8 and 11 codebases to Java 17.`,
58+
: `Welcome to code transformation!`,
4859
},
4960
}

packages/core/src/amazonq/webview/ui/tabs/generator.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,7 @@ export class TabDataGenerator {
3535
'Amazon Q Developer uses generative AI. You may need to verify responses. See the [AWS Responsible AI Policy](https://aws.amazon.com/machine-learning/responsible-ai/policy/).',
3636
quickActionCommands: this.quickActionsGenerator.generateForTab(tabType),
3737
promptInputPlaceholder: TabTypeDataMap[tabType].placeholder,
38-
contextCommands: [
39-
{
40-
groupName: 'Mention code',
41-
commands: [
42-
{
43-
command: '@workspace',
44-
description: '(BETA) Reference all code in workspace.',
45-
},
46-
],
47-
},
48-
],
38+
contextCommands: TabTypeDataMap[tabType].contextCommands,
4939
chatItems: needWelcomeMessages
5040
? [
5141
{

packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ export class Messenger {
191191
value: JDKVersion.JDK11,
192192
label: JDKVersion.JDK11,
193193
},
194+
{
195+
value: JDKVersion.JDK17,
196+
label: JDKVersion.JDK17,
197+
},
194198
{
195199
value: JDKVersion.UNSUPPORTED,
196200
label: 'Other',

packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ export default class MessengerUtils {
4444
} else if (os.platform() === 'darwin') {
4545
const jdkVersion = transformByQState.getSourceJDKVersion()
4646
if (jdkVersion === JDKVersion.JDK8) {
47-
javaHomePrompt += ` ${CodeWhispererConstants.macJava8HomeHelpChatMessage}`
47+
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(1.8)}`
4848
} else if (jdkVersion === JDKVersion.JDK11) {
49-
javaHomePrompt += ` ${CodeWhispererConstants.macJava11HomeHelpChatMessage}`
49+
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(11)}`
50+
} else if (jdkVersion === JDKVersion.JDK17) {
51+
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(17)}`
5052
}
5153
} else {
5254
javaHomePrompt += ` ${CodeWhispererConstants.linuxJavaHomeHelpChatMessage}`

packages/core/src/auth/auth.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ export interface ConnectionStateChangeEvent {
126126
readonly state: ProfileMetadata['connectionState']
127127
}
128128

129-
export type AuthType = Auth
130-
131129
export type DeletedConnection = { connId: Connection['id']; storedProfile?: StoredProfile }
132130
type DeclaredConnection = Pick<SsoProfile, 'ssoRegion' | 'startUrl'> & { source: string }
133131

0 commit comments

Comments
 (0)