-
Notifications
You must be signed in to change notification settings - Fork 274
Simplify error troubleshooting workflow with two-step guidance #6941
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
fe61db8
71dfc00
43cae9d
db8f91b
e5a292b
e38ac72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -168,45 +168,56 @@ func (e *ErrorMiddleware) Run(ctx context.Context, next NextFn) (*actions.Action | |||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if troubleshootScope != "" { | ||||||||||||||
| var troubleshootPrompt string | ||||||||||||||
| switch troubleshootScope { | ||||||||||||||
| case "explain": | ||||||||||||||
| troubleshootPrompt = fmt.Sprintf( | ||||||||||||||
| `Steps to follow: | ||||||||||||||
| troubleshootPrompt := fmt.Sprintf( | ||||||||||||||
| `Steps to follow: | ||||||||||||||
| 1. Use available tools including azd_error_troubleshooting tool to identify this error. | ||||||||||||||
| 2. Provide a concise explanation of the error and its root cause in 3-5 sentences. | ||||||||||||||
| DO NOT return JSON. Use plain text with minimal markdown formatting. | ||||||||||||||
| 2. Provide a concise explanation using these two sections with bold markdown titles: | ||||||||||||||
| **What's happening**: Explain what the error is in 1-2 sentences. | ||||||||||||||
| **Why it's happening**: Explain the root cause in 1-3 sentences. | ||||||||||||||
| DO NOT return JSON. Use plain text with minimal markdown formatting beyond the section titles. | ||||||||||||||
| Do not provide fix steps. Do not perform any file changes. | ||||||||||||||
| Error details: %s`, errorInput) | ||||||||||||||
| case "guide": | ||||||||||||||
| troubleshootPrompt = fmt.Sprintf( | ||||||||||||||
| `Steps to follow: | ||||||||||||||
|
|
||||||||||||||
| agentOutput, err := azdAgent.SendMessage(ctx, troubleshootPrompt) | ||||||||||||||
|
|
||||||||||||||
| if err != nil { | ||||||||||||||
| e.displayAgentResponse(ctx, agentOutput, AIDisclaimer) | ||||||||||||||
| span.SetStatus(codes.Error, "agent.send_message.failed") | ||||||||||||||
| return nil, err | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| e.displayAgentResponse(ctx, agentOutput, AIDisclaimer) | ||||||||||||||
|
|
||||||||||||||
| // Ask user if they want step-by-step fix guidance | ||||||||||||||
| wantGuide, err := e.promptForFixGuidance(ctx) | ||||||||||||||
| if err != nil { | ||||||||||||||
| span.SetStatus(codes.Error, "agent.guidance.prompt.failed") | ||||||||||||||
| return nil, fmt.Errorf("prompting for fix guidance: %w", err) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| if !wantGuide { | ||||||||||||||
| span.SetStatus(codes.Ok, "agent.troubleshoot.explain_only") | ||||||||||||||
| return actionResult, originalError | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Generate step-by-step fix guidance | ||||||||||||||
| guidePrompt := fmt.Sprintf( | ||||||||||||||
| `Steps to follow: | ||||||||||||||
| 1. Use available tools including azd_error_troubleshooting tool to identify this error. | ||||||||||||||
| 2. Provide only the actionable fix steps as a short numbered list (max 5 steps). | ||||||||||||||
| Each step should be one sentence. Include exact commands if applicable. | ||||||||||||||
| DO NOT return JSON. Do not explain the error. Do not perform any file changes. | ||||||||||||||
| Error details: %s`, errorInput) | ||||||||||||||
| case "summarize": | ||||||||||||||
| troubleshootPrompt = fmt.Sprintf( | ||||||||||||||
| `Steps to follow: | ||||||||||||||
| 1. Use available tools including azd_error_troubleshooting tool to identify this error. | ||||||||||||||
| 2. Provide a brief summary with two sections: | ||||||||||||||
| **Error**: 1-2 sentence explanation of the root cause. | ||||||||||||||
| **Fix**: Numbered list of up to 3 actionable steps (one sentence each). | ||||||||||||||
| Keep the total response under 10 lines. | ||||||||||||||
| DO NOT return JSON. Do not perform any file changes. | ||||||||||||||
| Error details: %s`, errorInput) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| agentOutput, err := azdAgent.SendMessage(ctx, troubleshootPrompt) | ||||||||||||||
| guideOutput, err := azdAgent.SendMessage(ctx, guidePrompt) | ||||||||||||||
|
|
||||||||||||||
| if err != nil { | ||||||||||||||
| e.displayAgentResponse(ctx, agentOutput, AIDisclaimer) | ||||||||||||||
| e.displayAgentResponse(ctx, guideOutput, AIDisclaimer) | ||||||||||||||
| span.SetStatus(codes.Error, "agent.send_message.failed") | ||||||||||||||
| return nil, err | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| e.displayAgentResponse(ctx, agentOutput, AIDisclaimer) | ||||||||||||||
| e.displayAgentResponse(ctx, guideOutput, AIDisclaimer) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Ask user if they want to let AI fix the error | ||||||||||||||
|
|
@@ -427,7 +438,7 @@ func promptForErrorHandlingConsent( | |||||||||||||
|
|
||||||||||||||
| // promptTroubleshootingWithConsent combines consent and scope selection into a single prompt. | ||||||||||||||
| // Checks if a saved preference exists (e.g. mcp.errorHandling.troubleshooting.explain). | ||||||||||||||
| // Returns the scope ("explain", "fix", "summary") or "" if skipped. | ||||||||||||||
| // Returns the scope ("explain") or "" if skipped. | ||||||||||||||
|
Comment on lines
439
to
+441
|
||||||||||||||
| func (e *ErrorMiddleware) promptTroubleshootingWithConsent(ctx context.Context) (string, error) { | ||||||||||||||
| const configPrefix = "mcp.errorHandling.troubleshooting" | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -436,30 +447,18 @@ func (e *ErrorMiddleware) promptTroubleshootingWithConsent(ctx context.Context) | |||||||||||||
| return "", fmt.Errorf("failed to load user config: %w", err) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Check for saved "always" preferences | ||||||||||||||
| scopes := []string{"explain", "guide", "summarize", "skip"} | ||||||||||||||
| for _, scope := range scopes { | ||||||||||||||
| if val, ok := userConfig.GetString(configPrefix + "." + scope); ok && val == "allow" { | ||||||||||||||
| e.console.Message(ctx, output.WithWarningFormat( | ||||||||||||||
| "Troubleshooting scope is set to always %q. To change, run %s.\n", | ||||||||||||||
| scope, | ||||||||||||||
| output.WithHighLightFormat(fmt.Sprintf("azd config unset %s.%s", configPrefix, scope)), | ||||||||||||||
| )) | ||||||||||||||
| if scope == "skip" { | ||||||||||||||
| return "", nil | ||||||||||||||
| } | ||||||||||||||
| return scope, nil | ||||||||||||||
| } | ||||||||||||||
| // Check for saved "always skip" preference | ||||||||||||||
| if val, ok := userConfig.GetString(configPrefix + ".skip"); ok && val == "allow" { | ||||||||||||||
| e.console.Message(ctx, output.WithWarningFormat( | ||||||||||||||
| "Troubleshooting is set to always skip. To change, run %s.\n", | ||||||||||||||
hemarina marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||
| output.WithHighLightFormat(fmt.Sprintf("azd config unset %s.skip", configPrefix)), | ||||||||||||||
| )) | ||||||||||||||
| return "", nil | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
||||||||||||||
| // Check for saved troubleshooting scope (e.g. "explain") and honor it without prompting. | |
| if val, ok := userConfig.GetString(configPrefix + ".explain"); ok && val == "allow" { | |
| return "explain", nil | |
| } |
Copilot
AI
Feb 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the remaining option now being "Explain the error" (and fix guidance coming in a separate follow-up), the surrounding prompt text still saying "Generate troubleshooting steps" can be misleading. Consider updating the prompt/help copy to reflect the new two-step explanation→guidance flow so users know what to expect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The guide prompt tells the agent to use azd_error_troubleshooting again even though the immediately preceding explanation step likely already invoked the tool in the same conversation. This can increase latency/cost and may re-introduce verbosity; consider instructing the agent to reuse prior context/tool results and only call the troubleshooting tool again if needed.