Add redis as optional storage
This commit is contained in:
parent
374a82f17b
commit
7b97e22088
84
BotSharp.Core/AgentStorageInRedis.cs
Normal file
84
BotSharp.Core/AgentStorageInRedis.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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}")]
|
||||
|
|
|
|||
|
|
@ -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}")]
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
32
Platform.Articulate/Controllers/TrainController.cs
Normal file
32
Platform.Articulate/Controllers/TrainController.cs
Normal 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
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue