GitHub Copilot Extensions: Adding followup prompts in a VS Code Extension

5 minute read

In the first post of this series, we introduced GitHub Copilot Extensions and discussed the two types of extensions. Client side and server side extensions.

In our previous post on Using Context in a VS Code Extension, we enhanced our VS Code Copilot extension by adding support for references to the UI and how to use explicit references in the prompt.

Goal

This post demonstrates how to enhance your VS Code Copilot extension by adding follow-up prompts to guide users toward further exploration within the Copilot Chat interface. We'll cover:

  1. Creating and registering a follow-up provider
  2. Defining follow-up suggestions using vscode.ChatFollowup
  3. Dynamically generating follow-ups based on context
  4. Integrating follow-ups with existing extension functionality

By the end of this tutorial, you'll understand how to use follow-up prompts to create more engaging and interactive experiences within your Copilot extension. We'll continue building upon our pirate/Yoda parrot example to demonstrate these concepts in practice.

TIP

The complete source code for this tutorial series is available on GitHub. These posts will guide you through building this extension step-by-step, from initial setup to the final version you see in the repository.

This simple example extension acts like a chat parrot, repeating what you type in the chat window. You can optionally have it repeat your message in pirate or Yoda style.

Follow-ups

Copilot Chat allows extensions to provide follow-up suggestions after generating a response. These follow-ups can guide users toward further exploration by suggesting related prompts, alternative approaches, relevant topics, or any other helpful next steps. This feature enhances the interactive experience by prompting users with potential avenues for continuing the conversation or refining their queries. Follow-ups can be dynamically generated based on the current context and the previous interaction, making them a powerful tool for guiding users through complex tasks or explorations.

Below you can see an example of a follow-up question to a prompt, "What about password hashing?"), notice it's a blue link before the prompt box.

What about password hashing following

If we click on it, it will execute the What about password hashing? prompt

executed a prompt from a followup

Now, let's explore how to enhance user engagement by enabling our extension to suggest relevant follow-up questions within the Copilot Chat interface. This feature allows us to guide users toward further exploration and provide helpful prompts for continuing the conversation or refining their queries.

Adding Follow-up questions

To enhance the user experience and guide further interaction, we can provide follow-up suggestions within our Copilot Chat extension. These suggestions appear after a response is generated, offering the user relevant next steps or alternative queries. To implement this functionality, we need to create a provider that returns an array of vscode.ChatFollowup objects. Each vscode.ChatFollowup object represents a single suggestion and has a specific format that we'll explore in detail. This approach allows us to dynamically suggest relevant follow-ups based on the current conversation context and the user's previous interactions.

ChatFollowup interface

export interface ChatFollowup {
		/**
		 * The message to send to the chat.
		 */
		prompt: string;

		/**
		 * A title to show the user. The prompt will be shown by default, when this is unspecified.
		 */
		label?: string;

		/**
		 * By default, the followup goes to the same participant/command. But this property can be set to invoke a different participant by ID.
		 * Followups can only invoke a participant that was contributed by the same extension.
		 */
		participant?: string;

		/**
		 * By default, the followup goes to the same participant/command. But this property can be set to invoke a different command.
		 */
		command?: string;
	}

Providing Follow-up Suggestions in Copilot Chat

First let's implement a provider that implements the vscode.ChatFollowupProvider interface. We care about the provideFollowups method, which results a ChatResult, a ChatContext and a CancellationToken.

export interface ChatFollowupProvider {
		/**
		 * Provide followups for the given result.
		 * @param result This object has the same properties as the result returned from the participant callback, including `metadata`, but is not the same instance.
		 * @param token A cancellation token.
		 */
		provideFollowups(result: ChatResult, context: ChatContext, token: CancellationToken): ProviderResult<ChatFollowup[]>;
	}

Let's first implement the provider, we will return three suggestions picked from a list of prompts randomly. The three follow-ups are all the same, but one is without a command, and the other two are for likeapirate and likeyoda commands.

Since we skip the optional participant property, the follow-up will be sent to the same participant, but if this property is defined then the prompt will be sent to another participant

Note

Follow-ups can only invoke a participant that was contributed by the same extension.

Create a file (e.g., followup.ts) and add the following code:

import * as vscode from 'vscode';

const likeFeedbackList = [
    "How Can I write my own VS Code extension?",
    "I Love VS Code",
    "I Love GitHub Copilot",
    "GitHub Copilot Extensions are so cool"
];

export function generateFollowups(): vscode.ChatFollowup[] | undefined {
    // Get a random prompt from the list
    const randomPrompt = likeFeedbackList[Math.floor(Math.random() * likeFeedbackList.length)];

    const followups: vscode.ChatFollowup[] = [
        {
            label: `🦜Parrot '${randomPrompt}'`,
            prompt: randomPrompt,
            command: ""
        },
        {
            label: `🦜Parrot '${randomPrompt}' like a pirate`,
            prompt: randomPrompt,
            command: "likeapirate"
        },
        {
            label: `🦜Parrot '${randomPrompt}' like Yoda`,
            prompt: randomPrompt,
            command: "likeyoda"
        }
    ];

    return followups;
}

Now that we have our follow-up provider all we are missing is registering it. open extension.ts and add the following code inside the active method:

participant.followupProvider = { provideFollowups: generateFollowups };

add at the top of the file the import statement for the follow-up provider:

import { generateFollowups } from './followup';

That's it! Now when you run your extension and generate a response, you should see the follow-up suggestions appear in the Copilot Chat interface.

parrot follow-ups

As an exercise, try implementing a more sophisticated follow-up provider that leverages the Copilot AI API to generate contextually relevant suggestions based on the user's prompt. You can apply the techniques and principles discussed in the Integrating an LLM into a VS Code Extension post to create dynamic and intelligent follow-up prompts. This will allow your extension to offer more tailored and helpful suggestions, further enhancing the user experience.

References

Next In Series

Next: Getting feedback on responses for our chat parrot.