From d286d0dd8318e9cf72644e151387f3add65ba558 Mon Sep 17 00:00:00 2001 From: haiping008 Date: Sat, 30 Dec 2017 14:26:35 -0600 Subject: [PATCH] Add bunch of APIs --- Bot.Rasa.RestApi/AgentController.cs | 31 +++++++++ Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj | 19 ++++++ Bot.Rasa.RestApi/EntityController.cs | 17 +++++ Bot.Rasa.RestApi/EssentialController.cs | 67 +++++++++++++++++++ Bot.Rasa.sln | 18 ++++- Bot.Rasa/Agents/Agent.cs | 14 ++-- Bot.Rasa/Agents/AgentExtension.cs | 12 +++- Bot.Rasa/Agents/AgentResponse.cs | 1 - Bot.Rasa/Bot.Rasa.csproj | 6 +- Bot.Rasa/Console/RasaConsole.cs | 62 ++++++++++++++--- Bot.Rasa/Console/RasaOptions.cs | 4 ++ Bot.Rasa/Console/RequestExtension.cs | 27 +++++--- Bot.Rasa/Entities/EntityItem.cs | 23 +++++++ Bot.Rasa/Entities/EntityType.cs | 26 +++++++ Bot.Rasa/EntityDbContextExtension.cs | 13 ++-- Bot.Rasa/Expressions/EntitiyOfSpeech.cs | 27 ++++++++ Bot.Rasa/Intents/Intent.cs | 8 +-- Bot.Rasa/Intents/IntentExpression.cs | 18 +++-- Bot.Rasa/Models/UserSay.cs | 9 ++- Bot.UnitTest/AgentTest.cs | 27 ++++---- Bot.UnitTest/Database.cs | 30 --------- Bot.UnitTest/GenerateTestData.cs | 34 ---------- Bot.UnitTest/TestEssential.cs | 34 ++++++++++ .../2b6a288e-d891-40c6-96ce-6a0cf324545c.json | 61 +++++++++++++++++ Bot.WebStarter/Bot.WebStarter.csproj | 27 ++++++++ Bot.WebStarter/Program.cs | 25 +++++++ Bot.WebStarter/Settings/appsettings.json | 19 ++++++ Bot.WebStarter/Settings/dbsettings.json | 10 +++ Bot.WebStarter/Startup.cs | 51 ++++++++++++++ 29 files changed, 594 insertions(+), 126 deletions(-) create mode 100644 Bot.Rasa.RestApi/AgentController.cs create mode 100644 Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj create mode 100644 Bot.Rasa.RestApi/EntityController.cs create mode 100644 Bot.Rasa.RestApi/EssentialController.cs create mode 100644 Bot.Rasa/Entities/EntityItem.cs create mode 100644 Bot.Rasa/Entities/EntityType.cs create mode 100644 Bot.Rasa/Expressions/EntitiyOfSpeech.cs delete mode 100644 Bot.UnitTest/Database.cs delete mode 100644 Bot.UnitTest/GenerateTestData.cs create mode 100644 Bot.UnitTest/TestEssential.cs create mode 100644 Bot.WebStarter/App_Data/DbInitializer/Agents/2b6a288e-d891-40c6-96ce-6a0cf324545c.json create mode 100644 Bot.WebStarter/Bot.WebStarter.csproj create mode 100644 Bot.WebStarter/Program.cs create mode 100644 Bot.WebStarter/Settings/appsettings.json create mode 100644 Bot.WebStarter/Settings/dbsettings.json create mode 100644 Bot.WebStarter/Startup.cs diff --git a/Bot.Rasa.RestApi/AgentController.cs b/Bot.Rasa.RestApi/AgentController.cs new file mode 100644 index 00000000..49f5991a --- /dev/null +++ b/Bot.Rasa.RestApi/AgentController.cs @@ -0,0 +1,31 @@ +using Bot.Rasa.Agents; +using Bot.Rasa.Console; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Bot.Rasa.RestApi +{ + public class AgentController : EssentialController + { + [HttpGet("id")] + public Agent Get([FromRoute] String id) + { + var console = new RasaConsole(dc); + return console.LoadAgent(id); + } + + [HttpPost] + public String Create([FromBody] Agent agent) + { + dc.DbTran(() => { + + + + }); + + return agent.Id; + } + } +} diff --git a/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj b/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj new file mode 100644 index 00000000..3813d93c --- /dev/null +++ b/Bot.Rasa.RestApi/Bot.Rasa.RestApi.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.0 + + + + bin\Debug\netcoreapp2.0\Bot.Rasa.RestApi.xml + + + + + + + + + + + diff --git a/Bot.Rasa.RestApi/EntityController.cs b/Bot.Rasa.RestApi/EntityController.cs new file mode 100644 index 00000000..7784e954 --- /dev/null +++ b/Bot.Rasa.RestApi/EntityController.cs @@ -0,0 +1,17 @@ +using Bot.Rasa.Entities; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Bot.Rasa.RestApi +{ + public class EntityController : EssentialController + { + [HttpPost] + public string CreateEntity([FromBody] EntityType entity) + { + return entity.Id; + } + } +} diff --git a/Bot.Rasa.RestApi/EssentialController.cs b/Bot.Rasa.RestApi/EssentialController.cs new file mode 100644 index 00000000..21b3543a --- /dev/null +++ b/Bot.Rasa.RestApi/EssentialController.cs @@ -0,0 +1,67 @@ +using Bot.Rasa.Console; +using EntityFrameworkCore.BootKit; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.Sqlite; +using MySql.Data.MySqlClient; +using System; +using System.Collections.Generic; +using System.Data.SqlClient; +using System.Text; + +namespace Bot.Rasa.RestApi +{ +#if !DEBUG + [Authorize] +#endif + [Produces("application/json")] + [Route("bot/[controller]")] + public class EssentialController : ControllerBase + { + protected Database dc { get; set; } + + public EssentialController() + { + dc = new Database(); + + string db = RasaConsole.Options.DbName; + string connectionString = RasaConsole.Options.DbConnectionString; + + if (db.Equals("SqlServer")) + { + dc.BindDbContext(new DatabaseBind + { + MasterConnection = new SqlConnection(connectionString), + CreateDbIfNotExist = true, + AssemblyNames = RasaConsole.Options.Assembles + }); + } + else if (db.Equals("Sqlite")) + { + connectionString = connectionString.Replace("|DataDirectory|\\", RasaConsole.Options.ContentRootPath + "\\App_Data\\"); + dc.BindDbContext(new DatabaseBind + { + MasterConnection = new SqliteConnection(connectionString), + CreateDbIfNotExist = true, + AssemblyNames = RasaConsole.Options.Assembles + }); + } + else if (db.Equals("MySql")) + { + dc.BindDbContext(new DatabaseBind + { + MasterConnection = new MySqlConnection(connectionString), + CreateDbIfNotExist = true, + AssemblyNames = RasaConsole.Options.Assembles + }); + } + else if (db.Equals("InMemory")) + { + dc.BindDbContext(new DatabaseBind + { + AssemblyNames = RasaConsole.Options.Assembles + }); + } + } + + } +} diff --git a/Bot.Rasa.sln b/Bot.Rasa.sln index 760c4187..7e984f0b 100644 --- a/Bot.Rasa.sln +++ b/Bot.Rasa.sln @@ -1,11 +1,15 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27130.2003 +VisualStudioVersion = 15.0.27130.2010 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.Rasa", "Bot.Rasa\Bot.Rasa.csproj", "{8E57A9A5-EB37-4F83-93FE-3324A069B568}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.UnitTest", "Bot.UnitTest\Bot.UnitTest.csproj", "{90705625-1342-4ED8-A05B-46C720D20EE4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bot.Rasa.RestApi", "Bot.Rasa.RestApi\Bot.Rasa.RestApi.csproj", "{310EECBB-8B77-4F4A-A09C-6B5EED29155E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot.WebStarter", "Bot.WebStarter\Bot.WebStarter.csproj", "{ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +25,14 @@ Global {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 + {310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {310EECBB-8B77-4F4A-A09C-6B5EED29155E}.Release|Any CPU.Build.0 = Release|Any CPU + {ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ACBEB546-00AB-4EB7-8DBF-4BFF722FC9EA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Bot.Rasa/Agents/Agent.cs b/Bot.Rasa/Agents/Agent.cs index 80ddfa72..696e933c 100644 --- a/Bot.Rasa/Agents/Agent.cs +++ b/Bot.Rasa/Agents/Agent.cs @@ -1,6 +1,7 @@ -using Bot.Rasa.Intents; -using CustomEntityFoundation.Entities; +using Bot.Rasa.Entities; +using Bot.Rasa.Intents; using EntityFrameworkCore.BootKit; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -9,12 +10,17 @@ using System.Text; namespace Bot.Rasa.Agents { - public class RasaAgent : Entity, IDbRecord + [Table("Bot_Agent")] + public class Agent : DbRecord, IDbRecord { [MaxLength(64)] public String Name { get; set; } [ForeignKey("AgentId")] - public List Intents { get; set; } + public List Intents { get; set; } + + [ForeignKey("AgentId")] + [JsonProperty("entity_types")] + public List EntityTypes { get; set; } } } diff --git a/Bot.Rasa/Agents/AgentExtension.cs b/Bot.Rasa/Agents/AgentExtension.cs index b406ea43..75908fe1 100644 --- a/Bot.Rasa/Agents/AgentExtension.cs +++ b/Bot.Rasa/Agents/AgentExtension.cs @@ -1,5 +1,6 @@ -using Bot.Rasa.Models; -using CustomEntityFoundation; +using Bot.Rasa.Entities; +using Bot.Rasa.Models; +using EntityFrameworkCore.BootKit; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; @@ -10,7 +11,12 @@ namespace Bot.Rasa.Agents { public static class AgentExtension { - public static RasaTrainingData GrabCorpus(this RasaAgent agent, EntityDbContext dc) + public static String CreateEntity(this Agent agent, EntityType entity, Database dc) + { + return entity.Id; + } + + public static RasaTrainingData GrabCorpus(this Agent agent, Database dc) { var trainingData = new RasaTrainingData { diff --git a/Bot.Rasa/Agents/AgentResponse.cs b/Bot.Rasa/Agents/AgentResponse.cs index 7431b76e..48f79116 100644 --- a/Bot.Rasa/Agents/AgentResponse.cs +++ b/Bot.Rasa/Agents/AgentResponse.cs @@ -1,5 +1,4 @@ using Bot.Rasa.Intents; -using CustomEntityFoundation.Entities; using EntityFrameworkCore.BootKit; using System; using System.Collections.Generic; diff --git a/Bot.Rasa/Bot.Rasa.csproj b/Bot.Rasa/Bot.Rasa.csproj index 899f1d28..102c72f2 100644 --- a/Bot.Rasa/Bot.Rasa.csproj +++ b/Bot.Rasa/Bot.Rasa.csproj @@ -5,11 +5,7 @@ - - - - - + diff --git a/Bot.Rasa/Console/RasaConsole.cs b/Bot.Rasa/Console/RasaConsole.cs index c1c14f61..fb218d5e 100644 --- a/Bot.Rasa/Console/RasaConsole.cs +++ b/Bot.Rasa/Console/RasaConsole.cs @@ -1,7 +1,13 @@ using Bot.Rasa.Agents; -using CustomEntityFoundation; +using Bot.Rasa.Entities; +using EntityFrameworkCore.BootKit; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; @@ -9,21 +15,61 @@ namespace Bot.Rasa.Console { public class RasaConsole { - private EntityDbContext dc { get; set; } - public RasaOptions options { get; set; } + private Database dc { get; set; } + public static RasaOptions Options { get; set; } + public static IConfiguration Configuration { get; set; } - public RasaConsole(EntityDbContext dc, RasaOptions options) + public RasaConsole(Database dc) { this.dc = dc; - this.options = options; } - public RasaAgent LoadAgent(String agentId) + /// + /// Restore a agent instance from json file + /// + /// + /// + public Agent RestoreAgent(String agentId) { - return dc.Agent().Find(agentId); + string json = File.ReadAllText($"{Options.ContentRootPath}\\App_Data\\DbInitializer\\Agents\\{agentId}.json"); + var agent = JsonConvert.DeserializeObject(json); + + agent.Id = agentId; + agent.EntityTypes.ForEach(entityType => + { + entityType.Items = entityType.Values.Select(x => new EntityItem + { + Value = x + }).ToList(); + }); + + agent.Intents.ForEach(intent => { + + intent.Expressions.ForEach(expression => + { + }); + + }); + + return agent; } - public String CreateAgent(RasaAgent agent) + /// + /// Dump agent train data to json file + /// + /// + /// + public bool DumpAgent(String agentId) + { + return true; + } + + public Agent LoadAgent(String agentId) + { + return dc.Agent().Include(x => x.Intents).FirstOrDefault(x => x.Id == agentId); + } + + public String CreateAgent(Agent agent) { if (dc.Agent().Any(x => x.Name == agent.Name)) return String.Empty; diff --git a/Bot.Rasa/Console/RasaOptions.cs b/Bot.Rasa/Console/RasaOptions.cs index 318fbb14..81456305 100644 --- a/Bot.Rasa/Console/RasaOptions.cs +++ b/Bot.Rasa/Console/RasaOptions.cs @@ -7,5 +7,9 @@ namespace Bot.Rasa.Console public class RasaOptions { public string HostUrl { get; set; } + public String[] Assembles { get; set; } + public string ContentRootPath { get; set; } + public String DbName { get; set; } + public String DbConnectionString { get; set; } } } diff --git a/Bot.Rasa/Console/RequestExtension.cs b/Bot.Rasa/Console/RequestExtension.cs index 18168891..7ab49ff8 100644 --- a/Bot.Rasa/Console/RequestExtension.cs +++ b/Bot.Rasa/Console/RequestExtension.cs @@ -1,6 +1,6 @@ using Bot.Rasa.Agents; using Bot.Rasa.Models; -using CustomEntityFoundation; +using EntityFrameworkCore.BootKit; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; @@ -15,18 +15,29 @@ namespace Bot.Rasa.Console { public static AgentResponse TextRequest(this RasaConsole console, String agentId, String text) { - var client = new RestClient($"{console.options.HostUrl}"); + var client = new RestClient($"{RasaConsole.Options.HostUrl}"); - var request = new RestRequest("parse?project={project}&q={text}", Method.GET); - request.AddUrlSegment("project", agentId); - request.AddUrlSegment("text", text); + var request = new RestRequest("parse", Method.POST); + string json = JsonConvert.SerializeObject(new { Project = agentId, Q = text }, + new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + request.AddParameter("application/json", json, ParameterType.RequestBody); var response = client.Execute(request); return response.Data; } - public static bool Train(this RasaConsole console, EntityDbContext dc, String agentId) + /// + /// Need two categories at least + /// + /// + /// + /// + /// + public static bool Train(this RasaConsole console, Database dc, String agentId) { var agent = dc.Agent().Find(agentId); var corpus = agent.GrabCorpus(dc); @@ -37,14 +48,14 @@ namespace Bot.Rasa.Console ContractResolver = new CamelCasePropertyNamesContractResolver() }); - var client = new RestClient($"{console.options.HostUrl}"); + var client = new RestClient($"{RasaConsole.Options.HostUrl}"); var request = new RestRequest("train", Method.POST); request.AddQueryParameter("project", agentId); request.AddParameter("application/json", json, ParameterType.RequestBody); var response = client.Execute(request); - return true; + return response.IsSuccessful; } } } diff --git a/Bot.Rasa/Entities/EntityItem.cs b/Bot.Rasa/Entities/EntityItem.cs new file mode 100644 index 00000000..bc721353 --- /dev/null +++ b/Bot.Rasa/Entities/EntityItem.cs @@ -0,0 +1,23 @@ +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; + +namespace Bot.Rasa.Entities +{ + [Table("Bot_EntityItem")] + public class EntityItem : DbRecord, IDbRecord + { + [Required] + [StringLength(36)] + public String EntityTypeId { get; set; } + + [MaxLength(128)] + public String Value { get; set; } + + [NotMapped] + public List Synonyms { get; set; } + } +} diff --git a/Bot.Rasa/Entities/EntityType.cs b/Bot.Rasa/Entities/EntityType.cs new file mode 100644 index 00000000..9798621a --- /dev/null +++ b/Bot.Rasa/Entities/EntityType.cs @@ -0,0 +1,26 @@ +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; + +namespace Bot.Rasa.Entities +{ + [Table("Bot_EntityType")] + public class EntityType : DbRecord, IDbRecord + { + [Required] + [StringLength(36)] + public String AgentId { get; set; } + + [MaxLength(64)] + public String Name { get; set; } + + [NotMapped] + public List Values { get; set; } + + [ForeignKey("EntityTypeId")] + public List Items { get; set; } + } +} diff --git a/Bot.Rasa/EntityDbContextExtension.cs b/Bot.Rasa/EntityDbContextExtension.cs index d317834e..5c0cad18 100644 --- a/Bot.Rasa/EntityDbContextExtension.cs +++ b/Bot.Rasa/EntityDbContextExtension.cs @@ -1,6 +1,5 @@ using Bot.Rasa.Agents; using Bot.Rasa.Intents; -using CustomEntityFoundation; using EntityFrameworkCore.BootKit; using Microsoft.EntityFrameworkCore; using System; @@ -12,19 +11,19 @@ namespace Bot.Rasa { public static class EntityDbContextExtension { - public static DbSet Agent(this EntityDbContext dc) + public static DbSet Agent(this Database dc) { - return dc.Table(); + return dc.Table(); } - public static DbSet Intent(this EntityDbContext dc) + public static DbSet Intent(this Database dc) { - return dc.Table(); + return dc.Table(); } - public static DbSet IntentExpression(this EntityDbContext dc) + public static DbSet IntentExpression(this Database dc) { - return dc.Table(); + return dc.Table(); } } } diff --git a/Bot.Rasa/Expressions/EntitiyOfSpeech.cs b/Bot.Rasa/Expressions/EntitiyOfSpeech.cs new file mode 100644 index 00000000..71efad2c --- /dev/null +++ b/Bot.Rasa/Expressions/EntitiyOfSpeech.cs @@ -0,0 +1,27 @@ +using EntityFrameworkCore.BootKit; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; + +namespace Bot.Rasa.Expressions +{ + [Table("Bot_EntityOfSpeech")] + public class EntitiyOfSpeech : DbRecord, IDbRecord + { + [Required] + [StringLength(36)] + public String ExpressionId { get; set; } + + public int Start { get; set; } + + [Required] + [MaxLength(128)] + public String Value { get; set; } + + [Required] + [MaxLength(64)] + public String Entity { get; set; } + } +} diff --git a/Bot.Rasa/Intents/Intent.cs b/Bot.Rasa/Intents/Intent.cs index d073a73c..99ed6839 100644 --- a/Bot.Rasa/Intents/Intent.cs +++ b/Bot.Rasa/Intents/Intent.cs @@ -1,5 +1,4 @@ -using CustomEntityFoundation.Entities; -using EntityFrameworkCore.BootKit; +using EntityFrameworkCore.BootKit; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -8,7 +7,8 @@ using System.Text; namespace Bot.Rasa.Intents { - public class RasaIntent : Entity, IDbRecord + [Table("Bot_Intent")] + public class Intent : DbRecord, IDbRecord { [Required] [StringLength(36)] @@ -21,6 +21,6 @@ namespace Bot.Rasa.Intents public String Description { get; set; } [ForeignKey("IntentId")] - public List Expressions { get; set; } + public List Expressions { get; set; } } } diff --git a/Bot.Rasa/Intents/IntentExpression.cs b/Bot.Rasa/Intents/IntentExpression.cs index d3860640..73b5ef84 100644 --- a/Bot.Rasa/Intents/IntentExpression.cs +++ b/Bot.Rasa/Intents/IntentExpression.cs @@ -1,5 +1,4 @@ -using CustomEntityFoundation; -using CustomEntityFoundation.Entities; +using Bot.Rasa.Expressions; using EntityFrameworkCore.BootKit; using Newtonsoft.Json; using System; @@ -11,8 +10,14 @@ using System.Text; namespace Bot.Rasa.Intents { - public class RasaIntentExpression : Entity, IDbRecord + [Table("Bot_IntentExpression")] + public class IntentExpression : DbRecord, IDbRecord { + public IntentExpression() + { + Entities = new List(); + } + [Required] [StringLength(36)] public String IntentId { get; set; } @@ -21,9 +26,12 @@ namespace Bot.Rasa.Intents [MaxLength(128)] public String Text { get; set; } - public override bool IsExist(EntityDbContext dc) + [ForeignKey("ExpressionId")] + public List Entities { get; set; } + + public bool IsExist(Database dc) { - return dc.Table().Any(x => x.IntentId == IntentId && x.Text == Text); + return dc.Table().Any(x => x.IntentId == IntentId && x.Text == Text); } } } diff --git a/Bot.Rasa/Models/UserSay.cs b/Bot.Rasa/Models/UserSay.cs index 0906531c..fba18a21 100644 --- a/Bot.Rasa/Models/UserSay.cs +++ b/Bot.Rasa/Models/UserSay.cs @@ -1,4 +1,5 @@ -using System; +using Bot.Rasa.Expressions; +using System; using System.Collections.Generic; using System.Text; @@ -6,7 +7,13 @@ namespace Bot.Rasa.Models { public class UserSay { + public UserSay() + { + Entities = new List(); + } + public String Text { get; set; } public String Intent { get; set; } + public List Entities { get; set; } } } diff --git a/Bot.UnitTest/AgentTest.cs b/Bot.UnitTest/AgentTest.cs index baa0454c..16f6ba2d 100644 --- a/Bot.UnitTest/AgentTest.cs +++ b/Bot.UnitTest/AgentTest.cs @@ -11,34 +11,35 @@ using System.Text; namespace Bot.UnitTest { [TestClass] - public class AgentTest : Database + public class AgentTest : TestEssential { 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 rasa = new RasaConsole(dc); - var agent = new RasaAgent - { - Id = PIZZA_BOT_ID, - Name = "Pizza Bot" - }; + var agent = rasa.RestoreAgent(PIZZA_BOT_ID); int row = dc.DbTran(() => rasa.CreateAgent(agent)); + if(row > 0) { - var generator = new GenerateTestData(); - dc.DbTran(() => generator.LoadData(dc, agent)); + //var result = rasa.Train(dc, agent.Id); } + + var loadedAgent = rasa.LoadAgent(agent.Id); + Assert.IsTrue(loadedAgent.Intents.Count == agent.Intents.Count); + + var response = rasa.TextRequest(agent.Id, "weather in Chicago tomorrow"); + Assert.IsTrue(response.Intent.Name == "weather"); } [TestMethod] public void TextRequest() { - var rasa = new RasaConsole(dc, Options); + var rasa = new RasaConsole(dc); 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"); @@ -47,7 +48,7 @@ namespace Bot.UnitTest [TestMethod] public void Train() { - var rasa = new RasaConsole(dc, Options); + var rasa = new RasaConsole(dc); rasa.Train(dc, PIZZA_BOT_ID); } } diff --git a/Bot.UnitTest/Database.cs b/Bot.UnitTest/Database.cs deleted file mode 100644 index fc6feeff..00000000 --- a/Bot.UnitTest/Database.cs +++ /dev/null @@ -1,30 +0,0 @@ -using CustomEntityFoundation; -using System; -using System.IO; - -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(); - } - } - - -} diff --git a/Bot.UnitTest/GenerateTestData.cs b/Bot.UnitTest/GenerateTestData.cs deleted file mode 100644 index a8bb3917..00000000 --- a/Bot.UnitTest/GenerateTestData.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Bot.Rasa; -using Bot.Rasa.Agents; -using Bot.Rasa.Intents; -using CustomEntityFoundation; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Bot.UnitTest -{ - public class GenerateTestData - { - public void LoadData(EntityDbContext dc, RasaAgent agent) - { - var intent = new RasaIntent - { - AgentId = agent.Id, - Name = "Weather", - Expressions = new List - { - new RasaIntentExpression { Text ="What is the weather like today in Chicago?" }, - new RasaIntentExpression { Text ="Is it will be rain?" }, - new RasaIntentExpression { Text ="It's windy outside?" }, - new RasaIntentExpression { Text ="It's very code there?" } - } - }; - - if (dc.Intent().Any(x => x.Name == intent.Name)) return; - - dc.Intent().Add(intent); - } - } -} diff --git a/Bot.UnitTest/TestEssential.cs b/Bot.UnitTest/TestEssential.cs new file mode 100644 index 00000000..ee839977 --- /dev/null +++ b/Bot.UnitTest/TestEssential.cs @@ -0,0 +1,34 @@ +using Bot.Rasa.Console; +using EntityFrameworkCore.BootKit; +using Microsoft.Data.Sqlite; +using System; +using System.IO; + +namespace Bot.UnitTest +{ + public abstract class TestEssential + { + protected Database dc { get; set; } + + public TestEssential() + { + RasaConsole.Options = new RasaOptions + { + HostUrl = "http://192.168.56.101:5000", + ContentRootPath = $"{Directory.GetCurrentDirectory()}\\..\\..\\..\\..\\Bot.WebStarter", + Assembles = new String[] { "Bot.Rasa" } + }; + + dc = new Database(); + + dc.BindDbContext(new DatabaseBind + { + MasterConnection = new SqliteConnection($"Data Source={RasaConsole.Options.ContentRootPath}\\App_Data\\bot-rasa.db"), + CreateDbIfNotExist = true, + AssemblyNames = new string[] { "Bot.Rasa" } + }); + } + } + + +} diff --git a/Bot.WebStarter/App_Data/DbInitializer/Agents/2b6a288e-d891-40c6-96ce-6a0cf324545c.json b/Bot.WebStarter/App_Data/DbInitializer/Agents/2b6a288e-d891-40c6-96ce-6a0cf324545c.json new file mode 100644 index 00000000..4e8a7fbd --- /dev/null +++ b/Bot.WebStarter/App_Data/DbInitializer/Agents/2b6a288e-d891-40c6-96ce-6a0cf324545c.json @@ -0,0 +1,61 @@ +{ + "name": "Weather Bot", + + "entity_types": [ + { + "name": "date", + "values": [ "today", "tomorrow", "yesterday", "now" ] + } + ], + + "entity_synonyms": [ + + ], + + "intents": [ + { + "name": "greet", + "expressions": [ + { "text": "Hi" }, + { "text": "Hey" }, + { "text": "Hello" }, + { "text": "How are you?" }, + { "text": "What's up?" }, + { "text": "How is going?" } + ] + }, + { + "name": "weather", + "expressions": [ + { + "text": "What is the weather like today in Chicago?", + "entities": [ + { + "start": 25, + "value": "today", + "entity": "date" + } + ] + }, + { + "text": "Will it be rain tomorrow in Beijing?", + "entities": [ + { + "start": 16, + "value": "tomorrow", + "entity": "date" + }, + { + "start": 28, + "value": "Beijing", + "entity": "location" + } + ] + }, + { "text": "It's windy outside?" }, + { "text": "It's very code there?" }, + { "text": "It's gonna be snow?" } + ] + } + ] +} \ No newline at end of file diff --git a/Bot.WebStarter/Bot.WebStarter.csproj b/Bot.WebStarter/Bot.WebStarter.csproj new file mode 100644 index 00000000..6c62ba3a --- /dev/null +++ b/Bot.WebStarter/Bot.WebStarter.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp2.0 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bot.WebStarter/Program.cs b/Bot.WebStarter/Program.cs new file mode 100644 index 00000000..56a33126 --- /dev/null +++ b/Bot.WebStarter/Program.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; + +namespace Bot.WebStarter +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build(); + } +} diff --git a/Bot.WebStarter/Settings/appsettings.json b/Bot.WebStarter/Settings/appsettings.json new file mode 100644 index 00000000..287e2813 --- /dev/null +++ b/Bot.WebStarter/Settings/appsettings.json @@ -0,0 +1,19 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Warning" + } + }, + "Console": { + "LogLevel": { + "Default": "Warning" + } + } + }, + + "Rasa": { + "Host": "http://192.168.56.101:5000" + } +} diff --git a/Bot.WebStarter/Settings/dbsettings.json b/Bot.WebStarter/Settings/dbsettings.json new file mode 100644 index 00000000..c7db88e6 --- /dev/null +++ b/Bot.WebStarter/Settings/dbsettings.json @@ -0,0 +1,10 @@ +{ + "Database": { + "Default": "Sqlite", + "ConnectionStrings": { + "InMemory": "DataSource=:memory:", + "Sqlite": "Data Source=|DataDirectory|\\bot-rasa.db;", + "SqlServer": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=bot-rasa;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False" + } + } +} \ No newline at end of file diff --git a/Bot.WebStarter/Startup.cs b/Bot.WebStarter/Startup.cs new file mode 100644 index 00000000..5dee6b04 --- /dev/null +++ b/Bot.WebStarter/Startup.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Bot.Rasa.Console; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Bot.WebStarter +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvc(); + + string db = RasaConsole.Configuration.GetSection("Database:Default").Value; + RasaConsole.Options = new RasaOptions + { + HostUrl = Configuration.GetSection("Rasa:Host").Value, + Assembles = new String[] { "Bot.Rasa" }, + ContentRootPath = env.ContentRootPath, + DbName = db, + DbConnectionString = Configuration.GetSection("Database:ConnectionStrings")[db] + }; + } + } +}