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.
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.PromptByLocation→Find assets by [Location]Topic.PromptByTechnician→Show me assets assigned to [Technician Name]Topic.PromptExpiringWarranty→List 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.
[
{
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:
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:
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:
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 theRequestSparksevent and overwrite your changes. - Variable Names – The global variables
PA_Copilot_Sparks.sparkGroupsandPA_Copilot_Sparks.sparksare case‑sensitive. A typo will silently fail. - Multiple Groups – To add more than one group, add more objects to the
Topic.PromptGroupTablearray. Each object can have its ownentityNameandsparkslist. - 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
- Original article by Matthew Devaney: Customize The Model-Driven Apps Copilot Prompt Library
- Microsoft Learn: Customize Chat in Model-Driven Apps with Copilot
Learn how small coding practices—like using descriptive names, flattening conditions, and simplifying logic—can make your apps easier to update and less error-prone.
Move past the gallery and discover the hidden patterns for validation, navigation, and smart submission handling in your data entry forms.
PowerShell unlocks admin capabilities that the Power Platform admin center simply doesn’t offer—from recovering deleted apps to blocking trial licenses. Here’s how to wield them safely.