Skip to content

Commit 3f6da33

Browse files
gtewksburyTom Laird-McConnell
authored andcommitted
updated the LUIS TryFindEntity extension to only return an entity by … (microsoft#4509)
* updated the LUIS TryFindEntity extension to only return an entity by type if its start index doesn't overlap with the start and end index of other LuisResult Entities. I came across this issue when working with an intent that accepts both a date and number. If the intent message is 'make a reservation tomorrow morning at 2 for 7 people', 7 being the trained 'number' in LUIS, the current TryFindEntity extension was pulling back '2', which was already considered part of the datetime entity * added unit tests and correctet and updated logic to only consider an overlap if start and end index are within another entity recommendation
1 parent 699d68f commit 3f6da33

File tree

3 files changed

+101
-1
lines changed

3 files changed

+101
-1
lines changed

CSharp/Library/Microsoft.Bot.Builder/Luis/Extensions.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,16 @@ public static partial class Extensions
5353
/// <returns>True if the entity was found, false otherwise.</returns>
5454
public static bool TryFindEntity(this LuisResult result, string type, out EntityRecommendation entity)
5555
{
56-
entity = result.Entities?.FirstOrDefault(e => e.Type == type);
56+
Func<EntityRecommendation, IList<EntityRecommendation>, bool> doesNotOverlapRange = (current, recommendations) =>
57+
{
58+
return !recommendations.Where(r => current != r)
59+
.Any(r => r.StartIndex.HasValue && r.EndIndex.HasValue && current.StartIndex.HasValue &&
60+
r.StartIndex.Value <= current.StartIndex.Value && r.EndIndex.Value >= current.EndIndex.Value);
61+
};
62+
63+
64+
// find the recommended entity that does not overlap start and end ranges with other result entities
65+
entity = result.Entities?.Where(e => e.Type == type && doesNotOverlapRange(e, result.Entities)).FirstOrDefault();
5766
return entity != null;
5867
}
5968

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using Microsoft.Bot.Builder.Luis.Models;
2+
using System.Collections.Generic;
3+
using Microsoft.Bot.Builder.Luis;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
6+
namespace Microsoft.Bot.Builder.Tests
7+
{
8+
[TestClass]
9+
public class LuisTryFindEntityTests
10+
{
11+
12+
[TestMethod]
13+
public void Luis_TryFindEntity_Date_And_Multiple_Numbers_Where_One_Number_Overlaps()
14+
{
15+
// assemble
16+
17+
var recommendations = new List<EntityRecommendation>
18+
{
19+
new EntityRecommendation { Type = "builtin.datetimeV2.time", Entity = "10 pm", StartIndex=25, EndIndex=30},
20+
new EntityRecommendation { Type = "builtin.number", Entity = "10", StartIndex=25, EndIndex=27},
21+
new EntityRecommendation { Type = "builtin.number", Entity = "8", StartIndex=35, EndIndex=36}
22+
};
23+
24+
var result = new LuisResult("make me a reservation at 10 pm for 8 people", recommendations);
25+
26+
// act
27+
28+
EntityRecommendation recommendation;
29+
result.TryFindEntity("builtin.number", out recommendation);
30+
31+
// assert
32+
33+
Assert.IsNotNull(recommendation,"entity recommendation not found");
34+
Assert.AreEqual("8", recommendation.Entity, "wrong entity recommendation selected"); // it should not select 10 since that overlaps with the datetime entity
35+
}
36+
37+
[TestMethod]
38+
public void Luis_TryFindEntity_Date_And_One_Number_Where_One_Number_Overlaps()
39+
{
40+
// assemble
41+
42+
var recommendations = new List<EntityRecommendation>
43+
{
44+
new EntityRecommendation { Type = "builtin.number", Entity = "10", StartIndex=25, EndIndex=27}, // it should not consider this a number since if overlaps with the datetime entity
45+
new EntityRecommendation { Type = "builtin.datetimeV2.time", Entity = "10 pm", StartIndex=25, EndIndex=30}
46+
};
47+
48+
var result = new LuisResult("make me a reservation at 10 pm", recommendations);
49+
50+
// act
51+
52+
EntityRecommendation numberRecommendation;
53+
result.TryFindEntity("builtin.number", out numberRecommendation);
54+
55+
EntityRecommendation timeRecommendation;
56+
result.TryFindEntity("builtin.datetimeV2.time", out timeRecommendation);
57+
58+
59+
// assert
60+
61+
Assert.IsNotNull(timeRecommendation, "time entity recommendation not found");
62+
Assert.IsNull(numberRecommendation, "number recommendation should be null as it falls within the datetime range");
63+
Assert.AreEqual("10 pm", timeRecommendation.Entity, "wrong entity recommendation selected");
64+
}
65+
66+
[TestMethod]
67+
public void Luis_TryFindEntity_Find_Number_No_Overlaps()
68+
{
69+
// assemble
70+
71+
var recommendations = new List<EntityRecommendation>
72+
{
73+
new EntityRecommendation { Type = "builtin.number", Entity = "8", StartIndex=26, EndIndex=27},
74+
};
75+
76+
var result = new LuisResult("make me a reservation for 8 people", recommendations);
77+
78+
// act
79+
80+
EntityRecommendation numberRecommendation;
81+
result.TryFindEntity("builtin.number", out numberRecommendation);
82+
83+
84+
// assert
85+
86+
Assert.IsNotNull(numberRecommendation, "number recommendation not found");
87+
Assert.AreEqual("8", numberRecommendation.Entity, "wrong entity recommendation selected");
88+
}
89+
}
90+
}

CSharp/Tests/Microsoft.Bot.Builder.Tests/Microsoft.Bot.Builder.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
<Compile Include="DialogTaskManagerTests.cs" />
103103
<Compile Include="DialogTaskTests.cs" />
104104
<Compile Include="DialogTestBase.cs" />
105+
<Compile Include="LuisTryFindEntityTests.cs" />
105106
<Compile Include="FormTests.cs" />
106107
<Compile Include="OrderedContractResolver.cs" />
107108
<Compile Include="PromptRecognizerTests.cs" />

0 commit comments

Comments
 (0)