From 09c6ca862de8b308b07b4560880c827e020c85ff Mon Sep 17 00:00:00 2001 From: haiping008 Date: Sun, 17 Dec 2017 23:30:20 -0600 Subject: [PATCH] Parse, Train, Agent --- .gitignore | 1 + Bot.Rasa.sln | 31 +++++++++++ Bot.Rasa/Agents/Agent.cs | 15 ++++++ Bot.Rasa/Agents/AgentResponse.cs | 23 ++++++++ Bot.Rasa/Bot.Rasa.csproj | 17 ++++++ Bot.Rasa/Console/RasaConsole.cs | 35 +++++++++++++ Bot.Rasa/Console/RasaOptions.cs | 11 ++++ Bot.Rasa/Console/RequestExtension.cs | 78 ++++++++++++++++++++++++++++ Bot.Rasa/EntityDbContextExtension.cs | 19 +++++++ Bot.Rasa/Intents/Intent.cs | 14 +++++ Bot.UnitTest/AgentTest.cs | 49 +++++++++++++++++ Bot.UnitTest/Bot.UnitTest.csproj | 19 +++++++ Bot.UnitTest/Database.cs | 35 +++++++++++++ 13 files changed, 347 insertions(+) create mode 100644 Bot.Rasa.sln create mode 100644 Bot.Rasa/Agents/Agent.cs create mode 100644 Bot.Rasa/Agents/AgentResponse.cs create mode 100644 Bot.Rasa/Bot.Rasa.csproj create mode 100644 Bot.Rasa/Console/RasaConsole.cs create mode 100644 Bot.Rasa/Console/RasaOptions.cs create mode 100644 Bot.Rasa/Console/RequestExtension.cs create mode 100644 Bot.Rasa/EntityDbContextExtension.cs create mode 100644 Bot.Rasa/Intents/Intent.cs create mode 100644 Bot.UnitTest/AgentTest.cs create mode 100644 Bot.UnitTest/Bot.UnitTest.csproj create mode 100644 Bot.UnitTest/Database.cs diff --git a/.gitignore b/.gitignore index 940794e6..e81bfb9e 100644 --- a/.gitignore +++ b/.gitignore @@ -286,3 +286,4 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs +/App_Data diff --git a/Bot.Rasa.sln b/Bot.Rasa.sln new file mode 100644 index 00000000..760c4187 --- /dev/null +++ b/Bot.Rasa.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2003 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.Rasa", "Bot.Rasa\Bot.Rasa.csproj", "{8E57A9A5-EB37-4F83-93FE-3324A069B568}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.UnitTest", "Bot.UnitTest\Bot.UnitTest.csproj", "{90705625-1342-4ED8-A05B-46C720D20EE4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8E57A9A5-EB37-4F83-93FE-3324A069B568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E57A9A5-EB37-4F83-93FE-3324A069B568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E57A9A5-EB37-4F83-93FE-3324A069B568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E57A9A5-EB37-4F83-93FE-3324A069B568}.Release|Any CPU.Build.0 = Release|Any CPU + {90705625-1342-4ED8-A05B-46C720D20EE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90705625-1342-4ED8-A05B-46C720D20EE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90705625-1342-4ED8-A05B-46C720D20EE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90705625-1342-4ED8-A05B-46C720D20EE4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A9969D89-C98B-40A5-A12B-FC87E55B3A19} + EndGlobalSection +EndGlobal diff --git a/Bot.Rasa/Agents/Agent.cs b/Bot.Rasa/Agents/Agent.cs new file mode 100644 index 00000000..42a9d61c --- /dev/null +++ b/Bot.Rasa/Agents/Agent.cs @@ -0,0 +1,15 @@ +using CustomEntityFoundation.Entities; +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; + +namespace Bot.Rasa.Agents +{ + public class RasaAgent : Entity, IDbRecord + { + [MaxLength(64)] + public String Name { get; set; } + } +} diff --git a/Bot.Rasa/Agents/AgentResponse.cs b/Bot.Rasa/Agents/AgentResponse.cs new file mode 100644 index 00000000..7431b76e --- /dev/null +++ b/Bot.Rasa/Agents/AgentResponse.cs @@ -0,0 +1,23 @@ +using Bot.Rasa.Intents; +using CustomEntityFoundation.Entities; +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Bot.Rasa.Agents +{ + public class AgentResponse + { + public AgentResponseIntent Intent { get; set; } + + public String Text { get; set; } + } + + public class AgentResponseIntent + { + public String Name { get; set; } + + public Decimal Confidence { get; set; } + } +} diff --git a/Bot.Rasa/Bot.Rasa.csproj b/Bot.Rasa/Bot.Rasa.csproj new file mode 100644 index 00000000..899f1d28 --- /dev/null +++ b/Bot.Rasa/Bot.Rasa.csproj @@ -0,0 +1,17 @@ + + + + netcoreapp2.0 + + + + + + + + + + + + + diff --git a/Bot.Rasa/Console/RasaConsole.cs b/Bot.Rasa/Console/RasaConsole.cs new file mode 100644 index 00000000..c1c14f61 --- /dev/null +++ b/Bot.Rasa/Console/RasaConsole.cs @@ -0,0 +1,35 @@ +using Bot.Rasa.Agents; +using CustomEntityFoundation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Bot.Rasa.Console +{ + public class RasaConsole + { + private EntityDbContext dc { get; set; } + public RasaOptions options { get; set; } + + public RasaConsole(EntityDbContext dc, RasaOptions options) + { + this.dc = dc; + this.options = options; + } + + public RasaAgent LoadAgent(String agentId) + { + return dc.Agent().Find(agentId); + } + + public String CreateAgent(RasaAgent agent) + { + if (dc.Agent().Any(x => x.Name == agent.Name)) return String.Empty; + + dc.Agent().Add(agent); + + return agent.Id; + } + } +} diff --git a/Bot.Rasa/Console/RasaOptions.cs b/Bot.Rasa/Console/RasaOptions.cs new file mode 100644 index 00000000..318fbb14 --- /dev/null +++ b/Bot.Rasa/Console/RasaOptions.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Bot.Rasa.Console +{ + public class RasaOptions + { + public string HostUrl { get; set; } + } +} diff --git a/Bot.Rasa/Console/RequestExtension.cs b/Bot.Rasa/Console/RequestExtension.cs new file mode 100644 index 00000000..bbd46b30 --- /dev/null +++ b/Bot.Rasa/Console/RequestExtension.cs @@ -0,0 +1,78 @@ +using Bot.Rasa.Agents; +using CustomEntityFoundation; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using RestSharp; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Bot.Rasa.Console +{ + public static class RequestExtension + { + public static AgentResponse TextRequest(this RasaConsole console, String agentId, String text) + { + var client = new RestClient($"{console.options.HostUrl}"); + + var request = new RestRequest("parse?project={project}&q={text}", Method.GET); + request.AddUrlSegment("project", agentId); + request.AddUrlSegment("text", text); + + var response = client.Execute(request); + + return response.Data; + } + + public static bool Train(this RasaConsole console, String agentId) + { + var client = new RestClient($"{console.options.HostUrl}"); + + var request = new RestRequest("train", Method.POST); + + request.AddQueryParameter("project", agentId); + + string json = JsonConvert.SerializeObject(new + { + rasa_nlu_data = new RasaTrainingData + { + UserSays = new List + { + new UserSay{ Text = "What's the weather like today?", Intent = "Weather" }, + new UserSay{ Text = "Is gonna rain tomorrow?", Intent = "Weather"}, + new UserSay{ Text = "Sunny", Intent = "Weather"}, + new UserSay{ Text = "Is it raining outside?", Intent = "Weather"}, + new UserSay{ Text = "It is raining", Intent = "Weather"}, + new UserSay{ Text = "How old are you?", Intent = "Age"}, + new UserSay{ Text = "When were you born?", Intent = "Age"}, + new UserSay{ Text = "Where do you come from", Intent = "Country"}, + new UserSay{ Text = "Where are you from?", Intent = "Country"}, + new UserSay{ Text = "are you from US?", Intent = "Country"}, + new UserSay{ Text = "What do you like for lunch?", Intent = "Lunch"}, + new UserSay{ Text = "Would you like some cookie?", Intent = "Lunch"} + } + } + }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); + + request.AddParameter("application/json", json, ParameterType.RequestBody); + + var response = client.Execute(request); + + return true; + } + + } + + public class RasaTrainingData + { + [JsonProperty("common_examples")] + public List UserSays { get; set; } + } + + public class UserSay + { + public String Text { get; set; } + public String Intent { get; set; } + } +} diff --git a/Bot.Rasa/EntityDbContextExtension.cs b/Bot.Rasa/EntityDbContextExtension.cs new file mode 100644 index 00000000..9fda0c99 --- /dev/null +++ b/Bot.Rasa/EntityDbContextExtension.cs @@ -0,0 +1,19 @@ +using Bot.Rasa.Agents; +using CustomEntityFoundation; +using EntityFrameworkCore.BootKit; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Bot.Rasa +{ + public static class EntityDbContextExtension + { + public static DbSet Agent(this EntityDbContext dc) + { + return dc.Table(); + } + } +} diff --git a/Bot.Rasa/Intents/Intent.cs b/Bot.Rasa/Intents/Intent.cs new file mode 100644 index 00000000..ee832c61 --- /dev/null +++ b/Bot.Rasa/Intents/Intent.cs @@ -0,0 +1,14 @@ +using CustomEntityFoundation.Entities; +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; + +namespace Bot.Rasa.Intents +{ + public class RasaIntent : Entity, IDbRecord + { + public String Name { get; set; } + } +} diff --git a/Bot.UnitTest/AgentTest.cs b/Bot.UnitTest/AgentTest.cs new file mode 100644 index 00000000..82c0df65 --- /dev/null +++ b/Bot.UnitTest/AgentTest.cs @@ -0,0 +1,49 @@ +using Bot.Rasa; +using Bot.Rasa.Agents; +using Bot.Rasa.Console; +using EntityFrameworkCore.BootKit; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Bot.UnitTest +{ + [TestClass] + public class AgentTest : Database + { + public static String PIZZA_BOT_ID = "2b6a288e-d891-40c6-96ce-6a0cf324545c"; + public static RasaOptions Options = new RasaOptions { HostUrl = "http://192.168.56.101:5000" }; + + [TestMethod] + public void CreateAgent() + { + var rasa = new RasaConsole(dc, Options); + + var agent = new RasaAgent + { + Id = PIZZA_BOT_ID, + Name = "Pizza Bot" + }; + + dc.DbTran(() => rasa.CreateAgent(agent)); + } + + [TestMethod] + public void TextRequest() + { + var rasa = new RasaConsole(dc, Options); + var response = rasa.TextRequest(PIZZA_BOT_ID, "how old are you"); + response = rasa.TextRequest(PIZZA_BOT_ID, "where do you come from"); + response = rasa.TextRequest(PIZZA_BOT_ID, "would you like some cookie"); + } + + [TestMethod] + public void Train() + { + var rasa = new RasaConsole(dc, Options); + rasa.Train(PIZZA_BOT_ID); + } + } +} diff --git a/Bot.UnitTest/Bot.UnitTest.csproj b/Bot.UnitTest/Bot.UnitTest.csproj new file mode 100644 index 00000000..020eafdb --- /dev/null +++ b/Bot.UnitTest/Bot.UnitTest.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.0 + + false + + + + + + + + + + + + + diff --git a/Bot.UnitTest/Database.cs b/Bot.UnitTest/Database.cs new file mode 100644 index 00000000..fdb0b189 --- /dev/null +++ b/Bot.UnitTest/Database.cs @@ -0,0 +1,35 @@ +using CustomEntityFoundation; +using CustomEntityFoundation.Entities; +using EntityFrameworkCore.BootKit; +using Microsoft.Data.Sqlite; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Bot.UnitTest +{ + public abstract class Database + { + protected EntityDbContext dc { get; set; } + + public Database() + { + EntityDbContext.Assembles = new String[] { "Bot.Rasa" }; + var options = new DatabaseOptions + { + ContentRootPath = Directory.GetCurrentDirectory() + "\\..\\..\\..\\..", + }; + + // Sqlite + options.Database = "Sqlite"; + options.ConnectionString = "Data Source=|DataDirectory|\\bot.db"; + EntityDbContext.Options = options; + + dc = new EntityDbContext(); + dc.InitDb(); + } + } + + +}