Recap: What is an assistant?
In the previous post https://community.dynamics.com/business/b/jesusalmarazblog/posts/business-central-warehouse-chat-with-luis we defined an assistant and created an assistant with LUIS. An assistant is a tool that convert natural language in these two elements:
- Intents: Is an action that user intend to be done. “Open the order” (=find an order with some criteria), “Tell me the needs” (=with an already selected order give me the list of its components).
- Entity: The data related with the intent and needed to complete the action defined in this intent (order number or order output item name).
Publish and consume
To use a LUIS assistant App from outside we must publish it. We can see our API end point in the App-Manage-Azure Resources:
The access point URL have these components:
- https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/{Application-Id}?verbose=true&timezoneOffset=0&subscription-key={Primary-key}&q= {Natural language sentence input}
This service breaks Natural language into a JSON with the intents and entities. If we send the GET request:
- https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/{Application-Id}?verbose=true&timezoneOffset=0&subscription-key={Primary-key}&q=Open the order of mountain bike , we have the response with intents and entities breakdown (Intent=”Open Order”, Entity name=”Output Item Name” and Entity value=”mountain bike”):
"topIntent": "Open Order",
"intents": {
"Open Order": {
"score": 0.999999344
}
},
"entities": {
"Output item name": [
"mountain bike"
We can process this JSON to access to BC database and build an intelligent response, searching the order with this output item description:
AssemblyHeader.SetFilter(Description, '@*' + EntityValue + '*');
The Business Central side
We create a new page “Assembly Assistant” cloning the assembly order list, adding two text boxes:
- Input text: We set the focus in the input text box and activate the microphone, and we can chat with Business Central to pick the components lots of the assembly order.
- Response. This multiline text box will show us the log of the conversation with BC in chat mode (newer at the top).
To show a chat example we reverse the “Response box” order to older in top:
You: Open order of Paquete de conferencia. (You ask for the assembly order of item called “Paquete de conferencia”).
Business Central: OP-121 Paquete de conferencia 1-6. (BC find the order and show you order number and complete description).
You: tell me the needs (You ask for order components information).
Business Central: Mesa de conferencia AMBERES (BC display component names).
Business Central: Silla giratoria MÉXICO, negra
You: Begin scan lots (You tell BC you are going to scan lots).
Business Central: Scanning Lots (BC tell you it got the intent and is ready to receive lots numbers. You active the scan and read component lot numbers in barcode).
Code breakdown
The AL Code is in this repository:
We have done the LUIS part, not the scanning lots parts, but you know how can it be done: search lot numbers in order item components and create reservation entries related to the assembly line table. Aside this part, we can highlight these other parts:
HTTP call with GET:
procedure GetLUISPredicition(InputText: Text) TextoResponse: Text
var
HttpClient: HttpClient;
Request: HttpRequestMessage;
Response: HttpResponseMessage;
url: Text;
begin
url := StrSubstNo(AppUrl, GetLUISAppID(), GetLUISSubsKey(), InputText);
Request.Method('GET');
Request.SetRequestUri(url);
HttpClient.Send(Request, Response);
Response.Content.ReadAs(TextoResponse);
end;
Break JSON into intents and entities:
The return of previous Http call is a JSON string. We manage this string to extract Intents and entities. I get the main intent with this code. The main intent is the most possible intent detected in the sentence by LUIS:
procedure GetMainIntent(ResponseText: Text) IntentName: Text
var
JSONBuffer: Record "JSON Buffer" temporary;
begin
with JSONBuffer do begin
ReadFromText(ResponseText);
SetRange(Path, IntentPathFilter);
SetRange("Token type", "Token type"::String);
if not FindFirst() then
error(ErrNoIntent);
IntentName := Value;
end;
end;
The entity search code is very similar, but using and index value to get an entity in a set of them (We have also a very similar function to get the entity name called “GetEntityName”, but I didn´t want to make longer the code part):
local procedure GetEntityValue(ResponseLuisText: Text; Index: Integer): text[250]
var
JSONBuffer: Record "JSON Buffer" temporary;
begin
with JSONBuffer do begin
ReadFromText(ResponseLuisText);
Reset();
SetRange(Path, StrSubstNo(EntityPathValueFilter, Index));
SetRange("Token type", "Token type"::String);
if FindFirst() then
exit(Value);
end;
end;
The next step is process the intents with their related entities: when I already get the intent and entities we can process them to access database and give the user an output: Once we have got the intent, if the Intent is “Open Assembly Order” we read in the response the entity name and value with this function:
local procedure OpenOrder(ResponseLUISText: text; var AssemblyHeader: Record "Assembly Header")
var
JSONBuffer: Record "JSON Buffer" temporary;
EntityName: text[250];
EntityValue: Text[250];
begin
EntityName := GetEntityName(ResponseLUISText, 0);
EntityValue := GetEntityValue(ResponseLUISText, 0);
AssemblyHeader.Reset();
case EntityName of
GetOrderNumberEntity():
AssemblyHeader.SetFilter("No.", '*' + EntityValue);
GetProductNameEntity():
AssemblyHeader.SetFilter(Description, '@*' + EntityValue + '*');
else
Error(ErrNoEntity);
end;
AssemblyHeader.FindFirst();
end;
This way we can return to the user the number and description of the order in the response text box of the page and wait for the next sentence of the user. He can ask for the components or begin to scan lots and BC will keep on breaking the sentences in intents and entities with LUIS service, and so on.
Final recap.
When we talk about assistant the main concepts are intents and entities. These are not the only concepts involved in an assistant, then even can keep the state of a conversation. The assistant convert a natural language input in a serialized data that machines can understand and process. The value of this is to allow user interaction through easier ways.
*This post is locked for comments