From 7b97e22088344e84dc51a98040395117fdd17912 Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Sun, 30 Sep 2018 20:27:57 -0500 Subject: [PATCH] Add redis as optional storage --- BotSharp.Core/AgentStorageInRedis.cs | 84 +++++++++++++++++++ BotSharp.Core/BotSharp.Core.csproj | 1 + Platform.Articulate/ArticulateAi.cs | 23 +++++ .../Controllers/AgentController.cs | 6 +- .../Controllers/DomainController.cs | 4 +- .../Controllers/EntityController.cs | 4 +- .../Controllers/IntentController.cs | 37 ++------ .../Controllers/ScenarioController.cs | 13 ++- .../Controllers/TrainController.cs | 32 +++++++ Platform.Articulate/Models/AgentModel.cs | 4 +- Platform.Articulate/Models/IntentModel.cs | 6 ++ 11 files changed, 166 insertions(+), 48 deletions(-) create mode 100644 BotSharp.Core/AgentStorageInRedis.cs create mode 100644 Platform.Articulate/Controllers/TrainController.cs diff --git a/BotSharp.Core/AgentStorageInRedis.cs b/BotSharp.Core/AgentStorageInRedis.cs new file mode 100644 index 00000000..bc636f06 --- /dev/null +++ b/BotSharp.Core/AgentStorageInRedis.cs @@ -0,0 +1,84 @@ +using BotSharp.Platform.Abstraction; +using BotSharp.Platform.Models; +using CSRedis; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace BotSharp.Core +{ + public class AgentStorageInRedis : IAgentStorage + where TAgent : AgentBase + { + private static CSRedisClient csredis; + + public AgentStorageInRedis() + { + if (csredis == null) + { + csredis = new CSRedisClient("127.0.0.1:6379,defaultDatabase=botsharp,poolsize=50,ssl=false,writeBuffer=10240,prefix=agent."); + } + } + + public TAgent FetchById(string agentId) + { + var key = agentId; + if (csredis.Exists(key)) + { + return JsonConvert.DeserializeObject(csredis.Get(key)); + } + else + { + return null; + } + } + + public TAgent FetchByName(string agentName) + { + var agents = new List(); + + var keys = csredis.Keys("agent.*"); + foreach (string key in keys) + { + var data = csredis.Get(key.Split('.')[1]); + var agent = JsonConvert.DeserializeObject(data); + + if(agent.Name == agentName) + { + return agent; + } + } + + return default(TAgent); + } + + public bool Persist(TAgent agent) + { + if (String.IsNullOrEmpty(agent.Id)) + { + agent.Id = Guid.NewGuid().ToString(); + } + + csredis.Set(agent.Id, JsonConvert.SerializeObject(agent)); + + return true; + } + + public List Query() + { + var agents = new List(); + + var keys = csredis.Keys("agent.*"); + foreach (string key in keys) + { + var data = csredis.Get(key.Split('.')[1]); + var agent = JsonConvert.DeserializeObject(data); + agents.Add(agent); + } + + return agents; + } + } +} diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj index b7afbf98..e0d24abc 100644 --- a/BotSharp.Core/BotSharp.Core.csproj +++ b/BotSharp.Core/BotSharp.Core.csproj @@ -57,6 +57,7 @@ If you feel that this project is helpful to you, please Star on the project, we + diff --git a/Platform.Articulate/ArticulateAi.cs b/Platform.Articulate/ArticulateAi.cs index c902ccdd..2aec19bd 100644 --- a/Platform.Articulate/ArticulateAi.cs +++ b/Platform.Articulate/ArticulateAi.cs @@ -57,6 +57,29 @@ namespace Platform.Articulate return null; } + public List GetReferencedIntentsByEntity(string entityId) + { + var intents = new List(); + var allAgents = GetAllAgents(); + foreach (TAgent agt in allAgents) + { + var agent = agt as AgentModel; + + foreach (DomainModel domain in agent.Domains) + { + foreach (IntentModel intent in domain.Intents) + { + if(intent.Examples.Exists(x => x.Entities.Exists(y => y.EntityId == entityId))) + { + intents.Add(intent); + } + } + } + } + + return intents; + } + public StandardAgent StandardizeAgent(TAgent specificAgent) { var agent1 = specificAgent as AgentModel; diff --git a/Platform.Articulate/Controllers/AgentController.cs b/Platform.Articulate/Controllers/AgentController.cs index d6f90380..021ed7e2 100644 --- a/Platform.Articulate/Controllers/AgentController.cs +++ b/Platform.Articulate/Controllers/AgentController.cs @@ -21,7 +21,7 @@ namespace Platform.Articulate.Controllers public class AgentController : ControllerBase { private readonly IBotPlatform _platform; - private ArticulateAi, AgentModel> builder; + private ArticulateAi, AgentModel> builder; /// /// Initialize agent controller and get a platform instance @@ -30,7 +30,7 @@ namespace Platform.Articulate.Controllers public AgentController(IBotPlatform platform) { _platform = platform; - builder = new ArticulateAi, AgentModel>(); + builder = new ArticulateAi, AgentModel>(); } [HttpPost] @@ -45,7 +45,7 @@ namespace Platform.Articulate.Controllers } // convert to standard Agent structure - var builder = new ArticulateAi, AgentModel>(); + var builder = new ArticulateAi, AgentModel>(); agent.Id = Guid.NewGuid().ToString(); agent.Name = agent.AgentName; builder.SaveAgent(agent); diff --git a/Platform.Articulate/Controllers/DomainController.cs b/Platform.Articulate/Controllers/DomainController.cs index a17f7d80..4115d66a 100644 --- a/Platform.Articulate/Controllers/DomainController.cs +++ b/Platform.Articulate/Controllers/DomainController.cs @@ -18,11 +18,11 @@ namespace Platform.Articulate.Controllers [Route("[controller]")] public class DomainController : ControllerBase { - private ArticulateAi, AgentModel> builder; + private ArticulateAi, AgentModel> builder; public DomainController() { - builder = new ArticulateAi, AgentModel>(); + builder = new ArticulateAi, AgentModel>(); } [HttpGet("{domainId}")] diff --git a/Platform.Articulate/Controllers/EntityController.cs b/Platform.Articulate/Controllers/EntityController.cs index e3dac061..c9bcb08c 100644 --- a/Platform.Articulate/Controllers/EntityController.cs +++ b/Platform.Articulate/Controllers/EntityController.cs @@ -16,11 +16,11 @@ namespace Platform.Articulate.Controllers [Route("[controller]")] public class EntityController : ControllerBase { - private ArticulateAi, AgentModel> builder; + private ArticulateAi, AgentModel> builder; public EntityController() { - builder = new ArticulateAi, AgentModel>(); + builder = new ArticulateAi, AgentModel>(); } [HttpGet("{entityId}")] diff --git a/Platform.Articulate/Controllers/IntentController.cs b/Platform.Articulate/Controllers/IntentController.cs index d66e190d..305c2d00 100644 --- a/Platform.Articulate/Controllers/IntentController.cs +++ b/Platform.Articulate/Controllers/IntentController.cs @@ -17,11 +17,11 @@ namespace Platform.Articulate.Controllers [Route("[controller]")] public class IntentController : ControllerBase { - private ArticulateAi, AgentModel> builder; + private ArticulateAi, AgentModel> builder; public IntentController() { - builder = new ArticulateAi, AgentModel>(); + builder = new ArticulateAi, AgentModel>(); } [HttpGet("{intentId}")] @@ -45,7 +45,8 @@ namespace Platform.Articulate.Controllers var agent = builder.GetAgentByName(intent.Agent); intent.Id = Guid.NewGuid().ToString(); - agent.Domains[0].Intents.Add(intent.ToObject()); + var domain = agent.Domains.First(x => x.DomainName == intent.Domain); + domain.Intents.Add(intent.ToObject()); builder.SaveAgent(agent); return intent; @@ -84,35 +85,9 @@ namespace Platform.Articulate.Controllers } [HttpGet("/entity/{entityId}/intent")] - public List GetReferencedIntentsByEntity([FromRoute] string entityId, [FromQuery] int start, [FromQuery] int limit) + public List GetReferencedIntentsByEntity([FromRoute] string entityId, [FromQuery] int start, [FromQuery] int limit) { - var intents = new List(); - - string dataDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Articulate"); - - string entityPath = Directory.GetFiles(dataDir).FirstOrDefault(x => x.Contains($"-entity-{entityId}.json")); - var entity = JsonConvert.DeserializeObject(System.IO.File.ReadAllText(entityPath)); - - string agentId = entityPath.Split(Path.DirectorySeparatorChar).Last().Split('-')[1]; - - string agentPath = Directory.GetFiles(dataDir).FirstOrDefault(x => x.Contains($"agent-{agentId}.json")); - var agent = JsonConvert.DeserializeObject(System.IO.File.ReadAllText(agentPath)); - - var intentPaths = Directory.GetFiles(dataDir).Where(x => x.Contains($"agent-{agent.Id}-intent-")).ToList(); - - for (int i = 0; i < intentPaths.Count; i++) - { - string json = System.IO.File.ReadAllText(intentPaths[i]); - - var intent = JsonConvert.DeserializeObject(json); - - if (intent.Examples.Exists(x => x.Entities.Exists(e => e.EntityId == entityId))) - { - intents.Add(intent); - } - } - - return intents; + return builder.GetReferencedIntentsByEntity(entityId).Select(x => x.ToObject()).ToList(); } [HttpGet("/domain/{domainId}/intent")] diff --git a/Platform.Articulate/Controllers/ScenarioController.cs b/Platform.Articulate/Controllers/ScenarioController.cs index 1c8d8711..3b959063 100644 --- a/Platform.Articulate/Controllers/ScenarioController.cs +++ b/Platform.Articulate/Controllers/ScenarioController.cs @@ -15,11 +15,11 @@ namespace Platform.Articulate.Controllers [Route("[controller]")] public class ScenarioController : ControllerBase { - private ArticulateAi, AgentModel> builder; + private ArticulateAi, AgentModel> builder; public ScenarioController() { - builder = new ArticulateAi, AgentModel>(); + builder = new ArticulateAi, AgentModel>(); } [HttpGet("/intent/{intentId}/scenario")] @@ -51,12 +51,9 @@ namespace Platform.Articulate.Controllers var agent = builder.GetAgentByName(scenario.Agent); - var model = scenario.ToObject(); - - agent.Domains.First(x => x.DomainName == scenario.Domain) - .Intents - .First(x => x.IntentName == scenario.Intent) - .Scenario = model; + var domain = agent.Domains.FirstOrDefault(x => x.DomainName == scenario.Domain); + var intent = domain.Intents.FirstOrDefault(x => x.IntentName == scenario.Intent); + intent.Scenario = scenario.ToObject(); builder.SaveAgent(agent); diff --git a/Platform.Articulate/Controllers/TrainController.cs b/Platform.Articulate/Controllers/TrainController.cs new file mode 100644 index 00000000..da6b32af --- /dev/null +++ b/Platform.Articulate/Controllers/TrainController.cs @@ -0,0 +1,32 @@ +using BotSharp.Core; +using Microsoft.AspNetCore.Mvc; +using Platform.Articulate.Models; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Platform.Articulate.Controllers +{ +#if ARTICULATE + [Route("[controller]")] + public class TrainController : ControllerBase + { + private ArticulateAi, AgentModel> builder; + + public TrainController() + { + builder = new ArticulateAi, AgentModel>(); + } + + [HttpGet("/agent/{agentId}/train")] + public AgentModel TrainAgent([FromRoute] string agentId) + { + var agent = builder.GetAgentById(agentId); + + agent.Status = "ready"; + + return agent; + } + } +#endif +} diff --git a/Platform.Articulate/Models/AgentModel.cs b/Platform.Articulate/Models/AgentModel.cs index cc1e60fe..e5dbbb81 100644 --- a/Platform.Articulate/Models/AgentModel.cs +++ b/Platform.Articulate/Models/AgentModel.cs @@ -11,7 +11,7 @@ namespace Platform.Articulate.Models public AgentModel() { Domains = new List(); - Entities = new List(); + Entities = new List(); } public string Status { get; set; } @@ -34,6 +34,6 @@ namespace Platform.Articulate.Models public List Domains { get; set; } - public List Entities { get; set; } + public List Entities { get; set; } } } diff --git a/Platform.Articulate/Models/IntentModel.cs b/Platform.Articulate/Models/IntentModel.cs index b1a2cc3f..356c58f3 100644 --- a/Platform.Articulate/Models/IntentModel.cs +++ b/Platform.Articulate/Models/IntentModel.cs @@ -18,8 +18,14 @@ namespace Platform.Articulate.Models public bool UseWebhook { get; set; } + /// + /// User says + /// public List Examples { get; set; } + /// + /// Intent responses + /// public ScenarioModel Scenario { get; set; } } }