From d656f4a75f20506249768a3ee2bcf5205a9c347a Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Wed, 3 Oct 2018 01:00:07 -0500 Subject: [PATCH] dialogflow upload and training --- BotSharp.Core.UnitTest/AgentTest.cs | 3 +- BotSharp.Core.UnitTest/Performance/Spotify.cs | 4 +- BotSharp.Core/Abstractions/IBotPlatform.cs | 3 +- BotSharp.Core/Abstractions/INlpPipeline.cs | 3 +- BotSharp.Core/Abstractions/INlpPredict.cs | 6 +- BotSharp.Core/Abstractions/INlpProvider.cs | 6 +- BotSharp.Core/Abstractions/INlpTrain.cs | 6 +- BotSharp.Core/Agents/Agent.cs | 75 -------- BotSharp.Core/BotSharp.Core.csproj | 4 + BotSharp.Core/Engines/BotEngineBase.cs | 16 +- BotSharp.Core/Engines/BotPredictor.cs | 4 +- BotSharp.Core/Engines/BotSharp/BotSharpAi.cs | 5 +- .../Engines/BotSharp/BotSharpCRFNer.cs | 5 +- .../BotSharp/BotSharpIntentClassifier.cs | 6 +- .../Engines/BotSharp/BotSharpProvider.cs | 4 +- .../Engines/BotSharp/BotSharpTagger.cs | 6 +- .../Engines/BotSharp/BotSharpTokenizer.cs | 6 +- BotSharp.Core/Engines/BotTrainer.cs | 3 +- .../Engines/Jieba.NET/JiebaTagger.cs | 1 - .../Engines/Jieba.NET/JiebaTokenizer.cs | 1 - BotSharp.Core/PlatformBuilderBase.cs | 5 +- .../IAgentImporter.cs | 6 - BotSharp.Platform.Models/AgentBase.cs | 10 ++ .../MachineLearning}/AgentMlConfig.cs | 8 +- .../FacebookMessengerController.cs | 3 +- BotSharp.WebHost/Program.cs | 1 - BotSharp.WebHost/Startup.cs | 3 +- Platform.Articulate/ArticulateAi.cs | 5 +- .../Controllers/AgentController.cs | 1 - .../AgentImporterInDialogflow.cs | 57 ++---- Platform.Dialogflow/ApiAi.cs | 33 ---- Platform.Dialogflow/ApiAiBase.cs | 75 -------- .../Controllers/AgentController.cs | 13 +- .../Controllers/TrainController.cs | 42 ++--- Platform.Dialogflow/DialogflowAi.cs | 165 ++++++++++++++++++ Platform.Dialogflow/Models/AgentModel.cs | 22 +-- ...Agent.cs => DialogflowAgentImportModel.cs} | 2 +- Platform.Dialogflow/Models/DialogflowAi.cs | 35 ---- 38 files changed, 269 insertions(+), 384 deletions(-) delete mode 100644 BotSharp.Core/Agents/Agent.cs rename {BotSharp.Core/Agents => BotSharp.Platform.Models/MachineLearning}/AgentMlConfig.cs (74%) delete mode 100644 Platform.Dialogflow/ApiAi.cs delete mode 100644 Platform.Dialogflow/ApiAiBase.cs create mode 100644 Platform.Dialogflow/DialogflowAi.cs rename Platform.Dialogflow/Models/{DialogflowAgent.cs => DialogflowAgentImportModel.cs} (92%) delete mode 100644 Platform.Dialogflow/Models/DialogflowAi.cs diff --git a/BotSharp.Core.UnitTest/AgentTest.cs b/BotSharp.Core.UnitTest/AgentTest.cs index 669e4917..6e7a3b0a 100644 --- a/BotSharp.Core.UnitTest/AgentTest.cs +++ b/BotSharp.Core.UnitTest/AgentTest.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using EntityFrameworkCore.BootKit; using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/BotSharp.Core.UnitTest/Performance/Spotify.cs b/BotSharp.Core.UnitTest/Performance/Spotify.cs index 8a3f394a..82c68465 100644 --- a/BotSharp.Core.UnitTest/Performance/Spotify.cs +++ b/BotSharp.Core.UnitTest/Performance/Spotify.cs @@ -1,6 +1,6 @@ using Bigtree.Algorithm.Extensions; -using BotSharp.Core.Agents; using BotSharp.Core.Engines; +using BotSharp.Platform.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; @@ -40,7 +40,7 @@ namespace BotSharp.Core.UnitTest.Performance //double accuracy = correct / (Samples.Count + 0.0); } - private Agent LoadAgent() + private AgentBase LoadAgent() { //_platform = new BotSharpAi(); diff --git a/BotSharp.Core/Abstractions/IBotPlatform.cs b/BotSharp.Core/Abstractions/IBotPlatform.cs index f8e5299f..fcff5338 100644 --- a/BotSharp.Core/Abstractions/IBotPlatform.cs +++ b/BotSharp.Core/Abstractions/IBotPlatform.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Platform.Models; +using BotSharp.Platform.Models; using BotSharp.Platform.Models.AiRequest; using BotSharp.Platform.Models.AiResponse; using Newtonsoft.Json.Linq; diff --git a/BotSharp.Core/Abstractions/INlpPipeline.cs b/BotSharp.Core/Abstractions/INlpPipeline.cs index 3b556c3a..1b39ae61 100644 --- a/BotSharp.Core/Abstractions/INlpPipeline.cs +++ b/BotSharp.Core/Abstractions/INlpPipeline.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; using System; diff --git a/BotSharp.Core/Abstractions/INlpPredict.cs b/BotSharp.Core/Abstractions/INlpPredict.cs index dbac47b8..d6b76f98 100644 --- a/BotSharp.Core/Abstractions/INlpPredict.cs +++ b/BotSharp.Core/Abstractions/INlpPredict.cs @@ -1,5 +1,5 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; +using BotSharp.Platform.Models; using System; using System.Collections.Generic; using System.Text; @@ -9,6 +9,6 @@ namespace BotSharp.Core.Abstractions { public interface INlpPredict : INlpPipeline { - Task Predict(Agent agent, NlpDoc doc, PipeModel meta); + Task Predict(AgentBase agent, NlpDoc doc, PipeModel meta); } } diff --git a/BotSharp.Core/Abstractions/INlpProvider.cs b/BotSharp.Core/Abstractions/INlpProvider.cs index 5a7975cd..93bb24b7 100644 --- a/BotSharp.Core/Abstractions/INlpProvider.cs +++ b/BotSharp.Core/Abstractions/INlpProvider.cs @@ -1,5 +1,5 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; +using BotSharp.Platform.Models; using System; using System.Collections.Generic; using System.Text; @@ -9,6 +9,6 @@ namespace BotSharp.Core.Abstractions { public interface INlpProvider : INlpPipeline { - Task Load(Agent agent, PipeModel meta); + Task Load(AgentBase agent, PipeModel meta); } } diff --git a/BotSharp.Core/Abstractions/INlpTrain.cs b/BotSharp.Core/Abstractions/INlpTrain.cs index 7a8d7209..218c5a6e 100644 --- a/BotSharp.Core/Abstractions/INlpTrain.cs +++ b/BotSharp.Core/Abstractions/INlpTrain.cs @@ -1,5 +1,5 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; +using BotSharp.Platform.Models; using System; using System.Collections.Generic; using System.Text; @@ -16,6 +16,6 @@ namespace BotSharp.Core.Abstractions /// Intermediate result /// Meta data which is packed to model /// - Task Train(Agent agent, NlpDoc doc, PipeModel meta); + Task Train(AgentBase agent, NlpDoc doc, PipeModel meta); } } diff --git a/BotSharp.Core/Agents/Agent.cs b/BotSharp.Core/Agents/Agent.cs deleted file mode 100644 index 1e638fdb..00000000 --- a/BotSharp.Core/Agents/Agent.cs +++ /dev/null @@ -1,75 +0,0 @@ -using BotSharp.Core.Engines; -using BotSharp.Platform.Models; -using EntityFrameworkCore.BootKit; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Text; - -namespace BotSharp.Core.Agents -{ - [Table("Bot_Agent")] - public class Agent : DbRecord, IDbRecord - { - public Agent() - { - CreatedDate = DateTime.UtcNow; - } - - [Required] - [MaxLength(64)] - public String Name { get; set; } - - [MaxLength(256)] - public String Description { get; set; } - - public Boolean Published { get; set; } - - [Required] - [MaxLength(5)] - public String Language { get; set; } - - /// - /// Only access text/ audio rquest - /// - [StringLength(32)] - public String ClientAccessToken { get; set; } - - /// - /// Developer can access more APIs - /// - [StringLength(32)] - public String DeveloperAccessToken { get; set; } - - [ForeignKey("AgentId")] - public List Intents { get; set; } - - /*[ForeignKey("AgentId")] - [JsonProperty("entity_types")] - public List Entities { get; set; }*/ - - public String Birthday - { - get - { - return CreatedDate.ToShortDateString(); - } - } - - [Required] - public DateTime CreatedDate { get; set; } - - public Boolean IsSkillSet { get; set; } - - [ForeignKey("AgentId")] - public AgentMlConfig MlConfig { get; set; } - - [NotMapped] - public TrainingCorpus Corpus { get; set; } - - [ForeignKey("AgentId")] - public List Integrations { get; set; } - } -} diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj index ba2800f8..2dee05d0 100644 --- a/BotSharp.Core/BotSharp.Core.csproj +++ b/BotSharp.Core/BotSharp.Core.csproj @@ -89,4 +89,8 @@ If you feel that this project is helpful to you, please Star on the project, we + + + + diff --git a/BotSharp.Core/Engines/BotEngineBase.cs b/BotSharp.Core/Engines/BotEngineBase.cs index 43bffcb1..ee0a59e1 100644 --- a/BotSharp.Core/Engines/BotEngineBase.cs +++ b/BotSharp.Core/Engines/BotEngineBase.cs @@ -1,9 +1,9 @@ -using BotSharp.Core.Agents; -using BotSharp.Models.NLP; +using BotSharp.Models.NLP; using BotSharp.Platform.Abstraction; using BotSharp.Platform.Models; using BotSharp.Platform.Models.AiRequest; using BotSharp.Platform.Models.AiResponse; +using BotSharp.Platform.Models.Intents; using DotNetToolkit; using EntityFrameworkCore.BootKit; using Microsoft.EntityFrameworkCore; @@ -26,7 +26,7 @@ namespace BotSharp.Core.Engines { protected Database dc; - protected Agent agent { get; set; } + protected AgentBase agent { get; set; } public BotEngineBase() { @@ -75,7 +75,7 @@ namespace BotSharp.Core.Engines }; } - public TrainingCorpus GetIntentExpressions(Agent agent) + /*public TrainingCorpus GetIntentExpressions(AgentBase agent) { TrainingCorpus corpus = new TrainingCorpus() { @@ -83,7 +83,7 @@ namespace BotSharp.Core.Engines Entities = new List() }; - //var expressParts = new List(); + var expressParts = new List(); var intents = agent.Intents; @@ -116,7 +116,7 @@ namespace BotSharp.Core.Engines say.Entities.Add(part); // assemble entity synonmus - /*if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text)) + if (!trainingData.Entities.Any(y => y.EntityType == x.Alias && y.EntityValue == x.Text)) { var allSynonyms = (from e in dc.Table() join ee in dc.Table() on e.Id equals ee.EntityId @@ -132,7 +132,7 @@ namespace BotSharp.Core.Engines }; trainingData.Entities.Add(te); - }*/ + } }); corpus.UserSays.Add(say); @@ -143,7 +143,7 @@ namespace BotSharp.Core.Engines corpus.UserSays = corpus.UserSays.Where(x => x.Intent != "Default Fallback Intent").ToList(); return corpus; - } + }*/ public TrainingCorpus GetIntentExpressions() { diff --git a/BotSharp.Core/Engines/BotPredictor.cs b/BotSharp.Core/Engines/BotPredictor.cs index 4ebf0643..df8ebf21 100644 --- a/BotSharp.Core/Engines/BotPredictor.cs +++ b/BotSharp.Core/Engines/BotPredictor.cs @@ -1,5 +1,5 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; +using BotSharp.Platform.Models; using BotSharp.Platform.Models.AiRequest; using DotNetToolkit; using Microsoft.Extensions.Configuration; @@ -19,7 +19,7 @@ namespace BotSharp.Core.Engines { public class BotPredictor { - public async Task Predict(Agent agent, AiRequest request) + public async Task Predict(AgentBase agent, AiRequest request) { // load model var dir = Path.Combine(request.AgentDir, request.Model); diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs b/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs index e3d622e9..f4fa1db9 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpAi.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; -using BotSharp.Core.Agents; using BotSharp.Platform.Models; namespace BotSharp.Core.Engines.BotSharp @@ -11,9 +10,9 @@ namespace BotSharp.Core.Engines.BotSharp { public override async Task Train(BotTrainOptions options) { - agent.Corpus = GetIntentExpressions(agent); + /*agent.Corpus = GetIntentExpressions(agent); var trainer = new BotTrainer(agent.Id, dc); - await trainer.Train(agent, options); + await trainer.Train(agent, options);*/ } } } diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpCRFNer.cs b/BotSharp.Core/Engines/BotSharp/BotSharpCRFNer.cs index 050dc9b5..f163047f 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpCRFNer.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpCRFNer.cs @@ -1,5 +1,4 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using Bigtree.Algorithm.CRFLite; using Bigtree.Algorithm.CRFLite.Decoder; using Bigtree.Algorithm.CRFLite.Encoder; @@ -22,7 +21,7 @@ namespace BotSharp.Core.Engines.BotSharp public IConfiguration Configuration { get; set; } public PipeSettings Settings { get; set; } - public async Task Train(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Train(AgentBase agent, NlpDoc doc, PipeModel meta) { var corpus = agent.Corpus; @@ -157,7 +156,7 @@ namespace BotSharp.Core.Engines.BotSharp return trainingTuple; } - public async Task Predict(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Predict(AgentBase agent, NlpDoc doc, PipeModel meta) { var decoder = new CRFDecoder(); var options = new DecoderOptions diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpIntentClassifier.cs b/BotSharp.Core/Engines/BotSharp/BotSharpIntentClassifier.cs index a2cb6604..9810289d 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpIntentClassifier.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpIntentClassifier.cs @@ -1,8 +1,8 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.NLP; using BotSharp.NLP.Classify; using BotSharp.NLP.Txt2Vec; +using BotSharp.Platform.Models; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; using System; @@ -20,7 +20,7 @@ namespace BotSharp.Core.Engines.BotSharp public PipeSettings Settings { get; set; } private ClassifierFactory _classifier; - public async Task Train(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Train(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(meta); @@ -38,7 +38,7 @@ namespace BotSharp.Core.Engines.BotSharp return true; } - public async Task Predict(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Predict(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(meta); diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpProvider.cs b/BotSharp.Core/Engines/BotSharp/BotSharpProvider.cs index 17e6d07c..4926cfbf 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpProvider.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpProvider.cs @@ -1,5 +1,5 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; +using BotSharp.Platform.Models; using Microsoft.Extensions.Configuration; using Newtonsoft.Json.Linq; using System; @@ -14,7 +14,7 @@ namespace BotSharp.Core.Engines.BotSharp public IConfiguration Configuration { get; set; } public PipeSettings Settings { get; set; } - public async Task Load(Agent agent, PipeModel meta) + public async Task Load(AgentBase agent, PipeModel meta) { meta.Meta = JObject.FromObject(new { version = "0.1.0" }); diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpTagger.cs b/BotSharp.Core/Engines/BotSharp/BotSharpTagger.cs index 69396724..2a45a01d 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpTagger.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpTagger.cs @@ -1,9 +1,9 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.NLP; using BotSharp.NLP.Corpus; using BotSharp.NLP.Tag; using BotSharp.NLP.Tokenize; +using BotSharp.Platform.Models; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; @@ -25,7 +25,7 @@ namespace BotSharp.Core.Engines.BotSharp } - public async Task Predict(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Predict(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(); @@ -38,7 +38,7 @@ namespace BotSharp.Core.Engines.BotSharp return true; } - public async Task Train(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Train(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(); diff --git a/BotSharp.Core/Engines/BotSharp/BotSharpTokenizer.cs b/BotSharp.Core/Engines/BotSharp/BotSharpTokenizer.cs index 0ca762a5..1d72057a 100644 --- a/BotSharp.Core/Engines/BotSharp/BotSharpTokenizer.cs +++ b/BotSharp.Core/Engines/BotSharp/BotSharpTokenizer.cs @@ -1,7 +1,7 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.NLP; using BotSharp.NLP.Tokenize; +using BotSharp.Platform.Models; using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; @@ -21,7 +21,7 @@ namespace BotSharp.Core.Engines.BotSharp } - public async Task Predict(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Predict(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(); @@ -36,7 +36,7 @@ namespace BotSharp.Core.Engines.BotSharp return true; } - public async Task Train(Agent agent, NlpDoc doc, PipeModel meta) + public async Task Train(AgentBase agent, NlpDoc doc, PipeModel meta) { Init(); diff --git a/BotSharp.Core/Engines/BotTrainer.cs b/BotSharp.Core/Engines/BotTrainer.cs index 849cf5e1..04cfca23 100644 --- a/BotSharp.Core/Engines/BotTrainer.cs +++ b/BotSharp.Core/Engines/BotTrainer.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.Platform.Models; using DotNetToolkit; using EntityFrameworkCore.BootKit; @@ -33,7 +32,7 @@ namespace BotSharp.Core.Engines this.agentId = agentId; } - public async Task Train(Agent agent, BotTrainOptions options) + public async Task Train(AgentBase agent, BotTrainOptions options) { var data = new NlpDoc(); diff --git a/BotSharp.Core/Engines/Jieba.NET/JiebaTagger.cs b/BotSharp.Core/Engines/Jieba.NET/JiebaTagger.cs index 30827d16..8507be0d 100644 --- a/BotSharp.Core/Engines/Jieba.NET/JiebaTagger.cs +++ b/BotSharp.Core/Engines/Jieba.NET/JiebaTagger.cs @@ -1,5 +1,4 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.NLP; using BotSharp.NLP.Tag; using JiebaNet.Segmenter; diff --git a/BotSharp.Core/Engines/Jieba.NET/JiebaTokenizer.cs b/BotSharp.Core/Engines/Jieba.NET/JiebaTokenizer.cs index de797544..ef1862ee 100644 --- a/BotSharp.Core/Engines/Jieba.NET/JiebaTokenizer.cs +++ b/BotSharp.Core/Engines/Jieba.NET/JiebaTokenizer.cs @@ -1,5 +1,4 @@ using BotSharp.Core.Abstractions; -using BotSharp.Core.Agents; using BotSharp.NLP.Tokenize; using JiebaNet.Segmenter; using Microsoft.Extensions.Configuration; diff --git a/BotSharp.Core/PlatformBuilderBase.cs b/BotSharp.Core/PlatformBuilderBase.cs index 96f717bf..56618ee8 100644 --- a/BotSharp.Core/PlatformBuilderBase.cs +++ b/BotSharp.Core/PlatformBuilderBase.cs @@ -45,10 +45,7 @@ namespace BotSharp.Core // Load system buildin entities importer.LoadBuildinEntities(agent); - // Generate corpus - importer.AssembleTrainData(agent); - - return default(TAgent); + return agent; } private AgentImportHeader LoadMeta(string dataDir) diff --git a/BotSharp.Platform.Abstraction/IAgentImporter.cs b/BotSharp.Platform.Abstraction/IAgentImporter.cs index b38a5b4b..1c59a340 100644 --- a/BotSharp.Platform.Abstraction/IAgentImporter.cs +++ b/BotSharp.Platform.Abstraction/IAgentImporter.cs @@ -35,11 +35,5 @@ namespace BotSharp.Platform.Abstraction /// /// void LoadBuildinEntities(TAgent agent); - - /// - /// generate training data - /// - /// - void AssembleTrainData(TAgent agent); } } diff --git a/BotSharp.Platform.Models/AgentBase.cs b/BotSharp.Platform.Models/AgentBase.cs index cbff5be6..7da90b26 100644 --- a/BotSharp.Platform.Models/AgentBase.cs +++ b/BotSharp.Platform.Models/AgentBase.cs @@ -7,6 +7,11 @@ namespace BotSharp.Platform.Models { public abstract class AgentBase { + public AgentBase() + { + CreatedDate = DateTime.UtcNow; + } + /// /// Guid /// @@ -32,5 +37,10 @@ namespace BotSharp.Platform.Models [Required] [MaxLength(5)] public String Language { get; set; } + + [Required] + public DateTime CreatedDate { get; set; } + + public TrainingCorpus Corpus { get; set; } } } diff --git a/BotSharp.Core/Agents/AgentMlConfig.cs b/BotSharp.Platform.Models/MachineLearning/AgentMlConfig.cs similarity index 74% rename from BotSharp.Core/Agents/AgentMlConfig.cs rename to BotSharp.Platform.Models/MachineLearning/AgentMlConfig.cs index e2d75ed6..13ab2740 100644 --- a/BotSharp.Core/Agents/AgentMlConfig.cs +++ b/BotSharp.Platform.Models/MachineLearning/AgentMlConfig.cs @@ -1,14 +1,12 @@ -using EntityFrameworkCore.BootKit; -using System; +using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text; -namespace BotSharp.Core.Agents +namespace BotSharp.Platform.Models.MachineLearning { - [Table("Bot_AgentMlConfig")] - public class AgentMlConfig : DbRecord, IDbRecord + public class AgentMlConfig { [Required] [StringLength(36)] diff --git a/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs b/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs index def0e9ea..8545f3a5 100644 --- a/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs +++ b/BotSharp.RestApi/Integrations/FacebookMessenger/FacebookMessengerController.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using BotSharp.NLP; using BotSharp.Platform.Models; using BotSharp.RestApi.Integrations.FacebookMessenger; diff --git a/BotSharp.WebHost/Program.cs b/BotSharp.WebHost/Program.cs index c03fcd8d..34198d19 100644 --- a/BotSharp.WebHost/Program.cs +++ b/BotSharp.WebHost/Program.cs @@ -18,7 +18,6 @@ namespace BotSharp.WebHost .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; - Console.WriteLine($"ContentRootPath: {env.ContentRootPath}"); string dir = Path.GetFullPath(env.ContentRootPath); string settingsFolder = Path.Combine(dir, "Settings"); diff --git a/BotSharp.WebHost/Startup.cs b/BotSharp.WebHost/Startup.cs index 9696c2a2..2a961c54 100644 --- a/BotSharp.WebHost/Startup.cs +++ b/BotSharp.WebHost/Startup.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using DotNetToolkit; using DotNetToolkit.JwtHelper; using EntityFrameworkCore.BootKit; diff --git a/Platform.Articulate/ArticulateAi.cs b/Platform.Articulate/ArticulateAi.cs index 127b6318..0f290aea 100644 --- a/Platform.Articulate/ArticulateAi.cs +++ b/Platform.Articulate/ArticulateAi.cs @@ -1,5 +1,4 @@ using BotSharp.Core; -using BotSharp.Core.Agents; using BotSharp.Core.Engines; using BotSharp.Models.NLP; using BotSharp.Platform.Abstraction; @@ -144,7 +143,7 @@ namespace Platform.Articulate var modelPath = Path.Combine(projectPath, model); var trainer = new BotTrainer(); - var parsedAgent = agent.ToObject(); + var parsedAgent = agent.ToObject(); var intents = new List>(); @@ -211,7 +210,7 @@ namespace Platform.Articulate var agent = GetAgentById(request.AgentId); var preditor = new BotPredictor(); - var doc = preditor.Predict(agent.ToObject(), request).Result; + var doc = preditor.Predict(agent, request).Result; var parameters = new Dictionary(); if (doc.Sentences[0].Entities == null) diff --git a/Platform.Articulate/Controllers/AgentController.cs b/Platform.Articulate/Controllers/AgentController.cs index a088f89b..256474cf 100644 --- a/Platform.Articulate/Controllers/AgentController.cs +++ b/Platform.Articulate/Controllers/AgentController.cs @@ -1,5 +1,4 @@ using BotSharp.Core; -using BotSharp.Core.Agents; using BotSharp.Core.Engines; using BotSharp.Platform.Abstraction; using BotSharp.Platform.Models; diff --git a/Platform.Dialogflow/AgentImporterInDialogflow.cs b/Platform.Dialogflow/AgentImporterInDialogflow.cs index 3736be34..b29673eb 100644 --- a/Platform.Dialogflow/AgentImporterInDialogflow.cs +++ b/Platform.Dialogflow/AgentImporterInDialogflow.cs @@ -3,11 +3,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; -using BotSharp.Core.Agents; using BotSharp.Platform.Abstraction; using BotSharp.Platform.Models; using BotSharp.Platform.Models.AiResponse; using BotSharp.Platform.Models.Intents; +using BotSharp.Platform.Models.MachineLearning; using DotNetToolkit; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -32,12 +32,12 @@ namespace Platform.Dialogflow { // load agent profile string data = File.ReadAllText(Path.Combine(AgentDir, "agent.json")); - var agent = JsonConvert.DeserializeObject(data); + var agent = JsonConvert.DeserializeObject(data); agent.Name = agentHeader.Name; agent.Id = agentHeader.Id; var result = agent.ToObject(); - /*result.ClientAccessToken = agentHeader.ClientAccessToken; + result.ClientAccessToken = agentHeader.ClientAccessToken; result.DeveloperAccessToken = agentHeader.DeveloperAccessToken; result.MlConfig = agent.ToObject(); @@ -47,14 +47,14 @@ namespace Platform.Dialogflow { agentHeader.Integrations.ForEach(x => x.AgentId = agent.Id); result.Integrations = agentHeader.Integrations; - }*/ + } return result; } public void LoadCustomEntities(TAgent agent) { - //agent.Entities = new List(); + agent.Entities = new List(); string entityDir = Path.Combine(AgentDir, "entities"); if (!Directory.Exists(entityDir)) return; @@ -82,14 +82,14 @@ namespace Platform.Dialogflow } var entityType = entity.ToObject(); - //agent.Entities.Add(entityType); + agent.Entities.Add(entityType); } }); } public void LoadIntents(TAgent agent) { - //agent.Intents = new List(); + agent.Intents = new List(); string intentDir = Path.Combine(AgentDir, "intents"); if (!Directory.Exists(intentDir)) return; @@ -109,7 +109,7 @@ namespace Platform.Dialogflow var intent = JsonConvert.DeserializeObject(intentJson); var newIntent = ImportIntentUserSays(agent, intent, fileName); - //agent.Intents.Add(newIntent); + agent.Intents.Add(newIntent); } }); } @@ -239,7 +239,7 @@ namespace Platform.Dialogflow public void LoadBuildinEntities(TAgent agent) { - /*agent.Intents.ForEach(intent => + agent.Intents.ForEach(intent => { if (intent.UserSays != null) { @@ -254,7 +254,7 @@ namespace Platform.Dialogflow }); } - });*/ + }); } private void LoadBuildinEntityTypePerUserSay(TAgent agent, IntentExpressionPart data) @@ -263,17 +263,17 @@ namespace Platform.Dialogflow if (existedEntityType == null) { - /*existedEntityType = new EntityType + existedEntityType = new EntityType { Name = data.Meta, Entries = new List(), IsOverridable = true - };*/ + }; agent.Entities.Add(existedEntityType); } - /*var entries = existedEntityType.Entries.Select(x => x.Value.ToLower()).ToList(); + var entries = existedEntityType.Entries.Select(x => x.Value.ToLower()).ToList(); if (!entries.Contains(data.Text.ToLower())) { existedEntityType.Entries.Add(new EntityEntry @@ -287,36 +287,7 @@ namespace Platform.Dialogflow } } }); - }*/ - } - - public void AssembleTrainData(TAgent agent) - { - // convert agent to training corpus - /*agent.Corpus = new TrainingCorpus - { - Entities = new List(), - UserSays = new List>() - }; - - agent.Intents.ForEach(intent => - { - intent.UserSays.ForEach(say => { - agent.Corpus.UserSays.Add(new TrainingIntentExpression - { - Intent = intent.Name, - Text = String.Join("", say.Data.Select(x => x.Text)), - Entities = say.Data.Where(x => !String.IsNullOrEmpty(x.Meta)) - .Select(x => new TrainingIntentExpressionPart - { - Value = x.Text, - Entity = x.Meta, - Start = x.Start - }) - .ToList() - }); - }); - });*/ + } } } } diff --git a/Platform.Dialogflow/ApiAi.cs b/Platform.Dialogflow/ApiAi.cs deleted file mode 100644 index 412ecb8b..00000000 --- a/Platform.Dialogflow/ApiAi.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Platform.Dialogflow.Models; -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace BotSharp.Core.Engines.Dialogflow -{ - public class ApiAi : ApiAiBase - { - private AIDataService dataService; - - public AIResponse TextRequest(AIRequest request) - { - if (request == null) - { - throw new ArgumentNullException("request"); - } - - if(dataService == null) - { - // dataService = new AIDataService(AiConfig); - } - - return dataService.Request(request); - } - - public void Train() - { - - } - } -} diff --git a/Platform.Dialogflow/ApiAiBase.cs b/Platform.Dialogflow/ApiAiBase.cs deleted file mode 100644 index 82d130a6..00000000 --- a/Platform.Dialogflow/ApiAiBase.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace BotSharp.Core.Engines.Dialogflow -{ - public class ApiAiBase - { - protected float[] TrimSilence(float[] samples) - { - if (samples == null) - { - return null; - } - - const float min = 0.000001f; - - var startIndex = 0; - var endIndex = samples.Length; - - for (var i = 0; i < samples.Length; i++) - { - - if (Math.Abs(samples[i]) > min) - { - startIndex = i; - break; - } - } - - for (var i = samples.Length - 1; i > 0; i--) - { - if (Math.Abs(samples[i]) > min) - { - endIndex = i; - break; - } - } - - if (endIndex <= startIndex) - { - return null; - } - - var result = new float[endIndex - startIndex]; - Array.Copy(samples, startIndex, result, 0, endIndex - startIndex); - return result; - - } - - protected static byte[] ConvertArrayShortToBytes(short[] array) - { - var numArray = new byte[array.Length * 2]; - Buffer.BlockCopy(array, 0, numArray, 0, numArray.Length); - return numArray; - } - - protected static short[] ConvertIeeeToPcm16(float[] source) - { - var resultBuffer = new short[source.Length]; - for (var i = 0; i < source.Length; i++) - { - var f = source[i] * 32768f; - - if (f > (double)short.MaxValue) - f = short.MaxValue; - else if (f < (double)short.MinValue) - f = short.MinValue; - resultBuffer[i] = Convert.ToInt16(f); - } - - return resultBuffer; - } - } -} diff --git a/Platform.Dialogflow/Controllers/AgentController.cs b/Platform.Dialogflow/Controllers/AgentController.cs index 57061926..38a64fa9 100644 --- a/Platform.Dialogflow/Controllers/AgentController.cs +++ b/Platform.Dialogflow/Controllers/AgentController.cs @@ -1,5 +1,4 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using DotNetToolkit; using EntityFrameworkCore.BootKit; using Microsoft.AspNetCore.Http; @@ -58,15 +57,19 @@ namespace Platform.Dialogflow.Controllers } string dest = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", uploadedFile.FileName.Split('.').First(), "tmp"); - System.IO.Directory.Delete(dest, true); + if (Directory.Exists(dest)) + { + System.IO.Directory.Delete(dest, true); + } Console.WriteLine($"Extract zip file to {dest}"); ZipFile.ExtractToDirectory(filePath, dest); System.IO.File.Delete(filePath); - Console.WriteLine($"LoadAgentFromFile {dest}"); + Console.WriteLine($"Loading agent from folder {dest}"); var agent = builder.LoadAgentFromFile>(dest); + builder.SaveAgent(agent); return Ok(agent.Id); } @@ -77,7 +80,7 @@ namespace Platform.Dialogflow.Controllers /// /// [HttpGet("{agentId}")] - public ActionResult Dump([FromRoute] String agentId) + public ActionResult Dump([FromRoute] String agentId) { return Ok(); } diff --git a/Platform.Dialogflow/Controllers/TrainController.cs b/Platform.Dialogflow/Controllers/TrainController.cs index 30360cc0..0978a705 100644 --- a/Platform.Dialogflow/Controllers/TrainController.cs +++ b/Platform.Dialogflow/Controllers/TrainController.cs @@ -1,10 +1,11 @@ -using BotSharp.Core.Agents; -using BotSharp.Core.Engines; +using BotSharp.Core.Engines; using BotSharp.Platform.Models; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; +using Platform.Dialogflow.Models; using System; using System.Collections.Generic; using System.IO; @@ -23,40 +24,29 @@ namespace Platform.Dialogflow.Controllers [Route("v1/[controller]")] public class TrainController : ControllerBase { - private readonly IBotPlatform _platform; + private DialogflowAi builder; - /// - /// Initialize dialog controller and get a platform instance - /// - /// - public TrainController(IBotPlatform platform) + public TrainController(IConfiguration configuration) { - _platform = platform; + builder = new DialogflowAi(); + builder.PlatformConfig = configuration.GetSection("DialogflowAi"); } [HttpPost] - public async Task> Train([FromQuery] string agentId) + public async Task> Train([FromQuery] string agentId) { - var trainer = new BotTrainer(); + var agent = builder.GetAgentById(agentId); - // save corpus to agent dir - var projectPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", agentId); - var model = Directory.GetDirectories(projectPath).Where(x => x.Contains("model_")).Last().Split(Path.DirectorySeparatorChar).Last(); - string dataDir = Path.Combine(projectPath, model); - - Console.WriteLine($"LoadAgentFromFile {dataDir}"); - - /*var agent = _platform.LoadAgentFromFile(dataDir); - - var info = await trainer.Train(agent, new BotTrainOptions + if(agent == null) { - AgentDir = projectPath, - Model = model - }); + agent = builder.GetAgentByName(agentId); + } - return Ok(new { info = info });*/ + var corpus = builder.ExtractorCorpus(agent); - return Ok(); + await builder.Train(agent, corpus); + + return agent; } } #endif diff --git a/Platform.Dialogflow/DialogflowAi.cs b/Platform.Dialogflow/DialogflowAi.cs new file mode 100644 index 00000000..3a81d890 --- /dev/null +++ b/Platform.Dialogflow/DialogflowAi.cs @@ -0,0 +1,165 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BotSharp.Core; +using BotSharp.Core.Engines; +using BotSharp.NLP; +using BotSharp.Platform.Abstraction; +using BotSharp.Platform.Models; +using BotSharp.Platform.Models.AiRequest; +using BotSharp.Platform.Models.AiResponse; +using DotNetToolkit; +using Platform.Dialogflow.Models; + +namespace Platform.Dialogflow +{ + public class DialogflowAi : + PlatformBuilderBase, + IPlatformBuilder + where TAgent : AgentModel + { + public TrainingCorpus ExtractorCorpus(TAgent agent) + { + var corpus = new TrainingCorpus + { + Entities = new List(), + UserSays = new List>() + }; + + agent.Entities.ForEach(entity => + { + corpus.Entities.Add(new TrainingEntity + { + Entity = entity.Name, + Values = entity.Entries.Select(x => new TrainingEntitySynonym + { + Value = x.Value, + Synonyms = x.Synonyms.Select(y => y.Synonym).ToList() + }).ToList() + }); + }); + + agent.Intents.ForEach(intent => + { + intent.UserSays.ForEach(say => { + corpus.UserSays.Add(new TrainingIntentExpression + { + Intent = intent.Name, + Text = String.Join("", say.Data.Select(x => x.Text)), + Entities = say.Data.Where(x => !String.IsNullOrEmpty(x.Meta)) + .Select(x => new TrainingIntentExpressionPart + { + Value = x.Text, + Entity = x.Meta, + Start = x.Start + }) + .ToList() + }); + }); + }); + + return corpus; + } + + public AiResponse TextRequest(AiRequest request) + { + var dataService = new AIDataService(new AIConfiguration("TOKEN", SupportedLanguage.English) + { + AgentId = request.AgentId, + Language = SupportedLanguage.English, + SessionId = request.SessionId + }); + + var response = dataService.Request(new AIRequest + { + SessionId = request.SessionId, + Query = new string[] { request.Text } + }); + + return response.ToObject(); + } + + public async Task Train(TAgent agent, TrainingCorpus corpus) + { + var trainer = new BotTrainer(); + + var trainOptions = new BotTrainOptions + { + //AgentDir = projectPath, + //Model = model + }; + + var info = await trainer.Train(agent, trainOptions); + + return true; + } + + protected float[] TrimSilence(float[] samples) + { + if (samples == null) + { + return null; + } + + const float min = 0.000001f; + + var startIndex = 0; + var endIndex = samples.Length; + + for (var i = 0; i < samples.Length; i++) + { + + if (Math.Abs(samples[i]) > min) + { + startIndex = i; + break; + } + } + + for (var i = samples.Length - 1; i > 0; i--) + { + if (Math.Abs(samples[i]) > min) + { + endIndex = i; + break; + } + } + + if (endIndex <= startIndex) + { + return null; + } + + var result = new float[endIndex - startIndex]; + Array.Copy(samples, startIndex, result, 0, endIndex - startIndex); + return result; + + } + + protected static byte[] ConvertArrayShortToBytes(short[] array) + { + var numArray = new byte[array.Length * 2]; + Buffer.BlockCopy(array, 0, numArray, 0, numArray.Length); + return numArray; + } + + protected static short[] ConvertIeeeToPcm16(float[] source) + { + var resultBuffer = new short[source.Length]; + for (var i = 0; i < source.Length; i++) + { + var f = source[i] * 32768f; + + if (f > (double)short.MaxValue) + f = short.MaxValue; + else if (f < (double)short.MinValue) + f = short.MinValue; + resultBuffer[i] = Convert.ToInt16(f); + } + + return resultBuffer; + } + } +} diff --git a/Platform.Dialogflow/Models/AgentModel.cs b/Platform.Dialogflow/Models/AgentModel.cs index 0682371f..312f3e07 100644 --- a/Platform.Dialogflow/Models/AgentModel.cs +++ b/Platform.Dialogflow/Models/AgentModel.cs @@ -1,6 +1,6 @@ -using BotSharp.Core.Agents; -using BotSharp.Platform.Models; +using BotSharp.Platform.Models; using BotSharp.Platform.Models.Intents; +using BotSharp.Platform.Models.MachineLearning; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -13,22 +13,11 @@ namespace Platform.Dialogflow.Models { public AgentModel() { - CreatedDate = DateTime.UtcNow; + } - [Required] - [MaxLength(64)] - public String Name { get; set; } - - [MaxLength(256)] - public String Description { get; set; } - public Boolean Published { get; set; } - [Required] - [MaxLength(5)] - public String Language { get; set; } - /// /// Only access text/ audio rquest /// @@ -54,15 +43,10 @@ namespace Platform.Dialogflow.Models } } - [Required] - public DateTime CreatedDate { get; set; } - public Boolean IsSkillSet { get; set; } public AgentMlConfig MlConfig { get; set; } - public TrainingCorpus Corpus { get; set; } - public List Integrations { get; set; } } } diff --git a/Platform.Dialogflow/Models/DialogflowAgent.cs b/Platform.Dialogflow/Models/DialogflowAgentImportModel.cs similarity index 92% rename from Platform.Dialogflow/Models/DialogflowAgent.cs rename to Platform.Dialogflow/Models/DialogflowAgentImportModel.cs index 5ef890e4..166c0f64 100644 --- a/Platform.Dialogflow/Models/DialogflowAgent.cs +++ b/Platform.Dialogflow/Models/DialogflowAgentImportModel.cs @@ -4,7 +4,7 @@ using System.Text; namespace Platform.Dialogflow.Models { - public class DialogflowAgent + public class DialogflowAgentImportModel { public String Id { get; set; } public String Name { get; set; } diff --git a/Platform.Dialogflow/Models/DialogflowAi.cs b/Platform.Dialogflow/Models/DialogflowAi.cs deleted file mode 100644 index 7b10b377..00000000 --- a/Platform.Dialogflow/Models/DialogflowAi.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using BotSharp.Core; -using BotSharp.Core.Engines; -using BotSharp.Platform.Abstraction; -using BotSharp.Platform.Models; -using BotSharp.Platform.Models.AiRequest; -using BotSharp.Platform.Models.AiResponse; -using Platform.Dialogflow.Models; - -namespace Platform.Dialogflow.Models -{ - public class DialogflowAi : - PlatformBuilderBase, - IPlatformBuilder - where TAgent : AgentModel - { - public TrainingCorpus ExtractorCorpus(TAgent agent) - { - throw new NotImplementedException(); - } - - public AiResponse TextRequest(AiRequest request) - { - throw new NotImplementedException(); - } - - public Task Train(TAgent agent, TrainingCorpus corpus) - { - throw new NotImplementedException(); - } - } -}