Tutorials/Power Apps/Build Custom Prompt Groups for Your Model-Driven App Copilot
Power Appsintermediate

Build Custom Prompt Groups for Your Model-Driven App Copilot

Add targeted prompt suggestions to your Copilot chat to help users quickly access records and data.

NA
Narmer Abader
@narmer · Published June 3, 2026

The prompt library inside a model-driven app Copilot can be extended with your own groups and prompts. Instead of users always typing from scratch, you can surface ready‑made questions that are common in your business. This guide walks through creating a new topic in Copilot Studio that listens for the RequestSparks event and injects custom prompts into the library.

Example Scenario

Imagine you have a model-driven app used by field technicians to manage asset inventory. You want the Copilot to suggest these prompts:

  • Find assets by [Location]
  • Show me assets assigned to [Technician Name]
  • List assets with warranty expiring in [Month Year]

All three prompts will appear under a new group named Asset Queries.

Step‑by‑Step Implementation

1. Open Your App’s Copilot Agent

In your model-driven app, go to the Agents menu and select Edit App Assistant Agent. This opens the associated Copilot Studio agent.

2. Create a New Topic

Add a new topic and name it, for example, “Custom Prompt Library Injector.” Change the trigger type to When a custom client event occurs.

In the event name field enter:

Microsoft.PowerApps.Copilot.RequestSparks

Set the Priority to 9999. A high number ensures your topic runs after the default topics.

3. Define Variables for Prompts and Group Name

Create a Text variable to hold the group name:

  • Variable: Topic.AssetGroupName
  • Value: Asset Queries

Create one Text variable for each prompt:

  • Topic.PromptByLocationFind assets by [Location]
  • Topic.PromptByTechnicianShow me assets assigned to [Technician Name]
  • Topic.PromptExpiringWarrantyList assets with warranty expiring in [Month Year]

4. Build the Prompt Group Table

Create a Table variable named Topic.PromptGroupTable. Set its value with the following formula. This table contains one group with the three prompts.

powerfxTopic.PromptGroupTable definition
[
{
  entityName: "",
  displayName: Topic.AssetGroupName,
  displaySubtitle: Topic.AssetGroupName,
  iconName: "box24Regular",
  sparks: [
    {
      displayName: Topic.PromptByLocation,
      type: "PromptText"
    },
    {
      displayName: Topic.PromptByTechnician,
      type: "PromptText"
    },
    {
      displayName: Topic.PromptExpiringWarranty,
      type: "PromptText"
    }
  ]
}
]

The entityName field is optional – when left blank, the group always appears. If you supply an entity logical name, the group only shows when the Copilot has context for that entity.

5. Build the Filtered Group List

Create another Table variable named Topic.PromptGroups. Set its value to:

powerfxTopic.PromptGroups filtered list
ForAll(
  Filter(
      Topic.PromptGroupTable,
      IsBlank(ThisRecord.entityName)
      || (!IsBlank(Global.PA_Copilot_EntityContext)
          && ThisRecord.entityName in DropColumns(Global.PA_Copilot_EntityContext, DisplayName, Description)
      )
  ),
  ThisRecord
)

This step is optional if your groups always have an empty entityName.` It ensures that groups targeting specific entities appear only when the appropriate record is in focus.

6. Merge into the Global Sparks Variables

The two platform‑controlled variables that hold the library’s contents are Global.PA_Copilot_Sparks.sparkGroups and Global.PA_Copilot_Sparks.sparks. You need to append your new group and prompts to whatever is already stored in these globals.

Use a Set variable value node to update Global.PA_Copilot_Sparks.sparkGroups:

powerfxAppend spark groups
With(
  {groups: CountRows(Global.PA_Copilot_Sparks.sparkGroups)},
  ForAll(
      Sequence(groups + CountRows(Topic.PromptGroups)),
      If(
          Value <= groups,
          Index(Global.PA_Copilot_Sparks.sparkGroups, Value),
          Index(Topic.PromptGroups, Value - groups)
      )
  )
)

Similarly, update Global.PA_Copilot_Sparks.sparks:

powerfxAppend sparks
With(
  {groups: CountRows(Global.PA_Copilot_Sparks.sparks)},
  ForAll(
      Sequence(groups + CountRows(Topic.PromptGroupTable)),
      If(
          Value <= groups,
          Index(Global.PA_Copilot_Sparks.sparks, Value),
          Index(Topic.PromptGroupTable, Value - groups)
      )
  )
)

Both formulas work by counting the existing rows in the global variable and then concatenating the new rows via an indexed sequence.

7. Publish and Test

Save the topic and Publish the Copilot Studio agent. Go back to your model-driven app and open the Copilot chat. The prompt library should now display the “Asset Queries” group with the three predefined prompts.

Selecting a prompt places it in the chat input with placeholders ([Location], [Technician Name], etc.) ready for the user to fill in.

Considerations & Common Mistakes

  • Priority Matters – If you don’t set a high priority (9999), another topic might handle the RequestSparks event and overwrite your changes.
  • Variable Names – The global variables PA_Copilot_Sparks.sparkGroups and PA_Copilot_Sparks.sparks are case‑sensitive. A typo will silently fail.
  • Multiple Groups – To add more than one group, add more objects to the Topic.PromptGroupTable array. Each object can have its own entityName and sparks list.
  • Performance – The merge logic runs quickly because it only handles tables in memory. No performance issues are expected.
  • Security – Prompts themselves don’t elevate privileges; they are just text templates. However, the Copilot’s responses still respect the user’s security roles.

Final Recommendation

Extending the prompt library is a lightweight way to guide users toward common queries. Start with a small set of prompts your team actually uses, and iterate based on feedback. Using the entityName filter can make prompts context‑aware, but keep it simple at first.

References