fix intent is not correct when context is empty in the middle of the converstion.
This commit is contained in:
parent
be63def9cc
commit
fc51b23bcf
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,5 +27,8 @@ namespace BotSharp.Core.Intents
|
|||
|
||||
[ForeignKey("IntentResponseId")]
|
||||
public List<IntentResponseMessage> Messages { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string IntentName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"Rasa": {
|
||||
"Host": "http://rasa.local:5000"
|
||||
"Nlu": "http://localhost:5000"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue