Member in entity class not created correctly using bf luis:generate:cs #1281
Description
Versions
BF-CLI: @microsoft/botframework-cli/4.14.1 win32-x64 node-v14.6.0
NodeJs: v14.6.0
CommandLine: Git Bash
OS: Windows 10
Describe the bug
When creating the c# class of a luis app the botframework-cli does not create entity classes of ML entities containig subentities correctly in some cases.
To Reproduce
Take this exported luis app:
{
"luis_schema_version": "7.0.0",
"intents": [
{
"name": "DeviceIntent",
"features": []
},
{
"name": "None",
"features": []
}
],
"entities": [
{
"name": "Device",
"children": [
{
"name": "DeviceName",
"children": [],
"features": [
{
"modelName": "DeviceName",
"isRequired": false
}
]
},
{
"name": "Number",
"children": [],
"features": [
{
"modelName": "number",
"isRequired": false
}
]
}
],
"roles": [],
"features": []
},
{
"name": "ObjectEntity",
"children": [
{
"name": "number",
"children": [],
"features": [
{
"modelName": "number",
"isRequired": true
}
]
},
{
"name": "name",
"children": [],
"features": [
{
"modelName": "ObjectName",
"isRequired": true
}
]
}
],
"roles": [],
"features": []
}
],
"hierarchicals": [],
"composites": [],
"closedLists": [
{
"name": "DeviceName",
"subLists": [
{
"canonicalForm": "abc",
"list": [
"AbC"
]
},
{
"canonicalForm": "fgh",
"list": [
"FGH"
]
}
],
"roles": []
},
{
"name": "ObjectName",
"subLists": [
{
"canonicalForm": "Name1",
"list": [
"name 1",
"name one"
]
},
{
"canonicalForm": "Name2",
"list": [
"name 2",
"name two"
]
}
],
"roles": []
}
],
"prebuiltEntities": [
{
"name": "number",
"roles": []
}
],
"utterances": [
{
"text": "it is device abc 1",
"intent": "DeviceIntent",
"entities": [
{
"entity": "Device",
"startPos": 13,
"endPos": 17,
"children": [
{
"entity": "Number",
"startPos": 17,
"endPos": 17,
"children": []
},
{
"entity": "DeviceName",
"startPos": 13,
"endPos": 15,
"children": []
}
]
}
]
},
{
"text": "it's device fgh 2",
"intent": "DeviceIntent",
"entities": [
{
"entity": "Device",
"startPos": 12,
"endPos": 16,
"children": [
{
"entity": "Number",
"startPos": 16,
"endPos": 16,
"children": []
},
{
"entity": "DeviceName",
"startPos": 12,
"endPos": 14,
"children": []
}
]
}
]
},
{
"text": "object name one 3 times",
"intent": "DeviceIntent",
"entities": [
{
"entity": "ObjectEntity",
"startPos": 7,
"endPos": 16,
"children": [
{
"entity": "number",
"startPos": 16,
"endPos": 16,
"children": []
},
{
"entity": "name",
"startPos": 7,
"endPos": 14,
"children": []
}
]
}
]
},
{
"text": "the object is name1 18 times",
"intent": "DeviceIntent",
"entities": [
{
"entity": "ObjectEntity",
"startPos": 14,
"endPos": 21,
"children": [
{
"entity": "number",
"startPos": 20,
"endPos": 21,
"children": []
},
{
"entity": "name",
"startPos": 14,
"endPos": 18,
"children": []
}
]
}
]
},
{
"text": "the objects name is name two 123 times",
"intent": "DeviceIntent",
"entities": [
{
"entity": "ObjectEntity",
"startPos": 20,
"endPos": 31,
"children": [
{
"entity": "number",
"startPos": 29,
"endPos": 31,
"children": []
},
{
"entity": "name",
"startPos": 20,
"endPos": 27,
"children": []
}
]
}
]
}
],
"versionId": "0.1",
"name": "MyTest",
"desc": "",
"culture": "de-de",
"tokenizerVersion": "1.0.2",
"patternAnyEntities": [],
"regex_entities": [],
"phraselists": [],
"regex_features": [],
"patterns": [],
"settings": []
}
Please notice the entity Device
with child DeviceName
to which the feature DeviceName
(a list entity) was assigned.
Then run bf luis:generate:cs --in app.json --out ./app.cs --className MyApp.MyLuisModel
. The command creates the file app.cs containing the class "MyLuisModel". In the nested class _Entities there are members public double[] number;
, public string[][] DeviceName;
and public DeviceClass[] Device;
. DeviceClass
looks like this:
public class DeviceClass
{
public string[][] DeviceName;
public string[] Number;
[JsonProperty("$instance")]
public _InstanceDevice _instance;
}
You can see that the member DeviceName
is of type string[][]
. If you change the child name of entity Device
from DeviceName
to Name
(or anything other than DeviceName; just change the value of property "name" in the json file at path entities[0].children[0]), then the class DeviceClass
looks like this:
public class DeviceClass
{
public string[] Name;
public string[] Number;
[JsonProperty("$instance")]
public _InstanceDevice _instance;
}
EDIT:
I've updated the Luis model and added another ML entity "ObjectEntity" consisting of sub entity "name" (required feature ObjectName) and "number" (required feature "number"). When I export the app and create the model classes, the new entity class looks like this:
public class ObjectEntityClass
{
public double[] number;
public string[] name;
[JsonProperty("$instance")]
public _InstanceObjectEntity _instance;
}
This is as expected! Well, now when I run a request using REST api the result looks like this:
{
"query": "object name 1 5 times",
"prediction": {
"topIntent": "DeviceIntent",
"intents": {
"DeviceIntent": {
"score": 0.9664061
}
},
"entities": {
"ObjectEntity": [{
"name": [
["Name1"]
],
"number": [5],
"$instance": {
"name": [{
"type": "ObjectName",
"text": "name 1",
"startIndex": 7,
"length": 6,
"score": 0.6040929,
"modelTypeId": 1,
"modelType": "Entity Extractor",
"recognitionSources": ["model"]
}],
"number": [{
"type": "builtin.number",
"text": "5",
"startIndex": 14,
"length": 1,
"score": 0.7429372,
"modelTypeId": 1,
"modelType": "Entity Extractor",
"recognitionSources": ["model"]
}]
}
}],
"number": [1],
"$instance": {
"ObjectEntity": [{
"type": "ObjectEntity",
"text": "name 1 5",
"startIndex": 7,
"length": 8,
"score": 0.6226765,
"modelTypeId": 1,
"modelType": "Entity Extractor",
"recognitionSources": ["model"]
}],
"number": [{
"type": "builtin.number",
"text": "1",
"startIndex": 12,
"length": 1,
"modelTypeId": 2,
"modelType": "Prebuilt Entity Extractor",
"recognitionSources": ["model"]
}]
}
}
}
}
Have a close look at the extracted entity:
"entities": {
"ObjectEntity": [{
"name": [
["Name1"]
],
"number": [5],
You'll see that the sub entity is of type string[][]
which leads to an JSON exception in the code because string[]
is expected.
End of edit
Expected behavior
DeviceName
in class DeviceClass
is of type string[]
.
[bug]