diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj
index ce66c15c..ab625d88 100644
--- a/BotSharp.Core/BotSharp.Core.csproj
+++ b/BotSharp.Core/BotSharp.Core.csproj
@@ -17,7 +17,8 @@
MIT
https://github.com/Oceania2018/BotSharp
NLU, Chatbot, Bot, AI Bot
- 1.0.0
+ 1.1.0
+ Support Rasa NLU 0.12.x
diff --git a/BotSharp.Core/Engines/RequestExtension.cs b/BotSharp.Core/Engines/RequestExtension.cs
index eef9045b..346ae0d1 100644
--- a/BotSharp.Core/Engines/RequestExtension.cs
+++ b/BotSharp.Core/Engines/RequestExtension.cs
@@ -32,14 +32,13 @@ namespace BotSharp.Core.Engines
var result = CallRasa(rasa.agent.Id, request.Query.First(), rasa.agent.Id);
RasaResponse response = result.Data;
- var intentResponse = HandleIntentPerContextIn(rasa, request, result.Data);
-
aiResponse.Id = Guid.NewGuid().ToString();
aiResponse.Lang = rasa.agent.Language;
aiResponse.Status = new AIResponseStatus { };
aiResponse.SessionId = rasa.AiConfig.SessionId;
aiResponse.Timestamp = DateTime.UtcNow;
+ var intentResponse = HandleIntentPerContextIn(rasa, request, result.Data);
HandleParameter(rasa.agent, intentResponse, response, request);
HandleMessage(intentResponse);
@@ -48,13 +47,13 @@ namespace BotSharp.Core.Engines
{
Source = "agent",
ResolvedQuery = request.Query.First(),
- Action = intentResponse.Action,
- Parameters = intentResponse.Parameters.ToDictionary(x => x.Name, x=> x.Value),
+ Action = intentResponse?.Action,
+ Parameters = intentResponse?.Parameters?.ToDictionary(x => x.Name, x=> x.Value),
Score = response.Intent.Confidence,
- Metadata = new AIResponseMetadata { IntentId = intentResponse.IntentId, IntentName = intentResponse.IntentName },
+ Metadata = new AIResponseMetadata { IntentId = intentResponse?.IntentId, IntentName = intentResponse?.IntentName },
Fulfillment = new AIResponseFulfillment
{
- Messages = intentResponse.Messages.Select(x => {
+ Messages = intentResponse?.Messages?.Select(x => {
if (x.Type == AIResponseMessageType.Custom)
{
return (new
@@ -115,21 +114,31 @@ namespace BotSharp.Core.Engines
};
}
response.IntentRanking = response.IntentRanking.Where(x => intents.Select(i => i.Name).Contains(x.Name)).ToList();
- response.Intent = response.IntentRanking.First();
- var intent = (dc.Table().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();
+ if (response.IntentRanking.Count == 0)
+ {
+ return null;
+ }
+ else
+ {
+ response.Intent = response.IntentRanking.First();
- var intentResponse = ArrayHelper.GetRandom(intent.Responses);
- intentResponse.IntentName = intent.Name;
+ var intent = (dc.Table().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();
- return intentResponse;
+ var intentResponse = ArrayHelper.GetRandom(intent.Responses);
+ intentResponse.IntentName = intent.Name;
+
+ return intentResponse;
+ }
}
private static void HandleParameter(Agent agent, IntentResponse intentResponse, RasaResponse response, AIRequest request)
{
+ if (intentResponse == null) return;
+
intentResponse.Parameters.ForEach(p => {
string query = request.Query.First();
var entity = response.Entities.FirstOrDefault(x => x.Entity == p.Name);
@@ -164,6 +173,8 @@ namespace BotSharp.Core.Engines
private static void HandleMessage(IntentResponse intentResponse)
{
+ if (intentResponse == null) return;
+
intentResponse.Messages = intentResponse.Messages.OrderBy(x => x.UpdatedTime).ToList();
intentResponse.Messages.ToList()
.ForEach(msg =>
@@ -196,6 +207,8 @@ namespace BotSharp.Core.Engines
private static void HandleContext(Database dc, RasaAi rasa, IntentResponse intentResponse, AIResponse aiResponse)
{
+ if (intentResponse == null) return;
+
// Merge context lifespan
// override if exists, otherwise add, delete if lifespan is zero
dc.DbTran(() =>
@@ -444,30 +457,12 @@ namespace BotSharp.Core.Engines
public static string Train(this RasaAi console, Database dc)
{
+ var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}");
+ var rest = new RestRequest("train", Method.POST);
+ rest.AddQueryParameter("project", console.agent.Id);
+
var corpus = console.agent.GrabCorpus(dc);
- // Add some fake data
- if(corpus.UserSays.Count < 3)
- {
- corpus.UserSays.Add(new RasaIntentExpression
- {
- Intent = "Welcome",
- Text = "Hi"
- });
-
- corpus.UserSays.Add(new RasaIntentExpression
- {
- Intent = "Welcome",
- Text = "Hey"
- });
-
- corpus.UserSays.Add(new RasaIntentExpression
- {
- Intent = "Welcome",
- Text = "Hello"
- });
- }
-
string json = JsonConvert.SerializeObject(new { rasa_nlu_data = corpus },
new JsonSerializerSettings
{
@@ -475,10 +470,13 @@ namespace BotSharp.Core.Engines
NullValueHandling = NullValueHandling.Ignore
});
- var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}");
- var rest = new RestRequest("train", Method.POST);
- rest.AddQueryParameter("project", console.agent.Id);
+#if RASA_NLU_0_11
rest.AddParameter("application/json", json, ParameterType.RequestBody);
+#else
+ string body = File.ReadAllText($"{Database.ContentRootPath}{Path.DirectorySeparatorChar}Settings{Path.DirectorySeparatorChar}config_jieba_mitie_sklearn.yml");
+ body = body.Replace("@data", json);
+ rest.AddParameter("application/x-yml", body, ParameterType.RequestBody);
+#endif
var response = client.Execute(rest);
diff --git a/BotSharp.UnitTest/AgentTest.cs b/BotSharp.UnitTest/AgentTest.cs
index 7a3f11f2..21b25ff0 100644
--- a/BotSharp.UnitTest/AgentTest.cs
+++ b/BotSharp.UnitTest/AgentTest.cs
@@ -66,7 +66,6 @@ namespace BotSharp.UnitTest
config.SessionId = Guid.NewGuid().ToString();
var rasa = new RasaAi(dc, config);
- rasa.agent = rasa.LoadAgent(dc, config);
string msg = rasa.Train(dc);
Assert.IsTrue(!String.IsNullOrEmpty(msg));
diff --git a/BotSharp.UnitTest/IntentTest.cs b/BotSharp.UnitTest/IntentTest.cs
index 16f6b7f5..533e65f4 100644
--- a/BotSharp.UnitTest/IntentTest.cs
+++ b/BotSharp.UnitTest/IntentTest.cs
@@ -18,6 +18,10 @@ 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" } });
+ Assert.AreEqual(response.Result.Metadata.IntentName, "greet");
}
}
}
diff --git a/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml b/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml
new file mode 100644
index 00000000..b49a4e34
--- /dev/null
+++ b/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml
@@ -0,0 +1,13 @@
+language: "zh"
+
+pipeline:
+- name: "nlp_mitie"
+ model: "data/total_word_feature_extractor_zh.dat"
+- name: "tokenizer_jieba"
+- name: "ner_mitie"
+- name: "ner_synonyms"
+- name: "intent_entity_featurizer_regex"
+- name: "intent_featurizer_mitie"
+- name: "intent_classifier_sklearn"
+
+data: @data