Search code examples
c#botframeworkazure-language-understanding

LuisService does not serialize all resolution values for DateTimeV2 entity in botframework V4


I am working on a bot that you can use to book rooms. I'm using the luis builtin datetime entity to detect the start and end time of a meeting. Luis recognizes datetimes just fine, but I cannot get to them in luisResult in the bot code. I am using Microsoft.Bot.Builder V4.3.2

This is the example sentence:

"which room is available from 2pm to 4pm"

The raw luisResult contains

"entities": [
{
  "entity": "from 2pm to 4pm",
  "type": "builtin.datetimeV2.timerange",
  "startIndex": 24,
  "endIndex": 38,
  "resolution": {
    "values": [
      {
        "timex": "(T14,T16,PT2H)",
        "type": "timerange",
        "start": "14:00:00",
        "end": "16:00:00"
      }
    ]
  }
}

]

This is what I get back from using the LuisService in the code:

{
  "type": "timerange",
  "timex": [
     "(T14,T16,PT2H)"
  ]
}

It is missing the "start" and "end" properties I found that this bug was also present in botframework V3, but it has been solved in V3.8 https://github.com/Microsoft/BotBuilder/issues/2764

This is the call to the luisService:

var luisResults = await _services.LuisServices[LuisConfiguration].RecognizeAsync(dc.Context, cancellationToken);

I expected "start" and "end" to be serialized for the DateTime v2 entity.

EDIT: A way to work around this issue is to enable the full api response in the instantiation of the bot service:

var app = new LuisApplication(luis.AppId, luis.AuthoringKey, luis.GetEndpoint());
var recognizer = new LuisRecognizer(app, includeApiResults: true);

The full result can now be obtained in

luisResults.Properties["luisResult"]

Solution

  • To get the full response you can set includeApiResults on the LuisRecognizer to true.

    var recognizer = new LuisRecognizer(application, includeApiResults: true);
    

    Here is how the switch actually works under the hood and where it stores the results.

    In case you want to improve the handling yourself, a good starting point to build an improved version of LuisRecognizer is provided in the bot builder samples in Luis with AppInsights.

    /// <summary>
    /// Initializes a new instance of the <see cref="TelemetryLuisRecognizer"/> class.
    /// </summary>
    /// <param name="application">The LUIS application to use to recognize text.</param>
    /// <param name="predictionOptions">The LUIS prediction options to use.</param>
    /// <param name="includeApiResults">TRUE to include raw LUIS API response.</param>
    /// <param name="logOriginalMessage">TRUE to include original user message.</param>
    /// <param name="logUserName">TRUE to include user name.</param>
    public TelemetryLuisRecognizer(LuisApplication application, LuisPredictionOptions predictionOptions = null, bool includeApiResults = false, bool logOriginalMessage = false, bool logUserName = false)
        : base(application, predictionOptions, includeApiResults)
    {
        LogOriginalMessage = logOriginalMessage;
        LogUsername = logUserName;
    }
    

    Please also note this issue on GitHub. While the issue is closed, it is tagged as enhancement for Version 4.4. Version 4.3 was released in march so work on 4.4 did start already.

    Personal tip: When you're working with datetimeV2, you should know about the Recognizer-Text repository, which basically contains the "engine" that drives the whole thing. Note a long list if issues and make sure you always check them first, before losing too much time in your development.