Skip to content

Conversation

motm32
Copy link
Contributor

@motm32 motm32 commented Aug 27, 2025

This adds a new CopilotUserInput which is essentially just a Wrapper class of several vscode.window methods that handle user input.

I will add a PR soon in ACA that shows how this can be used but in essence if context.ui is set to a CopilotUserInput then anytime showQuickPick, showInputBox, etc. is called it will prompt copilot for an answer instead of showing the user.

If copilot is unable to generate a response or the response it gives does not match one of the quick picks as InvalidInputError is thrown and this will switch the context.ui back to an AzExtUserInput and the quick picks will work as normal instead of polling Copilot.

canPickMany case has not been fully implemented yet since ACA doesn't have any canPickMany quick picks so I would need to test this using rg. For now I am just throwing it back to the user to make the choice.

Copy link
Contributor

@MicroFish91 MicroFish91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is sick, love what you've got cooking up

@motm32 motm32 marked this pull request as ready for review August 28, 2025 21:50
@motm32 motm32 requested a review from a team as a code owner August 28, 2025 21:50
return lmsInPreferredOrder?.at(0);
}

export function createPrimaryPromptToGetSingleQuickPickInput(picks: string[], relevantContext?: string): string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too concerned about how optimal this is yet. I think when we do this for other commands, we should probably have a way to pass custom prompts since it may not be a generic one shoe fits all scenario.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yeah idk how far I would want to take the custom prompts. I could see adding some custom info you can pass in like description or what question you are being asked but I think the general shape should remain the same.

/**
* Wrapper class of several `vscode.window` methods that handle user input.
*/
export declare class AzExtUserInput implements IAzureUserInput {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to export this now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR I use AzExtUserInput to create a new instance for when the user goes back to edit. I could probably move it to have the logic and check everytime a go back error is called but it seemed a little overkill to do that instead of the just changing it when the edit button is clicked. But lmk if you would prefer that and I can change it


public showOpenDialog(): Promise<vscodeTypes.Uri[]> {
// Throw this back to the user
throw new InvalidInputError();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How jarring is it when the error gets thrown back and the user has to take control? I'm not sure if there's a great way to do it, but just curious what it currently looks like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically the InvalidInputError() doesn't get thrown to the user (or at least it shouldn't). It behaves similar to how GoBackError() does. The error is thrown in the background and then the user just see the pick that copilot couldn't answer pop up (and any subsequent picks).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the webview that says Copiloting is generating the picks close?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so at the moment. Since the webview lives only in the aca extension there isn't that good of a way to dispose of it here. I may can add a listener on the ACA side to see if I can dispose of it anytime that error is thrown. The view does get disgarded once the picks are all finished but yeah I totally forgot about that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pass a reference to the webview whenever we make a copilot UI call?

const jsonResponse: string = JSON.parse(response) as string;
this._onDidFinishPromptEmitter.fire({ value: jsonResponse });
return jsonResponse;
} else if (options.value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an else if?

I thought it'd be more like:

  • Prompt Copilot
  • If response is invalid, then check if (options.value)
  • If it exists, return that
  • If response is valid, just return that

return jsonResponse;
} catch {
// if copilot is unable to provide a response, fall back to the default value if it exists
if (options.value) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be outside of if(options.prompt)? If there's no prompt, shouldn't we default to options.value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we would want it in both places actually. Like if copilot can't give a response then default to the options.value and if there is not prompt then also default to options.value.

@@ -156,6 +158,16 @@ export class AzureWizard<T extends (IInternalActionContext & Partial<types.Execu
step = this.goBack(step);
}
continue;
} else if (pe.errorType === 'InvalidInputError') {
// If this error is thrown it means copilot was unable to provide a valid response
// In order to re prompt the user we need to set the ui back to AzExtUserInput
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// In order to re prompt the user we need to set the ui back to AzExtUserInput
// To let the user take over completing the wizard, we should initialize an AzExtUserInput with the existing context

@motm32 motm32 merged commit 55fb36c into main Sep 10, 2025
4 checks passed
@motm32 motm32 deleted the meganmott/copilotInput branch September 10, 2025 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants