Skip to content

Commit fceeae7

Browse files
MarcoWang3aws-toolkit-automationWill-ShaoHual0minousDiler Zaza
authored
feat(amazonq): Auto Debug Functionality (#7609)
## Problem Developers frequently encounter compilation errors, linting issues, and other diagnostic problems while coding in VS Code. Currently, they need to manually copy error messages and switch to Amazon Q chat to get help fixing these issues, creating friction in the development workflow and breaking their coding flow. ## Solution This PR introduces Amazon Q Auto Debug, a new feature that seamlessly integrates diagnostic problem-solving directly into the VS Code editor experience. The feature provides three main interaction methods: Quick Fix Integration: When hovering over diagnostic errors/warnings, developers see Amazon Q options in the quick fix menu including "Fix Problem", "Fix All Errors", and "Explain Problem" actions. Command Palette Access: Three new commands are registered (amazonq.01.fixWithQ, amazonq.02.fixAllWithQ, amazonq.03.explainProblem) that can be triggered from the command palette or bound to keyboard shortcuts. Intelligent Error Processing: The system automatically captures diagnostic information from VS Code's language servers, formats error context with surrounding code snippets, and sends structured prompts to Amazon Q chat. For "Fix All" operations, it processes up to 15 errors at once to avoid overwhelming the AI system. The workflow operates through a controller-based architecture that monitors VS Code diagnostics, formats error context with file paths and line numbers, and communicates directly with the Amazon Q chat panel via LSP client messaging. When users trigger a fix action, the system automatically focuses the Amazon Q panel and submits a formatted prompt containing the error details and surrounding code context, enabling Amazon Q to provide targeted solutions without requiring manual context switching. ## Video Demos Fix single problem https://github.com/user-attachments/assets/c73b7a63-8806-4016-b7af-03f239f07bba Explain single problem https://github.com/user-attachments/assets/367137aa-8362-4a08-a12b-27d892c0b6e6 Fix all errors https://github.com/user-attachments/assets/95eb5691-d3be-499a-8e8c-76f4b77c57dd --------- Co-authored-by: aws-toolkit-automation <[email protected]> Co-authored-by: aws-toolkit-automation <> Co-authored-by: Will Lo <[email protected]> Co-authored-by: Diler Zaza <[email protected]> Co-authored-by: Diler Zaza <[email protected]> Co-authored-by: David <[email protected]> Co-authored-by: David Hasani <[email protected]> Co-authored-by: samgst-amazon <[email protected]> Co-authored-by: Ashish Reddy Podduturi <[email protected]> Co-authored-by: Tyrone Smith <[email protected]> Co-authored-by: zelzhou <[email protected]> Co-authored-by: Ralph Flora <[email protected]> Co-authored-by: Jingyuan Li <[email protected]> Co-authored-by: Rile Ge <[email protected]> Co-authored-by: Aidan Ton <[email protected]> Co-authored-by: Lei Gao <[email protected]> Co-authored-by: Laxman Reddy <[email protected]> Co-authored-by: invictus <[email protected]> Co-authored-by: chungjac <[email protected]>
1 parent 6e2976e commit fceeae7

File tree

12 files changed

+807
-0
lines changed

12 files changed

+807
-0
lines changed

packages/amazonq/src/extension.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import { registerCommands } from './commands'
4545
import { focusAmazonQPanel } from 'aws-core-vscode/codewhispererChat'
4646
import { activate as activateAmazonqLsp } from './lsp/activation'
4747
import { hasGlibcPatch } from './lsp/client'
48+
import { activateAutoDebug } from './lsp/chat/autoDebug/activation'
4849

4950
export const amazonQContextPrefix = 'amazonq'
5051

@@ -131,6 +132,14 @@ export async function activateAmazonQCommon(context: vscode.ExtensionContext, is
131132
await activateAmazonqLsp(context)
132133
}
133134

135+
// Activate AutoDebug feature at extension level
136+
try {
137+
const autoDebugFeature = await activateAutoDebug(context)
138+
context.subscriptions.push(autoDebugFeature)
139+
} catch (error) {
140+
getLogger().error('Failed to activate AutoDebug feature at extension level: %s', error)
141+
}
142+
134143
// Generic extension commands
135144
registerGenericCommands(context, amazonQContextPrefix)
136145

packages/amazonq/src/lsp/chat/activation.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ import { activate as registerLegacyChatListeners } from '../../app/chat/activati
1717
import { DefaultAmazonQAppInitContext } from 'aws-core-vscode/amazonq'
1818
import { AuthUtil, getSelectedCustomization } from 'aws-core-vscode/codewhisperer'
1919
import { pushConfigUpdate } from '../config'
20+
import { AutoDebugLspClient } from './autoDebug/lsp/autoDebugLspClient'
2021

2122
export async function activate(languageClient: LanguageClient, encryptionKey: Buffer, mynahUIPath: string) {
2223
const disposables = globals.context.subscriptions
2324

2425
const provider = new AmazonQChatViewProvider(mynahUIPath, languageClient)
2526

27+
// Set the chat view provider for AutoDebug to use
28+
AutoDebugLspClient.setChatViewProvider(provider)
29+
2630
disposables.push(
2731
window.registerWebviewViewProvider(AmazonQChatViewProvider.viewType, provider, {
2832
webviewOptions: {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import { getLogger } from 'aws-core-vscode/shared'
8+
import { AutoDebugCommands } from './commands'
9+
import { AutoDebugCodeActionsProvider } from './codeActionsProvider'
10+
import { AutoDebugController } from './controller'
11+
12+
/**
13+
* Auto Debug feature activation for Amazon Q
14+
* This handles the complete lifecycle of the auto debug feature
15+
*/
16+
export class AutoDebugFeature implements vscode.Disposable {
17+
private readonly logger = getLogger()
18+
private readonly disposables: vscode.Disposable[] = []
19+
20+
private autoDebugCommands?: AutoDebugCommands
21+
private codeActionsProvider?: AutoDebugCodeActionsProvider
22+
private controller?: AutoDebugController
23+
24+
constructor(private readonly context: vscode.ExtensionContext) {}
25+
26+
/**
27+
* Activate the auto debug feature
28+
*/
29+
async activate(): Promise<void> {
30+
try {
31+
// Initialize the controller first
32+
this.controller = new AutoDebugController()
33+
34+
// Initialize commands and register them with the controller
35+
this.autoDebugCommands = new AutoDebugCommands()
36+
this.autoDebugCommands.registerCommands(this.context, this.controller)
37+
38+
// Initialize code actions provider
39+
this.codeActionsProvider = new AutoDebugCodeActionsProvider()
40+
this.context.subscriptions.push(this.codeActionsProvider)
41+
42+
// Add all to disposables
43+
this.disposables.push(this.controller, this.autoDebugCommands, this.codeActionsProvider)
44+
} catch (error) {
45+
this.logger.error('AutoDebugFeature: Failed to activate auto debug feature: %s', error)
46+
throw error
47+
}
48+
}
49+
50+
/**
51+
* Get the auto debug controller instance
52+
*/
53+
getController(): AutoDebugController | undefined {
54+
return this.controller
55+
}
56+
57+
/**
58+
* Dispose of all resources
59+
*/
60+
dispose(): void {
61+
vscode.Disposable.from(...this.disposables).dispose()
62+
}
63+
}
64+
65+
/**
66+
* Factory function to activate auto debug feature with LSP client
67+
* This is the main entry point for activating auto debug
68+
*/
69+
export async function activateAutoDebug(
70+
context: vscode.ExtensionContext,
71+
client?: any,
72+
encryptionKey?: Buffer
73+
): Promise<AutoDebugFeature> {
74+
const feature = new AutoDebugFeature(context)
75+
await feature.activate()
76+
77+
return feature
78+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
8+
/**
9+
* Provides code actions for Amazon Q Auto Debug features.
10+
* Integrates with VS Code's quick fix system to offer debugging assistance.
11+
*/
12+
export class AutoDebugCodeActionsProvider implements vscode.CodeActionProvider, vscode.Disposable {
13+
private readonly disposables: vscode.Disposable[] = []
14+
15+
public static readonly providedCodeActionKinds = [vscode.CodeActionKind.QuickFix, vscode.CodeActionKind.Refactor]
16+
17+
constructor() {
18+
this.registerProvider()
19+
}
20+
21+
private registerProvider(): void {
22+
// Register for all file types
23+
const selector: vscode.DocumentSelector = [{ scheme: 'file' }]
24+
25+
this.disposables.push(
26+
vscode.languages.registerCodeActionsProvider(selector, this, {
27+
providedCodeActionKinds: AutoDebugCodeActionsProvider.providedCodeActionKinds,
28+
})
29+
)
30+
}
31+
32+
/**
33+
* Provides code actions for the given document and range
34+
*/
35+
public provideCodeActions(
36+
document: vscode.TextDocument,
37+
range: vscode.Range | vscode.Selection,
38+
context: vscode.CodeActionContext,
39+
token: vscode.CancellationToken
40+
): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
41+
if (token.isCancellationRequested) {
42+
return []
43+
}
44+
45+
const actions: vscode.CodeAction[] = []
46+
47+
// Get diagnostics for the current range
48+
const diagnostics = context.diagnostics.filter(
49+
(diagnostic) => diagnostic.range.intersection(range) !== undefined
50+
)
51+
52+
if (diagnostics.length > 0) {
53+
// Add "Fix with Amazon Q" action
54+
actions.push(this.createFixWithQAction(document, range, diagnostics))
55+
56+
// Add "Fix All with Amazon Q" action
57+
actions.push(this.createFixAllWithQAction(document))
58+
59+
// Add "Explain Problem" action
60+
actions.push(this.createExplainProblemAction(document, range, diagnostics))
61+
}
62+
return actions
63+
}
64+
65+
private createFixWithQAction(
66+
document: vscode.TextDocument,
67+
range: vscode.Range,
68+
diagnostics: vscode.Diagnostic[]
69+
): vscode.CodeAction {
70+
const action = new vscode.CodeAction(
71+
`Amazon Q: Fix Problem (${diagnostics.length} issue${diagnostics.length !== 1 ? 's' : ''})`,
72+
vscode.CodeActionKind.QuickFix
73+
)
74+
75+
action.command = {
76+
command: 'amazonq.01.fixWithQ',
77+
title: 'Amazon Q: Fix Problem',
78+
arguments: [range, diagnostics],
79+
}
80+
81+
action.diagnostics = diagnostics
82+
action.isPreferred = true // Make this the preferred quick fix
83+
84+
return action
85+
}
86+
87+
private createFixAllWithQAction(document: vscode.TextDocument): vscode.CodeAction {
88+
const action = new vscode.CodeAction('Amazon Q: Fix All Errors', vscode.CodeActionKind.QuickFix)
89+
90+
action.command = {
91+
command: 'amazonq.02.fixAllWithQ',
92+
title: 'Amazon Q: Fix All Errors',
93+
}
94+
95+
return action
96+
}
97+
98+
private createExplainProblemAction(
99+
document: vscode.TextDocument,
100+
range: vscode.Range,
101+
diagnostics: vscode.Diagnostic[]
102+
): vscode.CodeAction {
103+
const action = new vscode.CodeAction('Amazon Q: Explain Problem', vscode.CodeActionKind.QuickFix)
104+
105+
action.command = {
106+
command: 'amazonq.03.explainProblem',
107+
title: 'Amazon Q: Explain Problem',
108+
arguments: [range, diagnostics],
109+
}
110+
111+
action.diagnostics = diagnostics
112+
113+
return action
114+
}
115+
116+
public dispose(): void {
117+
vscode.Disposable.from(...this.disposables).dispose()
118+
}
119+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*!
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
import * as vscode from 'vscode'
7+
import { Commands, getLogger, messages } from 'aws-core-vscode/shared'
8+
import { AutoDebugController } from './controller'
9+
10+
/**
11+
* Auto Debug commands for Amazon Q
12+
* Handles all command registrations and implementations
13+
*/
14+
export class AutoDebugCommands implements vscode.Disposable {
15+
private readonly logger = getLogger()
16+
private readonly disposables: vscode.Disposable[] = []
17+
private controller!: AutoDebugController
18+
19+
/**
20+
* Register all auto debug commands
21+
*/
22+
registerCommands(context: vscode.ExtensionContext, controller: AutoDebugController): void {
23+
this.controller = controller
24+
this.disposables.push(
25+
// Fix with Amazon Q command
26+
Commands.register(
27+
{
28+
id: 'amazonq.01.fixWithQ',
29+
name: 'Amazon Q: Fix Problem',
30+
},
31+
async (range?: vscode.Range, diagnostics?: vscode.Diagnostic[]) => {
32+
await this.fixWithAmazonQ(range, diagnostics)
33+
}
34+
),
35+
36+
// Fix All with Amazon Q command
37+
Commands.register(
38+
{
39+
id: 'amazonq.02.fixAllWithQ',
40+
name: 'Amazon Q: Fix All Errors',
41+
},
42+
async () => {
43+
await this.fixAllWithAmazonQ()
44+
}
45+
),
46+
47+
// Explain Problem with Amazon Q command
48+
Commands.register(
49+
{
50+
id: 'amazonq.03.explainProblem',
51+
name: 'Amazon Q: Explain Problem',
52+
},
53+
async (range?: vscode.Range, diagnostics?: vscode.Diagnostic[]) => {
54+
await this.explainProblem(range, diagnostics)
55+
}
56+
)
57+
)
58+
59+
// Add all disposables to context
60+
context.subscriptions.push(...this.disposables)
61+
}
62+
63+
/**
64+
* Generic error handling wrapper for command execution
65+
*/
66+
private async executeWithErrorHandling<T>(
67+
action: () => Promise<T>,
68+
errorMessage: string,
69+
logContext: string
70+
): Promise<T | void> {
71+
try {
72+
return await action()
73+
} catch (error) {
74+
this.logger.error(`AutoDebugCommands: Error in ${logContext}: %s`, error)
75+
void messages.showMessage('error', 'Amazon Q was not able to fix or explain the problem. Try again shortly')
76+
}
77+
}
78+
79+
/**
80+
* Check if there's an active editor and log warning if not
81+
*/
82+
private checkActiveEditor(): vscode.TextEditor | undefined {
83+
const editor = vscode.window.activeTextEditor
84+
if (!editor) {
85+
this.logger.warn('AutoDebugCommands: No active editor found')
86+
}
87+
return editor
88+
}
89+
90+
/**
91+
* Fix with Amazon Q - fixes only the specific issues the user selected
92+
*/
93+
private async fixWithAmazonQ(range?: vscode.Range, diagnostics?: vscode.Diagnostic[]): Promise<void> {
94+
await this.executeWithErrorHandling(
95+
async () => {
96+
const editor = this.checkActiveEditor()
97+
if (!editor) {
98+
return
99+
}
100+
await this.controller.fixSpecificProblems(range, diagnostics)
101+
},
102+
'Fix with Amazon Q',
103+
'fixWithAmazonQ'
104+
)
105+
}
106+
107+
/**
108+
* Fix All with Amazon Q - processes all errors in the current file
109+
*/
110+
private async fixAllWithAmazonQ(): Promise<void> {
111+
await this.executeWithErrorHandling(
112+
async () => {
113+
const editor = this.checkActiveEditor()
114+
if (!editor) {
115+
return
116+
}
117+
await this.controller.fixAllProblemsInFile(10) // 10 errors per batch
118+
},
119+
'Fix All with Amazon Q',
120+
'fixAllWithAmazonQ'
121+
)
122+
}
123+
124+
/**
125+
* Explains the problem using Amazon Q
126+
*/
127+
private async explainProblem(range?: vscode.Range, diagnostics?: vscode.Diagnostic[]): Promise<void> {
128+
await this.executeWithErrorHandling(
129+
async () => {
130+
const editor = this.checkActiveEditor()
131+
if (!editor) {
132+
return
133+
}
134+
await this.controller.explainProblems(range, diagnostics)
135+
},
136+
'Explain Problem',
137+
'explainProblem'
138+
)
139+
}
140+
141+
/**
142+
* Dispose of all resources
143+
*/
144+
dispose(): void {
145+
vscode.Disposable.from(...this.disposables).dispose()
146+
}
147+
}

0 commit comments

Comments
 (0)