diff --git a/BotSharp.Core/Engines/NERs/WitAiEntityRecognizer.cs b/BotSharp.Core/Engines/NERs/WitAiEntityRecognizer.cs index b0a91ba6..a13029b4 100644 --- a/BotSharp.Core/Engines/NERs/WitAiEntityRecognizer.cs +++ b/BotSharp.Core/Engines/NERs/WitAiEntityRecognizer.cs @@ -1,11 +1,21 @@ using BotSharp.Core.Abstractions; +using BotSharp.Core.Agents; +using BotSharp.MachineLearning.NLP; +using DotNetToolkit; +using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using RestSharp; using System; using System.Collections.Generic; +using System.Linq; using System.Text; +using System.Threading.Tasks; namespace BotSharp.Core.Engines.NERs { - public class WitAiEntityRecognizer : INlpNer + public class WitAiEntityRecognizer : INlpPipeline, INlpNer { public List Ontologies { @@ -18,5 +28,72 @@ namespace BotSharp.Core.Engines.NERs }; } } + + public IConfiguration Configuration { get; set; } + public PipeSettings Settings { get; set; } + + public async Task Predict(Agent agent, NlpDoc doc, PipeModel meta) + { + var config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration"); + var client = new RestClient($"{config.GetSection("WitAi:url").Value}"); + var request = new RestRequest(config.GetSection("WitAi:resource").Value, Method.GET); + request.AddHeader("Authorization", "Bearer " + config.GetSection("WitAi:serverAccessToken").Value); + request.AddQueryParameter("v", config.GetSection("WitAi:version").Value); + request.AddQueryParameter("q", doc.Sentences[0].Text); + request.AddQueryParameter("verbose", "true"); + request.AddQueryParameter("autosuggest", "true"); + + var result = client.Execute(request); + + var entities = result.Data.Entities[0]; + if(entities.Datetime != null) + { + doc.Sentences[0].Entities.AddRange(entities.Datetime.Select(x => Map(x))); + } + + if(entities.Location != null) + { + doc.Sentences[0].Entities.AddRange(entities.Location.Select(x => Map(x))); + } + + return true; + } + + private NlpEntity Map(WitAiEntity entity) + { + return new NlpEntity + { + Confidence = entity.Confidence, + Start = entity.Start, + Value = entity.Value, + Entity = entity.Entity + }; + } + + public async Task Train(Agent agent, NlpDoc doc, PipeModel meta) + { + return true; + } + + private class WitAiResponse + { + public List Entities { get; set; } + } + + private class WitAiEntityResponse + { + public List Location { get; set; } + public List Datetime { get; set; } + } + + private class WitAiEntity + { + [JsonProperty("_entity")] + public string Entity { get; set; } + [JsonProperty("_start")] + public int Start { get; set; } + public string Value { get; set; } + public decimal Confidence { get; set; } + } } } diff --git a/BotSharp.Core/Engines/Rasa/RasaAi.cs b/BotSharp.Core/Engines/Rasa/RasaAi.cs index fceac1af..26405d85 100644 --- a/BotSharp.Core/Engines/Rasa/RasaAi.cs +++ b/BotSharp.Core/Engines/Rasa/RasaAi.cs @@ -84,7 +84,7 @@ namespace BotSharp.Core.Engines private IRestResponse CallRasa(string projectId, string text, string model) { var config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration"); - var client = new RestClient($"{config.GetSection("Rasa:Nlu").Value}"); + var client = new RestClient($"{config.GetSection("RasaNlu:url").Value}"); var rest = new RestRequest("parse", Method.POST); string json = JsonConvert.SerializeObject(new { Project = projectId, Q = text, Model = model }, @@ -107,7 +107,7 @@ namespace BotSharp.Core.Engines var corpus = GetIntentExpressions(); var config = (IConfiguration)AppDomain.CurrentDomain.GetData("Configuration"); - var client = new RestClient($"{config.GetSection("Rasa:Nlu").Value}"); + var client = new RestClient($"{config.GetSection("RasaNlu:url").Value}"); var contextHashs = corpus.UserSays .Select(x => x.ContextHash) diff --git a/BotSharp.Core/Engines/SpaCy/SpaCyProvider.cs b/BotSharp.Core/Engines/SpaCy/SpaCyProvider.cs index 2bdb44c8..39a0a878 100644 --- a/BotSharp.Core/Engines/SpaCy/SpaCyProvider.cs +++ b/BotSharp.Core/Engines/SpaCy/SpaCyProvider.cs @@ -24,7 +24,7 @@ namespace BotSharp.Core.Engines.SpaCy var response = client.Execute(request); meta.Meta = JObject.FromObject(response.Data); - meta.Meta["models"] = null; + meta.Meta.Remove("models"); meta.Model = response.Data.Models; return response.IsSuccessful; diff --git a/BotSharp.MachineLearning/SpaCy/server.py b/BotSharp.MachineLearning/SpaCy/server.py index 467b3c0f..b99e4671 100644 --- a/BotSharp.MachineLearning/SpaCy/server.py +++ b/BotSharp.MachineLearning/SpaCy/server.py @@ -9,9 +9,10 @@ import spacy nlp = spacy.load('en') ner = EntityRecognizer(nlp.vocab) +# python -m spacy info @route('/load') def load(): - pass + return {'version': '2.0.11', 'models': 'en_core_web_md, en', 'python': '3.5.2'} @route('/tokenizer') def tokenize(): @@ -201,4 +202,4 @@ def entityrecognizerpredict(): -run(host='0.0.0.0', port=5005, debug=True) \ No newline at end of file +run(host='0.0.0.0', port=5005, debug=False) \ No newline at end of file diff --git a/BotSharp.RestApi/AgentController.cs b/BotSharp.RestApi/AgentController.cs index 10f74cf8..d9a45a36 100644 --- a/BotSharp.RestApi/AgentController.cs +++ b/BotSharp.RestApi/AgentController.cs @@ -32,6 +32,14 @@ namespace BotSharp.RestApi _platform = platform; } + [HttpGet] + public ActionResult> AllAgents() + { + var dc = new DefaultDataContextLoader().GetDefaultDc(); + + return dc.Table().ToList(); + } + /// /// Restore a agent from a uploaded zip file /// diff --git a/BotSharp.WebHost/Settings/bot.json b/BotSharp.WebHost/Settings/bot.json index 3e721a5e..e00880bf 100644 --- a/BotSharp.WebHost/Settings/bot.json +++ b/BotSharp.WebHost/Settings/bot.json @@ -1,15 +1,22 @@ { - "Rasa": { - "Nlu": "http://localhost:5000" + "RasaNlu": { + "url": "http://localhost:5000" + }, + + "WitAi": { + "url": "https://api.wit.ai", + "resource": "message", + "serverAccessToken": "YLLK6SFAPXNYGMKAWLOREQ5MJQSX345L", + "version": "20180811" }, "BotSharpAi": { "Lang": "en", "Provider": "SpaCyProvider", "SpaCyProvider": { - "Url": "http://10.2.21.200:5005" + "Url": "http://localhost:5005" }, - "Pipe": "SpaCyTokenizer, CRFsuiteEntityRecognizer, FasttextClassifier", + "Pipe": "SpaCyTokenizer, CRFsuiteEntityRecognizer, WitAiEntityRecognizer, FasttextClassifier", "CRFsuiteEntityRecognizer": { "fields": "y w pos chk", "uniFeatures": "w wl pos chk shape shaped type p1 p2 p3 p4 s1 s2 s3 s4 2d 4d d&a d&- d&/ d&, d&. up iu au al ad ao cu cl ca cd cs",