Microsoft Copilot Studio is amazing. It’s like a bottomless lake where you could swim getting down and down and keep discovering wonderous pearls. In one of my latest posts I was discussing about the capabilities of Copilot studio to talk to D365F&O using simple techniques like Copilot agents based Power automate calls and analysing the responses in ChatGPT:
https://community.dynamics.com/blogs/post/?postid=792c6f1c-0bdb-ef11-a730-7c1e527e6d02
Let us talk today a further step down, where we can leverage Custom entities in our copilot Agents to respond to inputs to Copilot chat inputs.
How is the weather of Mumbai today?
The response you would get is: Average of 25 degrees Celsius, with chances of scattered rainfall, around noon.
The answer is more of a crisp weather condition description, which we can say of type: weather report. We can likewise ask questions: how old are you? And would expect answers like: 35 or 75, which is of type integral age value of a person. This is exactly Entities are doing in Copilot Studio. They store the answer type as a response. You can see a huge number of such Entities already in place by visiting: Copilot Studio >> Agents >> Settings >> Entities.
For example, we have our “Copilot for finance and operations apps” Agent >> under which clicking on Settings:
We can find from the below panel:
To see the list of Buil-in entities:
Click on ‘Add an entity to get started’.
Clicking on New Entity would give you the following option:
The first one is applicable for cases when you need a set of pre-defined options (Good, bad, very good, very bad), where as the next option, using RegEx, is more applicable for our case for identifying the vendor. Click on it to proceed. In the following screen that comes, I am defining the entity:
Look at the pattern which I have given. It’s of type: [A-Z]{4}-[0-9]{6}
Which means: the first four characters of the input could be any alphabet, followed by a hyphen and then the last six characters are numbers (ex: INMF-123456, USRT-123124, etc.)
Click on Save to continue.
The name of this topic, we are giving as, get vendor balance, and it should get triggered when asked questions like:
Get vendor balance or Can you fetch vendor balance, etc.
When the system responds like:
Where I am saving the response in a variable called vendCode which is a type of “Generic Vendor Code” entity, that we created.
In the next step, we are asking further questions like: can you tell us the legal entity or please provide the vendor legal entity:
Which it stores in a variable called companyId, which is of type Organization entity.
Finally we are passing on the input to an action (a flow), that looks like this:
This is obtaining the vendor balance from the flow and storing as a local variable called: balanceVal.
Let us take a look at what is exactly this custom Power Automate doing.
Inside the flow
The flow is getting inputs like Vendor code and the data area Id:
And then it’s calling an D365F&O OData entity action:
Which is a very simple OData action method that calculates the vendor balance by accepting the vendor code and dataAreaId:
[
SysODataActionAttribute(“GetVendBalance”, false),
SysOdataCollectionAttribute("vendAccount", Types::String),
SysOdataCollectionAttribute("DataAreaId", Types::String),
SysOdataCollectionAttribute("return", Types::real)
]
public static AmountMST GetVendBalance(str vendAccount, str DataAreaId)
{
AmountmST vendBal;
changeCompany(dataAreaId)
{
vendBal = VendTable::find(vendAccount).balanceMST();
}
return vendBal;
}
Of course, we can also interact with X++ code with Copilot by following Microsoft recommended code structure, by creating a Custom API Plugin, as well:
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/copilot/copilot-ai-plugins
But the one which is described above could be tailor-made for a vivid range of options and choices, starting from passing on simple parameters to complex data structures.
https://community.dynamics.com/blogs/post/?postid=792c6f1c-0bdb-ef11-a730-7c1e527e6d02
Let us talk today a further step down, where we can leverage Custom entities in our copilot Agents to respond to inputs to Copilot chat inputs.
What are entities in Copilot Studio?
We can compare them as data types. When you ask a question like this:How is the weather of Mumbai today?
The response you would get is: Average of 25 degrees Celsius, with chances of scattered rainfall, around noon.
The answer is more of a crisp weather condition description, which we can say of type: weather report. We can likewise ask questions: how old are you? And would expect answers like: 35 or 75, which is of type integral age value of a person. This is exactly Entities are doing in Copilot Studio. They store the answer type as a response. You can see a huge number of such Entities already in place by visiting: Copilot Studio >> Agents >> Settings >> Entities.
For example, we have our “Copilot for finance and operations apps” Agent >> under which clicking on Settings:
We can find from the below panel:
To see the list of Buil-in entities:
Click on ‘Add an entity to get started’.
Defining a vendor entity:
We would be defining a vendor entity, so that when asked: ‘What is the vendor code?’, if you reply ‘My vendor code is INMF-000001’ – it should be able to understand that INMF-000001 is the vendor code, not the entire response is the vendor code.Clicking on New Entity would give you the following option:
The first one is applicable for cases when you need a set of pre-defined options (Good, bad, very good, very bad), where as the next option, using RegEx, is more applicable for our case for identifying the vendor. Click on it to proceed. In the following screen that comes, I am defining the entity:
Look at the pattern which I have given. It’s of type: [A-Z]{4}-[0-9]{6}
Which means: the first four characters of the input could be any alphabet, followed by a hyphen and then the last six characters are numbers (ex: INMF-123456, USRT-123124, etc.)
Click on Save to continue.
Defining the topic
Let us go back to our topic and create a new topic like this:The name of this topic, we are giving as, get vendor balance, and it should get triggered when asked questions like:
Get vendor balance or Can you fetch vendor balance, etc.
When the system responds like:
Where I am saving the response in a variable called vendCode which is a type of “Generic Vendor Code” entity, that we created.
In the next step, we are asking further questions like: can you tell us the legal entity or please provide the vendor legal entity:
Which it stores in a variable called companyId, which is of type Organization entity.
Finally we are passing on the input to an action (a flow), that looks like this:
This is obtaining the vendor balance from the flow and storing as a local variable called: balanceVal.
Let us take a look at what is exactly this custom Power Automate doing.
Inside the flow
The flow is getting inputs like Vendor code and the data area Id:
And then it’s calling an D365F&O OData entity action:
Which is a very simple OData action method that calculates the vendor balance by accepting the vendor code and dataAreaId:
[
SysODataActionAttribute(“GetVendBalance”, false),
SysOdataCollectionAttribute("vendAccount", Types::String),
SysOdataCollectionAttribute("DataAreaId", Types::String),
SysOdataCollectionAttribute("return", Types::real)
]
public static AmountMST GetVendBalance(str vendAccount, str DataAreaId)
{
AmountmST vendBal;
changeCompany(dataAreaId)
{
vendBal = VendTable::find(vendAccount).balanceMST();
}
return vendBal;
}
Of course, we can also interact with X++ code with Copilot by following Microsoft recommended code structure, by creating a Custom API Plugin, as well:
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/copilot/copilot-ai-plugins
But the one which is described above could be tailor-made for a vivid range of options and choices, starting from passing on simple parameters to complex data structures.
Responding the answer to the copilot
And then we are passing the value back directly to copilot as:
Which we are obtaining back in our caller Action of Copilot and ending the conversation:
Save and publish the Topic. This will make it be available in D365F&O Copilot sidecar:
Which we are obtaining back in our caller Action of Copilot and ending the conversation:
Save and publish the Topic. This will make it be available in D365F&O Copilot sidecar:
Just see, how it's understanding not the entire response is the vendor code, but only INMF-000005 is the vendor code. If you give a wrong vendor number: it will kep asking you the same queston again and again, unless the correct input is given:
Additional considerations
- You can bring along the balance with it the currency. Consider using a List in your return type while designing the OData action method.
- You can ask vendor balance from any other legal entity, sitting on one legal entity.
- Consider using your own securities/privileges to ensure if the user is having necessary rights to inquire. The above code certainly exposes data results to an unwanted tapestry of users interacting beyond the borders of privilege limitations, which has to be handled with additional layers of securities.
*This post is locked for comments