Add redis as optional storage

This commit is contained in:
Oceania2018 2018-09-30 20:27:57 -05:00
parent 374a82f17b
commit 7b97e22088
11 changed files with 166 additions and 48 deletions

View file

@ -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<TAgent> : IAgentStorage<TAgent>
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<TAgent>(csredis.Get(key));
}
else
{
return null;
}
}
public TAgent FetchByName(string agentName)
{
var agents = new List<TAgent>();
var keys = csredis.Keys("agent.*");
foreach (string key in keys)
{
var data = csredis.Get(key.Split('.')[1]);
var agent = JsonConvert.DeserializeObject<TAgent>(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<TAgent> Query()
{
var agents = new List<TAgent>();
var keys = csredis.Keys("agent.*");
foreach (string key in keys)
{
var data = csredis.Get(key.Split('.')[1]);
var agent = JsonConvert.DeserializeObject<TAgent>(data);
agents.Add(agent);
}
return agents;
}
}
}

View file

@ -57,6 +57,7 @@ If you feel that this project is helpful to you, please Star on the project, we
<ItemGroup>
<PackageReference Include="Colorful.Console" Version="1.2.9" />
<PackageReference Include="CSRedisCore" Version="2.6.13" />
<PackageReference Include="DotNetToolkit" Version="1.6.0" />
<PackageReference Include="EntityFrameworkCore.BootKit" Version="1.9.1" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.1.1" />

View file

@ -57,6 +57,29 @@ namespace Platform.Articulate
return null;
}
public List<IntentModel> GetReferencedIntentsByEntity(string entityId)
{
var intents = new List<IntentModel>();
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;

View file

@ -21,7 +21,7 @@ namespace Platform.Articulate.Controllers
public class AgentController : ControllerBase
{
private readonly IBotPlatform _platform;
private ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
/// <summary>
/// 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<AgentStorageInMemory<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
}
[HttpPost]
@ -45,7 +45,7 @@ namespace Platform.Articulate.Controllers
}
// convert to standard Agent structure
var builder = new ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel>();
var builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
agent.Id = Guid.NewGuid().ToString();
agent.Name = agent.AgentName;
builder.SaveAgent(agent);

View file

@ -18,11 +18,11 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class DomainController : ControllerBase
{
private ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
public DomainController()
{
builder = new ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
}
[HttpGet("{domainId}")]

View file

@ -16,11 +16,11 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class EntityController : ControllerBase
{
private ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
public EntityController()
{
builder = new ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
}
[HttpGet("{entityId}")]

View file

@ -17,11 +17,11 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class IntentController : ControllerBase
{
private ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
public IntentController()
{
builder = new ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, 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<IntentModel>());
var domain = agent.Domains.First(x => x.DomainName == intent.Domain);
domain.Intents.Add(intent.ToObject<IntentModel>());
builder.SaveAgent(agent);
return intent;
@ -84,35 +85,9 @@ namespace Platform.Articulate.Controllers
}
[HttpGet("/entity/{entityId}/intent")]
public List<IntentModel> GetReferencedIntentsByEntity([FromRoute] string entityId, [FromQuery] int start, [FromQuery] int limit)
public List<IntentViewModel> GetReferencedIntentsByEntity([FromRoute] string entityId, [FromQuery] int start, [FromQuery] int limit)
{
var intents = new List<IntentModel>();
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<EntityModel>(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<AgentModel>(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<IntentModel>(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<IntentViewModel>()).ToList();
}
[HttpGet("/domain/{domainId}/intent")]

View file

@ -15,11 +15,11 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class ScenarioController : ControllerBase
{
private ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
public ScenarioController()
{
builder = new ArticulateAi<AgentStorageInMemory<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
}
[HttpGet("/intent/{intentId}/scenario")]
@ -51,12 +51,9 @@ namespace Platform.Articulate.Controllers
var agent = builder.GetAgentByName(scenario.Agent);
var model = scenario.ToObject<ScenarioModel>();
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<ScenarioModel>();
builder.SaveAgent(agent);

View file

@ -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<AgentStorageInRedis<AgentModel>, AgentModel> builder;
public TrainController()
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
}
[HttpGet("/agent/{agentId}/train")]
public AgentModel TrainAgent([FromRoute] string agentId)
{
var agent = builder.GetAgentById(agentId);
agent.Status = "ready";
return agent;
}
}
#endif
}

View file

@ -11,7 +11,7 @@ namespace Platform.Articulate.Models
public AgentModel()
{
Domains = new List<DomainModel>();
Entities = new List<EntityBase>();
Entities = new List<EntityModel>();
}
public string Status { get; set; }
@ -34,6 +34,6 @@ namespace Platform.Articulate.Models
public List<DomainModel> Domains { get; set; }
public List<EntityBase> Entities { get; set; }
public List<EntityModel> Entities { get; set; }
}
}

View file

@ -18,8 +18,14 @@ namespace Platform.Articulate.Models
public bool UseWebhook { get; set; }
/// <summary>
/// User says
/// </summary>
public List<IntentExampleModel> Examples { get; set; }
/// <summary>
/// Intent responses
/// </summary>
public ScenarioModel Scenario { get; set; }
}
}