Skip to content
This repository was archived by the owner on Jan 15, 2025. It is now read-only.

Commit 6c44b9b

Browse files
author
Vishwac Sena Kannan
committed
Updates to JSON -> LU for phrase list features
1 parent c959b47 commit 6c44b9b

File tree

5 files changed

+185
-9
lines changed

5 files changed

+185
-9
lines changed

packages/luis/src/parser/converters/luistoluconverter.js

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,16 @@ module.exports = {
9898
fileContent += NEWLINE + NEWLINE;
9999
}
100100
fileContent += `@ simple ${entity.name}`;
101-
if (entity.roles.length > 0) {
102-
fileContent += ` ${entity.roles.length > 1 ? `hasRoles` : `hasRole`} ${entity.roles.join(',')}`
101+
if (entity.roles && entity.roles.length > 0) {
102+
fileContent += ` ${entity.roles.length > 1 ? `hasRoles` : `hasRole`} ${entity.roles.join(',')}`;
103+
}
104+
if (entity.features && entity.features.length > 0) {
105+
let featuresList = new Array();
106+
entity.features.forEach(item => {
107+
if (item.featureName) featuresList.push(item.featureName);
108+
if (item.modelName) featuresList.push(item.modelName);
109+
})
110+
fileContent += ` ${featuresList.length > 1 ? `usesFeatures` : `usesFeature`} ${featuresList.join(',')}`;
103111
}
104112
fileContent += NEWLINE + NEWLINE;
105113
});
@@ -110,9 +118,17 @@ module.exports = {
110118
fileContent += '> # PREBUILT Entity definitions' + NEWLINE + NEWLINE;
111119
LUISJSON.prebuiltEntities.forEach(function(entity) {
112120
fileContent += `@ prebuilt ${entity.name}`;
113-
if (entity.roles.length > 0) {
121+
if (entity.roles && entity.roles.length > 0) {
114122
fileContent += ` ${entity.roles.length > 1 ? `hasRoles` : `hasRole`} ${entity.roles.join(',')}`;
115123
}
124+
if (entity.features && entity.features.length > 0) {
125+
let featuresList = new Array();
126+
entity.features.forEach(item => {
127+
if (item.featureName) featuresList.push(item.featureName);
128+
if (item.modelName) featuresList.push(item.modelName);
129+
})
130+
fileContent += ` ${featuresList.length > 1 ? `usesFeatures` : `usesFeature`} ${featuresList.join(',')}`;
131+
}
116132
fileContent += NEWLINE + NEWLINE;
117133
});
118134
fileContent += NEWLINE;
@@ -122,7 +138,7 @@ module.exports = {
122138
fileContent += '> # Phrase list definitions' + NEWLINE + NEWLINE;
123139
LUISJSON.model_features.forEach(function(entity) {
124140
fileContent += `@ phraselist ${entity.name}${(entity.mode ? `(interchangeable)` : ``)}`;
125-
if (entity.words !== '') {
141+
if (entity.words && entity.words !== '') {
126142
fileContent += ` = ${NEWLINE}\t- ${entity.words}`;
127143
}
128144
fileContent += NEWLINE + NEWLINE;
@@ -133,9 +149,17 @@ module.exports = {
133149
fileContent += '> # List entities' + NEWLINE + NEWLINE;
134150
LUISJSON.closedLists.forEach(function(ListItem) {
135151
fileContent += `@ list ${ListItem.name}`;
136-
if (ListItem.roles.length > 0) {
152+
if (ListItem.roles && ListItem.roles.length > 0) {
137153
fileContent += ` ${ListItem.roles.length > 1 ? `hasRoles` : `hasRole`} ${ListItem.roles.join(',')}`;
138154
}
155+
if (ListItem.features && ListItem.features.length > 0) {
156+
let featuresList = new Array();
157+
ListItem.features.forEach(item => {
158+
if (item.featureName) featuresList.push(item.featureName);
159+
if (item.modelName) featuresList.push(item.modelName);
160+
})
161+
fileContent += ` ${featuresList.length > 1 ? `usesFeatures` : `usesFeature`} ${featuresList.join(',')}`;
162+
}
139163
if (ListItem.subLists.length !== 0) {
140164
fileContent += ` = `;
141165
fileContent += NEWLINE;
@@ -155,9 +179,17 @@ module.exports = {
155179
fileContent += '> # RegEx entities' + NEWLINE + NEWLINE;
156180
LUISJSON.regex_entities.forEach(function(regExEntity) {
157181
fileContent += `@ regex ${regExEntity.name}`;
158-
if (regExEntity.roles.length > 0) {
182+
if (regExEntity.roles && regExEntity.roles.length > 0) {
159183
fileContent += ` ${regExEntity.roles.length > 1 ? `hasRoles` : `hasRole`} ${regExEntity.roles.join(',')}`;
160184
}
185+
if (regExEntity.features && regExEntity.features.length > 0) {
186+
let featuresList = new Array();
187+
regExEntity.features.forEach(item => {
188+
if (item.featureName) featuresList.push(item.featureName);
189+
if (item.modelName) featuresList.push(item.modelName);
190+
})
191+
fileContent += ` ${featuresList.length > 1 ? `usesFeatures` : `usesFeature`} ${featuresList.join(',')}`;
192+
}
161193
if (regExEntity.regexPattern !== '') {
162194
fileContent += ` = /${regExEntity.regexPattern}/`;
163195
}
@@ -171,9 +203,17 @@ module.exports = {
171203
fileContent += '> # Composite entities' + NEWLINE + NEWLINE;
172204
LUISJSON.composites.forEach(composite => {
173205
fileContent += `@ composite ${composite.name}`;
174-
if (composite.roles.length > 0) {
206+
if (composite.roles && composite.roles.length > 0) {
175207
fileContent += ` ${composite.roles.length > 1 ? `hasRoles` : `hasRole`} ${composite.roles.join(',')}`;
176208
}
209+
if (composite.features && composite.features.length > 0) {
210+
let featuresList = new Array();
211+
composite.features.forEach(item => {
212+
if (item.featureName) featuresList.push(item.featureName);
213+
if (item.modelName) featuresList.push(item.modelName);
214+
})
215+
fileContent += ` ${featuresList.length > 1 ? `usesFeatures` : `usesFeature`} ${featuresList.join(',')}`;
216+
}
177217
if (composite.children.length > 0) {
178218
fileContent += ` = [${composite.children.join(', ')}]`;
179219
}

packages/luis/src/parser/lufile/parseFileContents.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ const parseFeatureSections = function(parsedContent, featuresToProcess) {
170170
// verify the list of features requested have all been defined.
171171
let featuresList = section.Features.split(/[,;]/g).map(item => item.trim());
172172
(featuresList || []).forEach(feature => {
173-
let entityExists = (parsedContent.LUISJsonStructure.flatListOfEntityAndRoles || []).find(item => item.name == feature);
173+
let entityExists = (parsedContent.LUISJsonStructure.flatListOfEntityAndRoles || []).find(item => item.name == feature || item.name == `${feature}(interchangeable)`);
174174
if (entityExists) {
175175
if (entityExists.type === EntityTypeEnum.PHRASELIST) {
176176
// de-dupe and add features to intent.
@@ -212,7 +212,7 @@ const parseFeatureSections = function(parsedContent, featuresToProcess) {
212212
let entityExists = (parsedContent.LUISJsonStructure.flatListOfEntityAndRoles || []).find(item => item.name == section.Name);
213213
let entityType = undefined;
214214
if (entityExists) entityType = entityExists.type;
215-
let featureExists = (parsedContent.LUISJsonStructure.flatListOfEntityAndRoles || []).find(item => item.name == feature);
215+
let featureExists = (parsedContent.LUISJsonStructure.flatListOfEntityAndRoles || []).find(item => item.name == feature || item.name == `${feature}(interchangeable)`);
216216
if (featureExists) {
217217
// find the entity based on its type.
218218
let entityFound = (parsedContent.LUISJsonStructure[luisEntityTypeMap[entityType]] || []).find(item => item.name == section.Name);

packages/luis/test/commands/luis/convert.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ describe('luis:convert', () => {
4646
expect(await compareLuFiles('./../../../root.lu', './../../fixtures/verified/allGen.lu')).to.be.true
4747
})
4848

49+
test
50+
.stdout()
51+
.command(['luis:convert', '--in', `${path.join(__dirname, './../../fixtures/verified/plFeatures.json')}`, '--out', 'root.lu'])
52+
.it('luis:convert successfully reconstructs a markdown file from a LUIS input file', async () => {
53+
expect(await compareLuFiles('./../../../root.lu', './../../fixtures/verified/plFeatures.lu')).to.be.true
54+
})
55+
4956
test
5057
.stdout()
5158
.command(['luis:convert', '--in', `${path.join(__dirname, './../../fixtures/examples/1.lu')}`, '--out', 'root.json', '--name', '1'])
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
{
2+
"luis_schema_version": "5.0.0",
3+
"versionId": "0.1",
4+
"name": "AppName",
5+
"desc": "",
6+
"culture": "en-us",
7+
"tokenizerVersion": "1.0.0",
8+
"intents": [
9+
{
10+
"name": "None"
11+
},
12+
{
13+
"name": "intent1",
14+
"features": [
15+
{
16+
"featureName": "phraselist1"
17+
}
18+
]
19+
}
20+
],
21+
"entities": [
22+
{
23+
"name": "simple1",
24+
"children": [],
25+
"roles": [],
26+
"features": [
27+
{
28+
"featureName": "phraselist1"
29+
}
30+
]
31+
}
32+
],
33+
"hierarchicals": [
34+
{
35+
"name": "hierarchical",
36+
"children": [
37+
{
38+
"name": "hier_child1"
39+
},
40+
{
41+
"name": "hier_child2"
42+
}
43+
],
44+
"features": [
45+
{
46+
"modelName": "simple"
47+
},
48+
{
49+
"featureName": "phraselist1"
50+
}
51+
]
52+
}
53+
],
54+
"composites": [
55+
{
56+
"name": "composite1",
57+
"children": [
58+
"simple1",
59+
"age"
60+
],
61+
"features": [
62+
{
63+
"featureName": "phraselist1"
64+
}
65+
],
66+
"roles": []
67+
}
68+
],
69+
"closedLists": [],
70+
"patternAnyEntities": [],
71+
"regex_entities": [],
72+
"prebuiltEntities": [
73+
{
74+
"name": "age",
75+
"roles": [],
76+
"features": [
77+
{
78+
"featureName": "phraselist1"
79+
}
80+
]
81+
}
82+
],
83+
"model_features": [
84+
{
85+
"name": "phraselist1",
86+
"mode": true,
87+
"words": "who,why,where,what",
88+
"activated": true,
89+
"enabledForAllModels": false
90+
}
91+
],
92+
"regex_features": [],
93+
"patterns": [],
94+
"utterances": [],
95+
"settings": []
96+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
> # Intent definitions
3+
4+
## None
5+
6+
7+
## intent1
8+
9+
10+
> # Entity definitions
11+
12+
@ simple simple1 usesFeature phraselist1
13+
14+
15+
> # PREBUILT Entity definitions
16+
17+
@ prebuilt age usesFeature phraselist1
18+
19+
20+
> # Phrase list definitions
21+
22+
@ phraselist phraselist1(interchangeable) =
23+
- who,why,where,what
24+
25+
26+
> # List entities
27+
28+
> # RegEx entities
29+
30+
31+
> # Composite entities
32+
33+
@ composite composite1 usesFeature phraselist1 = [simple1, age]

0 commit comments

Comments
 (0)