Blog Post 6: Bonus – Building Your First Custom Copilot Plugin in X++
Introduction
In our previous posts, we explored what Copilot can do out of the box. But as D365 developers, we rarely stay "inside the box." The most exciting capability of Copilot in Finance & Operations is Extensibility.
Did you know you can teach Copilot new skills? You can write X++ code that Copilot triggers when a user asks a specific question. In this bonus post, we will walk through the architecture of a Client Plugin—a custom action that lets Copilot perform tasks inside the D365 client.
Caption: Turning your X++ logic into natural language skills.
The Concept: Client Actions
A "Client Action" allows Copilot to interact with the D365 interface based on user intent.
User says: "Take me to the release products form."
Copilot thinks: "I need a navigation plugin."
X++ executes: Your code runs and performs the navigation.
The Code: How It Works
Microsoft has introduced new classes and attributes specifically for this. You don't need to be a Python expert; you just need to know the SysCopilotChatAction class.
Here is a simplified example of what a custom "Navigation" plugin looks like in X++:
[DataContract]
[SysCopilotChatGlobalAction] // Defines this as a global action available anywhere
[SysCopilotChatActionDefinition(
identifierStr(MyCustom.NavigationPlugin),
'Navigate',
'Navigates to a specific form based on user input',
menuItemActionStr(MyNavigationMenuItem),
MenuItemType::Action)]
public final class MyNavigationPlugin extends SysCopilotChatAction
{
[DataMember('FormName')]
public str parmFormName(str _formName = formName)
{
formName = _formName;
return formName;
}
public void executeAction(SysCopilotChatActionDefinitionAttribute _actionDefinition)
{
// Your logic to open the menu item or form goes here
new MenuFunction(menuItemDisplayStr(MyTargetForm), MenuItemType::Display).run();
}
}
Key Components
Attributes: The
[SysCopilotChatActionDefinition]attribute is the "metadata" that tells Copilot what this class does. The description you write here is actually read by the AI to understand when to use this plugin.Data Contract: Input parameters (like
FormNamein the example above) are filled automatically by Copilot extracting information from the user's chat.Copilot Studio: Once you deploy this code, you register the action in Microsoft Copilot Studio (formerly Power Virtual Agents) so the chat bot knows it exists.
Caption: Connecting the "Brain" (Copilot Studio) to the "Body" (D365 X++).
Why Build Custom Plugins?
Complex Calculations: Let users ask "What is the projected margin for Item X?" and run a complex X++ price engine logic to give the answer.
Workflows: Create a skill like "Submit this purchase order for approval" that triggers a workflow via code.
Navigation: Build shortcuts for complex forms that users struggle to find.
Wrap Up
This brings our series to a close! We have gone from simple "Help" prompts to writing custom AI-driven code. The tools are in your hands—now it is time to build.