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

Commit 64a2839

Browse files
axelsrzmunozemilio
andauthored
Support for composite entities with prebuilt children (#1117)
* Support for composite entities with prebuilt children * Fixed test target Co-authored-by: Emilio Munoz <[email protected]>
1 parent 41daaf7 commit 64a2839

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed

packages/lu/src/parser/luis/luisGenBuilder.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ const buildVersion6 = function(luisApp) {
4141
try {
4242
result.intents = processIntents(luisApp.intents);
4343
result.closedLists = extractEntities(luisApp.closedLists);
44-
[result.entities, result.composites] = extractEntitiesV6(luisApp.entities, result.closedLists);
4544
result.prebuiltEntities = extractEntities(luisApp.prebuiltEntities, true);
45+
[result.entities, result.composites] = extractEntitiesV6(luisApp.entities, result.closedLists, result.prebuiltEntities);
4646
result.regex_entities = extractEntities(luisApp.regex_entities);
4747
result.patternAnyEntities = extractEntities(luisApp.patternAnyEntities);
4848
} catch (err) {
@@ -99,14 +99,16 @@ const extractEntities = function(entities, builtIn = false) {
9999
return result;
100100
}
101101

102-
const extractEntitiesV6 = function(entities, closedLists) {
102+
const extractEntitiesV6 = function(entities, closedLists, prebuiltEntitiesList) {
103103
// This method provides a simplified topological sort to
104104
// solve potential instanceOf dependecies in the v6 entities
105105

106106
const simpleEntitiesResult = [];
107107
const compositeEntitiesResult = [];
108108
const simpleEntitiesWithType = {};
109109

110+
const prebuiltEntitiesSet = new Set(prebuiltEntitiesList)
111+
110112
// Add 'closedList' entities as valid types for instanceOf
111113
closedLists.forEach(listEntity => {
112114
simpleEntitiesWithType[listEntity] = 'list'
@@ -143,6 +145,14 @@ const extractEntitiesV6 = function(entities, closedLists) {
143145
const last_type = simpleEntitiesWithType[entity.instanceOf] || entity.instanceOf;
144146
simpleEntitiesWithType[entity.name] = last_type;
145147
}
148+
// is simple with potential prebuilt
149+
if (entity.features !== undefined && Array.isArray(entity.features) && entity.features.length >= 0) {
150+
const prebuiltType = entity.features.find(element => element.isRequired && prebuiltEntitiesSet.has(element.modelName))
151+
if (prebuiltType !== undefined) {
152+
// marking the entity type for processSimpleEntity check
153+
entity.instanceOf = prebuiltType
154+
}
155+
}
146156
} else {
147157
throw CLIError("Malformed JSON: entity.children should be an array");
148158
}

packages/luis/test/commands/luis/generate/cs.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,15 @@ describe('luis:generate:cs', () => {
174174
.it('Generates class based on V6 with entity instanceOf referencing a closedList', async () => {
175175
await compareSourceFiles('../../../fixtures/generate/V6AnyEntityAsInstanceOf.cs', '../../../fixtures/generate/results/V6AnyEntityAsInstanceOf.cs')
176176
})
177+
178+
test
179+
.stdout()
180+
.command(['luis:generate:cs',
181+
'--in',
182+
`${path.join(__dirname, '../../../fixtures/generate/EntityPrebuiltType.json')}`,
183+
'--out',
184+
`${path.join(__dirname, '../../../fixtures/generate/results/EntityPrebuiltType.cs')}`])
185+
.it('Generates class based on V6 with a composite entity with a prebuilt child', async () => {
186+
await compareSourceFiles('../../../fixtures/generate/EntityPrebuiltType.cs', '../../../fixtures/generate/results/EntityPrebuiltType.cs')
187+
})
177188
})
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// <auto-generated>
2+
// Code generated by luis:generate:cs
3+
// Tool github: https://github.com/microsoft/botframework-cli
4+
// Changes may cause incorrect behavior and will be lost if the code is
5+
// regenerated.
6+
// </auto-generated>
7+
using Newtonsoft.Json;
8+
using Newtonsoft.Json.Serialization;
9+
using System;
10+
using System.Collections.Generic;
11+
using Microsoft.Bot.Builder;
12+
using Microsoft.Bot.Builder.AI.Luis;
13+
namespace Luis
14+
{
15+
public partial class : IRecognizerConvert
16+
{
17+
[JsonProperty("text")]
18+
public string Text;
19+
20+
[JsonProperty("alteredText")]
21+
public string AlteredText;
22+
23+
public enum Intent {
24+
};
25+
[JsonProperty("intents")]
26+
public Dictionary<Intent, IntentScore> Intents;
27+
28+
public class _Entities
29+
{
30+
// Simple entities
31+
public string[] MLTimeFrame;
32+
33+
// Built-in entities
34+
public Money[] money;
35+
36+
37+
// Composites
38+
public class _InstanceHotel
39+
{
40+
public InstanceData[] HotelTimeFrame;
41+
public InstanceData[] TotalAmount;
42+
}
43+
public class HotelClass
44+
{
45+
public string[] HotelTimeFrame;
46+
public string[] TotalAmount;
47+
[JsonProperty("$instance")]
48+
public _InstanceHotel _instance;
49+
}
50+
public HotelClass[] Hotel;
51+
52+
// Instance
53+
public class _Instance
54+
{
55+
public InstanceData[] Hotel;
56+
public InstanceData[] HotelTimeFrame;
57+
public InstanceData[] MLTimeFrame;
58+
public InstanceData[] TotalAmount;
59+
public InstanceData[] money;
60+
}
61+
[JsonProperty("$instance")]
62+
public _Instance _instance;
63+
}
64+
[JsonProperty("entities")]
65+
public _Entities Entities;
66+
67+
[JsonExtensionData(ReadData = true, WriteData = true)]
68+
public IDictionary<string, object> Properties {get; set; }
69+
70+
public void Convert(dynamic result)
71+
{
72+
var app = JsonConvert.DeserializeObject<>(
73+
JsonConvert.SerializeObject(
74+
result,
75+
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Error = OnError }
76+
)
77+
);
78+
Text = app.Text;
79+
AlteredText = app.AlteredText;
80+
Intents = app.Intents;
81+
Entities = app.Entities;
82+
Properties = app.Properties;
83+
}
84+
85+
private static void OnError(object sender, ErrorEventArgs args)
86+
{
87+
// If needed, put your custom error logic here
88+
Console.WriteLine(args.ErrorContext.Error.Message);
89+
args.ErrorContext.Handled = true;
90+
}
91+
92+
public (Intent intent, double score) TopIntent()
93+
{
94+
Intent maxIntent = Intent.None;
95+
var max = 0.0;
96+
foreach (var entry in Intents)
97+
{
98+
if (entry.Value.Score > max)
99+
{
100+
maxIntent = entry.Key;
101+
max = entry.Value.Score.Value;
102+
}
103+
}
104+
return (maxIntent, max);
105+
}
106+
}
107+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"intents": [],
3+
"entities": [
4+
{
5+
"name": "MLTimeFrame",
6+
"roles": []
7+
},
8+
{
9+
"name": "Hotel",
10+
"roles": [],
11+
"children": [
12+
{
13+
"name": "HotelTimeFrame",
14+
"children": [],
15+
"features": [
16+
{
17+
"modelName": "MLTimeFrame",
18+
"isRequired": false
19+
}
20+
]
21+
},
22+
{
23+
"name": "TotalAmount",
24+
"children": [],
25+
"features": [
26+
{
27+
"modelName": "money",
28+
"isRequired": true
29+
}
30+
]
31+
}
32+
]
33+
}
34+
],
35+
"composites": [],
36+
"closedLists": [],
37+
"regex_entities": [],
38+
"regex_features": [],
39+
"utterances": [],
40+
"patterns": [],
41+
"patternAnyEntities": [],
42+
"prebuiltEntities": [
43+
{
44+
"name": "money",
45+
"roles": []
46+
}
47+
],
48+
"luis_schema_version": "7.0.0",
49+
"versionId": "0.1",
50+
"name": "",
51+
"desc": "",
52+
"culture": "en-us",
53+
"phraselists": []
54+
}

0 commit comments

Comments
 (0)