Skip to content

Commit 3893f63

Browse files
committed
Convert timestamp to opt-in feature
Not convinced that we need to do this, but we can spare a few bytes in the NLU results files by only including the timestamp when requested via CLI argument.
1 parent 2be6d93 commit 3893f63

File tree

11 files changed

+49
-21
lines changed

11 files changed

+49
-21
lines changed

docs/Test.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ See [Caching speech-to-text transcriptions](#caching-speech-to-text-transcriptio
153153

154154
This is currently only used for LUIS, see the section on LUIS prebuilt entities in [Configuring prebuilt entities](LuisModelConfiguration.md#configuring-prebuilt-entities).
155155

156+
### `--timestamp`
157+
(Optional) Signals whether to add a timestamp to each NLU test result.
158+
159+
See the documentation on the [`timestamp` property](UtteranceExtensions.md#returning-timestamps-for-each-query) for more details.
160+
156161
### `-i, --include`
157162
(Optional) Path to custom NLU provider DLL. See documentation about [Specifying the include path](https://github.com/microsoft/NLU.DevOps/blob/master/docs/CliExtensions.md#specifying-the-include-path) for more details.
158163

docs/UtteranceExtensions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ When an NLU provider in NLU.DevOps returns a prediction result, the value will b
2222
```
2323
In this case, the intent confidence score was `0.99` and the text transcription confidence score was `0.95`. This is useful context when debugging false predictions, as a low confidence score may indicate that the model could be improved with more training examples. The recognized `genre` entity also includes a confidence score of `0.80`, although it should be noted that only the LUIS provider currently returns confidence score for entity types trained from examples.
2424

25-
## Labeled utterance timestamps
25+
## Returning timestamps for each query
2626

2727
When analyzing results for a set of NLU predictions, it is often important context to understand when the test was run. For example, for Dialogflow `date` and `time` entities, the service only returns a date time string, and no indication of what token(s) triggered that entity to be recognized. For example, the result from a query like `"Call a taxi in 15 minutes"` may look like the following:
2828
```json
@@ -38,7 +38,7 @@ When analyzing results for a set of NLU predictions, it is often important conte
3838
"timestamp": "2020-01-01T00:00:00-04:00"
3939
}
4040
```
41-
Without the context provided by the `timestamp` property, we wouldn't be able to make any assertion about the correctness of the `entityValue` property for time. Currently, LUIS, Lex, and Dialogflow return a timestamp for each prediction result.
41+
Without the context provided by the `timestamp` property, we wouldn't be able to make any assertion about the correctness of the `entityValue` property for time. Currently, you must specify the [`--timestamp`](Test.md#--timestamp) option to ensure a timestamp is assigned to each NLU prediction result.
4242

4343
## Utterance Extension Properties
4444

src/NLU.DevOps.CommandLine/Test/TestCommand.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ namespace NLU.DevOps.CommandLine.Test
77
using System.Collections.Generic;
88
using System.IO;
99
using System.Linq;
10+
using System.Threading;
1011
using System.Threading.Tasks;
12+
using Core;
1113
using Models;
1214
using Newtonsoft.Json.Linq;
1315
using static Serializer;
@@ -32,7 +34,8 @@ public override int Main()
3234

3335
protected override INLUTestClient CreateNLUTestClient()
3436
{
35-
return NLUClientFactory.CreateTestInstance(this.Options, this.Configuration, this.Options.SettingsPath);
37+
var client = NLUClientFactory.CreateTestInstance(this.Options, this.Configuration, this.Options.SettingsPath);
38+
return this.Options.Timestamp ? new TimestampNLUTestClient(client) : client;
3639
}
3740

3841
private static void EnsureDirectory(string filePath)
@@ -146,5 +149,34 @@ public LabeledUtteranceWithSpeechFile(string text, string intent, string speechF
146149

147150
public string SpeechFile { get; }
148151
}
152+
153+
private class TimestampNLUTestClient : INLUTestClient
154+
{
155+
public TimestampNLUTestClient(INLUTestClient client)
156+
{
157+
this.Client = client;
158+
}
159+
160+
private INLUTestClient Client { get; }
161+
162+
public async Task<LabeledUtterance> TestAsync(JToken query, CancellationToken cancellationToken)
163+
{
164+
var timestamp = DateTimeOffset.Now;
165+
var result = await this.Client.TestAsync(query, cancellationToken).ConfigureAwait(false);
166+
return result.WithTimestamp(timestamp);
167+
}
168+
169+
public async Task<LabeledUtterance> TestSpeechAsync(string speechFile, JToken query, CancellationToken cancellationToken)
170+
{
171+
var timestamp = DateTimeOffset.Now;
172+
var result = await this.Client.TestSpeechAsync(speechFile, query, cancellationToken).ConfigureAwait(false);
173+
return result.WithTimestamp(timestamp);
174+
}
175+
176+
public void Dispose()
177+
{
178+
this.Client.Dispose();
179+
}
180+
}
149181
}
150182
}

src/NLU.DevOps.CommandLine/Test/TestOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@ internal class TestOptions : BaseOptions
2828

2929
[Option('p', "parallelism", HelpText = "Numeric value to determine the numer of parallel tests. Default value is 3.", Required = false)]
3030
public int Parallelism { get; set; } = 3;
31+
32+
[Option("timestamp", HelpText = "Assign a timestamp to each utterance result.", Required = false)]
33+
public bool Timestamp { get; set; }
3134
}
3235
}

src/NLU.DevOps.Dialogflow/DialogflowNLUTestClient.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ protected override async Task<LabeledUtterance> TestAsync(string utterance, Canc
7878
result.QueryResult.Intent.DisplayName,
7979
result.QueryResult.Parameters?.Fields.SelectMany(GetEntities).ToList())
8080
.WithScore(result.QueryResult.IntentDetectionConfidence)
81-
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence)
82-
.WithTimestamp(DateTimeOffset.Now);
81+
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence);
8382
},
8483
cancellationToken)
8584
.ConfigureAwait(false);
@@ -115,8 +114,7 @@ protected override async Task<LabeledUtterance> TestSpeechAsync(string speechFil
115114
result.QueryResult.Intent.DisplayName,
116115
result.QueryResult.Parameters?.Fields.SelectMany(GetEntities).ToList())
117116
.WithScore(result.QueryResult.IntentDetectionConfidence)
118-
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence)
119-
.WithTimestamp(DateTimeOffset.Now);
117+
.WithTextScore(result.QueryResult.SpeechRecognitionConfidence);
120118
},
121119
cancellationToken)
122120
.ConfigureAwait(false);

src/NLU.DevOps.Lex.Tests/LexNLUTestClientTests.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,6 @@ public static async Task TestsWithSpeech(string slots, string entityType, string
8888
// assert reads content from file (file contents are "hello world")
8989
content.Should().Be("hello world");
9090

91-
// assert result type
92-
result.Should().BeOfType<JsonLabeledUtterance>();
93-
9491
// assert intent and text
9592
result.Intent.Should().Be(intent);
9693
result.Text.Should().Be(transcript);
@@ -123,7 +120,6 @@ public static async Task CreatesLabeledUtterances()
123120
using (var lex = new LexNLUTestClient(string.Empty, string.Empty, new LexSettings(), mockClient.Object))
124121
{
125122
var response = await lex.TestAsync(text).ConfigureAwait(false);
126-
response.Should().BeOfType<JsonLabeledUtterance>();
127123
response.Text.Should().Be(text);
128124
response.Intent.Should().Be(intent);
129125
response.Entities.Should().BeEmpty();

src/NLU.DevOps.Lex/LexNLUTestClient.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,7 @@ protected override async Task<LabeledUtterance> TestAsync(string utterance, Canc
9494
.Select(slot => new Entity(slot.Key, slot.Value, null, 0))
9595
.ToArray();
9696

97-
return new LabeledUtterance(utterance, postTextResponse.IntentName, entities)
98-
.WithTimestamp(DateTimeOffset.Now);
97+
return new LabeledUtterance(utterance, postTextResponse.IntentName, entities);
9998
}
10099

101100
/// <inheritdoc />
@@ -125,8 +124,7 @@ protected override async Task<LabeledUtterance> TestSpeechAsync(string speechFil
125124
.ToArray()
126125
: null;
127126

128-
return new JsonLabeledUtterance(postContentResponse.InputTranscript, postContentResponse.IntentName, slots)
129-
.WithTimestamp(DateTimeOffset.Now);
127+
return new LabeledUtterance(postContentResponse.InputTranscript, postContentResponse.IntentName, slots);
130128
}
131129
}
132130

src/NLU.DevOps.Luis.Tests/LuisNLUTestClientTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ public static async Task TestModel()
6565
using (var luis = builder.Build())
6666
{
6767
var result = await luis.TestAsync(test).ConfigureAwait(false);
68-
result.Should().BeOfType<JsonLabeledUtterance>();
6968
result.Text.Should().Be(test);
7069
result.Intent.Should().Be("intent");
7170
result.Entities.Count.Should().Be(1);

src/NLU.DevOps.Luis/LuisNLUTestClient.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,7 @@ Entity getEntity(EntityModel entity)
147147
speechLuisResult.LuisResult.TopScoringIntent?.Intent,
148148
speechLuisResult.LuisResult.Entities?.Select(getEntity).ToList())
149149
.WithScore(speechLuisResult.LuisResult.TopScoringIntent?.Score)
150-
.WithTextScore(speechLuisResult.TextScore)
151-
.WithTimestamp(DateTimeOffset.Now);
150+
.WithTextScore(speechLuisResult.TextScore);
152151
}
153152
}
154153
}

src/NLU.DevOps.LuisV3.Tests/LuisNLUTestClientTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ public static async Task TestModel()
6969
using (var luis = builder.Build())
7070
{
7171
var result = await luis.TestAsync(test).ConfigureAwait(false);
72-
result.Should().BeOfType<JsonLabeledUtterance>();
7372
result.Text.Should().Be(test);
7473
result.Intent.Should().Be("intent");
7574
result.Entities.Count.Should().Be(1);

0 commit comments

Comments
 (0)