fix intent is not correct when context is empty in the middle of the converstion.

This commit is contained in:
Oceania2018 2018-05-06 19:48:10 -05:00
parent be63def9cc
commit fc51b23bcf
6 changed files with 77 additions and 74 deletions

View file

@ -13,6 +13,11 @@ namespace BotSharp.Core.Agents
[Table("Bot_Agent")]
public class Agent : DbRecord, IDbRecord
{
public Agent()
{
CreatedDate = DateTime.UtcNow;
}
[MaxLength(64)]
public String Name { get; set; }
@ -49,5 +54,16 @@ namespace BotSharp.Core.Agents
[ForeignKey("AgentId")]
[JsonProperty("entity_types")]
public List<Entity> Entities { get; set; }
public String Birthday
{
get
{
return CreatedDate.ToShortDateString();
}
}
[Required]
public DateTime CreatedDate { get; set; }
}
}

View file

@ -27,52 +27,12 @@ namespace BotSharp.Core.Engines
public static AIResponse TextRequest(this RasaAi rasa, AIRequest request)
{
AIResponse aiResponse = new AIResponse();
RasaResponse response = null;
Database dc = rasa.dc;
// Merge input contexts
var contexts = dc.Table<ConversationContext>()
.Where(x => x.ConversationId == rasa.AiConfig.SessionId && x.Lifespan > 0)
.ToList()
.Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan })
.ToList();
contexts.AddRange(request.Contexts.Select(x => new AIContext { Name = x.Name.ToLower(), Lifespan = x.Lifespan }));
contexts = contexts.OrderBy(x => x.Name).ToList();
// search all potential intents which input context included in contexts
var intents = rasa.agent.Intents.Where(it =>
{
if (contexts.Count == 0)
{
return it.Contexts.Count() == 0;
}
else
{
return it.Contexts.Count() > 0 &&
it.Contexts.Count(x => contexts.Select(ctx => ctx.Name).Contains(x.Name.ToLower())) == it.Contexts.Count;
}
}).OrderByDescending(x => x.Contexts.Count).ToList();
var result = CallRasa(rasa.agent.Id, request.Query.First(), rasa.agent.Id);
RasaResponse response = result.Data;
var intentResponse = HandleIntentPerContextIn(rasa, request, result.Data);
if (result.Data.IntentRanking == null)
{
result.Data.IntentRanking = new List<RasaResponseIntent>
{
result.Data.Intent
};
}
result.Data.IntentRanking = result.Data.IntentRanking.Where(x => intents.Select(i => i.Name).Contains(x.Name)).ToList();
result.Data.Intent = result.Data.IntentRanking.First();
response = result.Data;
var intent = (dc.Table<Intent>().Where(x => x.Name == response.Intent.Name)
.Include(x => x.Responses).ThenInclude(x => x.Contexts)
.Include(x => x.Responses).ThenInclude(x => x.Parameters)
.Include(x => x.Responses).ThenInclude(x => x.Messages)).First();
var intentResponse = ArrayHelper.GetRandom(intent.Responses);
aiResponse.Id = Guid.NewGuid().ToString();
aiResponse.Lang = rasa.agent.Language;
aiResponse.Status = new AIResponseStatus { };
@ -90,7 +50,7 @@ namespace BotSharp.Core.Engines
Action = intentResponse.Action,
Parameters = intentResponse.Parameters.ToDictionary(x => x.Name, x=> x.Value),
Score = response.Intent.Confidence,
Metadata = new AIResponseMetadata { IntentId = intent.Id, IntentName = intent.Name },
Metadata = new AIResponseMetadata { IntentId = intentResponse.IntentId, IntentName = intentResponse.IntentName },
Fulfillment = new AIResponseFulfillment
{
Messages = intentResponse.Messages.Select(x => {
@ -116,6 +76,55 @@ namespace BotSharp.Core.Engines
return aiResponse;
}
private static IntentResponse HandleIntentPerContextIn(RasaAi rasa, AIRequest request, RasaResponse response)
{
Database dc = rasa.dc;
// Merge input contexts
var contexts = dc.Table<ConversationContext>()
.Where(x => x.ConversationId == rasa.AiConfig.SessionId && x.Lifespan > 0)
.ToList()
.Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan })
.ToList();
contexts.AddRange(request.Contexts.Select(x => new AIContext { Name = x.Name.ToLower(), Lifespan = x.Lifespan }));
contexts = contexts.OrderBy(x => x.Name).ToList();
// search all potential intents which input context included in contexts
var intents = rasa.agent.Intents.Where(it =>
{
if (contexts.Count == 0)
{
return it.Contexts.Count() == 0;
}
else
{
return it.Contexts.Count() == 0 ||
it.Contexts.Count(x => contexts.Select(ctx => ctx.Name).Contains(x.Name.ToLower())) == it.Contexts.Count;
}
}).OrderByDescending(x => x.Contexts.Count).ToList();
if (response.IntentRanking == null)
{
response.IntentRanking = new List<RasaResponseIntent>
{
response.Intent
};
}
response.IntentRanking = response.IntentRanking.Where(x => intents.Select(i => i.Name).Contains(x.Name)).ToList();
response.Intent = response.IntentRanking.First();
var intent = (dc.Table<Intent>().Where(x => x.Name == response.Intent.Name)
.Include(x => x.Responses).ThenInclude(x => x.Contexts)
.Include(x => x.Responses).ThenInclude(x => x.Parameters)
.Include(x => x.Responses).ThenInclude(x => x.Messages)).First();
var intentResponse = ArrayHelper.GetRandom(intent.Responses);
intentResponse.IntentName = intent.Name;
return intentResponse;
}
private static void HandleParameter(Agent agent, IntentResponse intentResponse, RasaResponse response, AIRequest request)
{
intentResponse.Parameters.ForEach(p => {
@ -210,7 +219,7 @@ namespace BotSharp.Core.Engines
});
aiResponse.Result.Contexts = dc.Table<ConversationContext>()
.Where(x => x.ConversationId == rasa.AiConfig.SessionId)
.Where(x => x.Lifespan > 0 && x.ConversationId == rasa.AiConfig.SessionId)
.Select(x => new AIContext { Name = x.Context.ToLower(), Lifespan = x.Lifespan })
.ToArray();
}

View file

@ -27,5 +27,8 @@ namespace BotSharp.Core.Intents
[ForeignKey("IntentResponseId")]
public List<IntentResponseMessage> Messages { get; set; }
[NotMapped]
public string IntentName { get; set; }
}
}

View file

@ -20,7 +20,8 @@ namespace BotSharp.UnitTest
{
Id = BOT_ID,
Name = BOT_NAME,
Language = "en"
Language = "en",
UserId = Guid.NewGuid().ToString()
};
var rasa = new RasaAi(dc);
@ -52,6 +53,7 @@ namespace BotSharp.UnitTest
agent.Id = BOT_ID;
agent.ClientAccessToken = BOT_CLIENT_TOKEN;
agent.DeveloperAccessToken = BOT_DEVELOPER_TOKEN;
agent.UserId = Guid.NewGuid().ToString();
int row = dc.DbTran(() => rasa.SaveAgent(agent));
}

View file

@ -3,6 +3,7 @@ using BotSharp.Core.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.UnitTest
@ -17,34 +18,6 @@ namespace BotSharp.UnitTest
config.SessionId = Guid.NewGuid().ToString();
var rasa = new RasaAi(dc, config);
// Round 1
var response = rasa.TextRequest(new AIRequest { Query = new String[] { "Hi, Voiceweb" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Wakeup");
// Round 2
response = rasa.TextRequest(new AIRequest { Query = new String[] { "I'm going to apple store to buy iphone 10" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Transfer2SalesBot");
// Round 3
response = rasa.TextRequest(new AIRequest { Query = new String[] { "Yes" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Transfer2SalesBot - address");
// Round 4
response = rasa.TextRequest(new AIRequest { Query = new String[] { "Sure" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Transfer2SalesBot - confirm address");
// Round 5
response = rasa.TextRequest(new AIRequest { Query = new String[] { "That's right" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Transfer2SalesBot - payment");
// Round 6
response = rasa.TextRequest(new AIRequest { Query = new String[] { "Yes" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Transfer2SalesBot - place work order");
// Round 7
response = rasa.TextRequest(new AIRequest { Query = new String[] { "byebye" } });
Assert.AreEqual(response.Result.Metadata.IntentName, "Byebye");
}
}
}

View file

@ -1,5 +1,5 @@
{
"Rasa": {
"Host": "http://rasa.local:5000"
"Nlu": "http://localhost:5000"
}
}