training api.

This commit is contained in:
Oceania2018 2018-10-01 12:15:17 -05:00
parent a5d90db155
commit f796df748e
20 changed files with 205 additions and 59 deletions

View file

@ -1,5 +1,6 @@
using BotSharp.Core.Agents;
using BotSharp.Core.Models;
using BotSharp.Platform.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;

View file

@ -14,7 +14,7 @@ namespace BotSharp.Core
where TAgent : AgentBase
{
private static CSRedisClient csredis;
private string prefix = String.Empty;
private static string prefix = String.Empty;
public AgentStorageInRedis()
{
@ -47,7 +47,7 @@ namespace BotSharp.Core
{
var agents = new List<TAgent>();
var keys = csredis.Keys($"{prefix }*");
var keys = csredis.Keys($"{prefix}*");
foreach (string key in keys)
{
var data = csredis.Get(key.Substring(prefix.Length));

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using BotSharp.Core.Models;
using BotSharp.Platform.Models;
namespace BotSharp.Core.Engines.BotSharp
{

View file

@ -7,6 +7,7 @@ using System.Threading.Tasks;
using BotSharp.Core.Abstractions;
using BotSharp.Core.Agents;
using BotSharp.Core.Intents;
using BotSharp.Platform.Models;
using DotNetToolkit;
using EntityFrameworkCore.BootKit;
using Microsoft.EntityFrameworkCore;

View file

@ -175,8 +175,8 @@ namespace BotSharp.Core.Engines
});
// set empty synonym to null
data.Entities
.Where(x => x.Synonyms != null)
/*data.Entities
.Where(x => x.Entity != null)
.ToList()
.ForEach(entity =>
{
@ -184,7 +184,7 @@ namespace BotSharp.Core.Engines
{
entity.Synonyms = null;
}
});
});*/
string json = JsonConvert.SerializeObject(new { rasa_nlu_data = data },
new JsonSerializerSettings

View file

@ -1,43 +1,70 @@
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using DotNetToolkit;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BotSharp.Core
{
public abstract class PlatformBuilderBase<TStorage, TAgent>
where TStorage : IAgentStorage<TAgent>, new ()
public abstract class PlatformBuilderBase<TAgent> where TAgent : AgentBase
{
protected static TStorage storage;
public IAgentStorage<TAgent> Storage { get; set; }
public IConfiguration PlatformConfig { get; set; }
public PlatformBuilderBase()
{
if (storage == null) storage = new TStorage();
}
public List<TAgent> GetAllAgents()
{
return storage.Query();
GetStorage();
return Storage.Query();
}
public TAgent GetAgentById(string agentId)
{
return storage.FetchById(agentId);
GetStorage();
return Storage.FetchById(agentId);
}
public TAgent GetAgentByName(string agentName)
{
return storage.FetchByName(agentName);
GetStorage();
return Storage.FetchByName(agentName);
}
public virtual bool SaveAgent(TAgent agent)
{
GetStorage();
// default save agent in FileStorage
storage.Persist(agent);
Storage.Persist(agent);
return true;
}
private IAgentStorage<TAgent> GetStorage()
{
if (Storage == null)
{
string storageName = PlatformConfig.GetValue<String>("AgentStorage");
switch (storageName)
{
case "AgentStorageInRedis":
Storage = Activator.CreateInstance<AgentStorageInRedis<TAgent>>();
break;
case "AgentStorageInMemory":
Storage = Activator.CreateInstance<AgentStorageInMemory<TAgent>>();
break;
}
}
return Storage;
}
}
}

View file

@ -10,9 +10,13 @@ namespace BotSharp.Platform.Abstraction
/// Platform abstraction
/// Implement this interface to build a Chatbot platform
/// </summary>
public interface IPlatformBuilder<TStorage, TAgent>
where TStorage : IAgentStorage<TAgent>, new()
public interface IPlatformBuilder<TAgent>
{
/// <summary>
/// Agent storage
/// </summary>
IAgentStorage<TAgent> Storage { get; set; }
/// <summary>
/// Parse options for the incoming text or voice request from the sender.
/// </summary>
@ -33,6 +37,6 @@ namespace BotSharp.Platform.Abstraction
/// <returns></returns>
bool SaveAgent(TAgent agent);
bool Train(TrainingCorpus corpus);
Task<bool> Train(TAgent agent, TrainingCorpus corpus);
}
}

View file

@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Core.Engines
namespace BotSharp.Platform.Models
{
public class BotTrainOptions
{

View file

@ -8,6 +8,6 @@ namespace BotSharp.Platform.Models
{
public virtual String Entity { get; set; }
public List<String> Synonyms { get; set; }
public List<TrainingEntitySynonym> Values { get; set; }
}
}

View file

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace BotSharp.Platform.Models
{
public class TrainingEntitySynonym
{
public String Value { get; set; }
public List<String> Synonyms { get; set; }
}
}

View file

@ -2,6 +2,8 @@
"ArticulateAi": {
"Lang": "en",
"AgentStorage": "AgentStorageInRedis",
"Provider": "BotSharpProvider",
"BotSharpProvider": {
},

View file

@ -1,11 +1,16 @@
using BotSharp.Core;
using BotSharp.Core.Agents;
using BotSharp.Core.Engines;
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using DotNetToolkit;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Platform.Articulate
{
@ -14,10 +19,10 @@ namespace Platform.Articulate
/// http://spg.ai/projects/articulate
/// This implementation takes over APIs of Articulate's 7500 port.
/// </summary>
public class ArticulateAi<TStorage, TAgent> :
PlatformBuilderBase<TStorage, TAgent>,
IPlatformBuilder<TStorage, TAgent>
where TStorage : IAgentStorage<TAgent>, new()
public class ArticulateAi<TAgent> :
PlatformBuilderBase<TAgent>,
IPlatformBuilder<TAgent>
where TAgent : AgentBase
{
public DialogRequestOptions RequestOptions { get; set; }
@ -80,23 +85,67 @@ namespace Platform.Articulate
return intents;
}
public TrainingCorpus ExtractorCorpus(TAgent specificAgent)
public TrainingCorpus ExtractorCorpus(TAgent agent)
{
var agent1 = specificAgent as AgentModel;
var standardAgent = new StandardAgent
var corpus = new TrainingCorpus();
var agt = agent as AgentModel;
corpus.Entities = agt.Entities.Select(x => new TrainingEntity
{
Name = agent1.Name,
Language = agent1.Language,
Description = agent1.Description
};
Entity = x.EntityName,
Values = x.Examples.Select(y => new TrainingEntitySynonym
{
Value = y.Value,
Synonyms = y.Synonyms
}).ToList()
}).ToList();
return new TrainingCorpus();
corpus.UserSays = new List<TrainingIntentExpression<TrainingIntentExpressionPart>>();
foreach(DomainModel domain in agt.Domains)
{
foreach(IntentModel intent in domain.Intents)
{
foreach(IntentExampleModel example in intent.Examples)
{
var say = new TrainingIntentExpression<TrainingIntentExpressionPart>()
{
Intent = intent.IntentName,
Text = example.UserSays,
Entities = example.Entities.Select(x => new TrainingIntentExpressionPart
{
Entity = x.Entity,
Start = x.Start,
Value = x.Value
}).ToList()
};
corpus.UserSays.Add(say);
}
}
}
return corpus;
}
public bool Train(TrainingCorpus corpus)
public async Task<bool> Train(TAgent agent, TrainingCorpus corpus)
{
throw new NotImplementedException();
string agentDir = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", agent.Id);
// save corpus to agent dir
var projectPath = Path.Combine(AppDomain.CurrentDomain.GetData("DataPath").ToString(), "Projects", agent.Id);
var model = "model_" + DateTime.UtcNow.ToString("yyyyMMdd");
var modelPath = Path.Combine(projectPath, model);
var trainer = new BotTrainer();
var parsedAgent = agent.ToObject<Agent>();
var info = await trainer.Train(parsedAgent, new BotTrainOptions
{
AgentDir = projectPath,
Model = model
});
return true;
}
}
}

View file

@ -4,6 +4,7 @@ using BotSharp.Core.Engines;
using BotSharp.Platform.Abstraction;
using BotSharp.Platform.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Platform.Articulate;
using Platform.Articulate.Models;
@ -20,17 +21,19 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class AgentController : ControllerBase
{
private readonly IConfiguration configuration;
private readonly IBotPlatform _platform;
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private ArticulateAi<AgentModel> builder;
/// <summary>
/// Initialize agent controller and get a platform instance
/// </summary>
/// <param name="platform"></param>
public AgentController(IBotPlatform platform)
public AgentController(IBotPlatform platform, IConfiguration configuration)
{
_platform = platform;
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpPost]
@ -45,7 +48,6 @@ namespace Platform.Articulate.Controllers
}
// convert to standard Agent structure
var builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
agent.Id = Guid.NewGuid().ToString();
agent.Name = agent.AgentName;
builder.SaveAgent(agent);

View file

@ -1,6 +1,7 @@
using BotSharp.Core;
using BotSharp.Platform.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Platform.Articulate.Models;
@ -18,11 +19,13 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class DomainController : ControllerBase
{
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private readonly IConfiguration configuration;
private ArticulateAi<AgentModel> builder;
public DomainController()
public DomainController(IConfiguration configuration)
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpGet("{domainId}")]

View file

@ -1,6 +1,7 @@
using BotSharp.Core;
using BotSharp.Platform.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using Platform.Articulate.ViewModels;
@ -16,11 +17,13 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class EntityController : ControllerBase
{
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private readonly IConfiguration configuration;
private ArticulateAi<AgentModel> builder;
public EntityController()
public EntityController(IConfiguration configuration)
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpGet("{entityId}")]

View file

@ -2,6 +2,7 @@
using BotSharp.Platform.Models;
using DotNetToolkit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using Platform.Articulate.ViewModels;
@ -17,11 +18,13 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class IntentController : ControllerBase
{
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private readonly IConfiguration configuration;
private ArticulateAi<AgentModel> builder;
public IntentController()
public IntentController(IConfiguration configuration)
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpGet("{intentId}")]
@ -52,6 +55,31 @@ namespace Platform.Articulate.Controllers
return intent;
}
[HttpPut("{intentId}")]
public IntentViewModel PutIntent([FromRoute] string intentId)
{
IntentViewModel intent = null;
using (var reader = new StreamReader(Request.Body))
{
string body = reader.ReadToEnd();
intent = JsonConvert.DeserializeObject<IntentViewModel>(body);
}
var agent = builder.GetAgentByIntentId(intentId);
var updateAgent = agent.Item1;
var updateIntents = updateAgent.Domains.First(x => x.Id == agent.Item2.Id).Intents;
var updateIntent = updateIntents.First(x => x.Id == agent.Item3.Id);
updateIntent.IntentName = intent.IntentName;
updateIntent.Examples = intent.Examples;
builder.SaveAgent(updateAgent);
return intent;
}
[HttpGet("{intentId}/webhook")]
public void GetIntentWebhook([FromRoute] string intentId)
{

View file

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
@ -9,6 +10,8 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class ParseControllercs : ControllerBase
{
private readonly IConfiguration configuration;
[HttpGet("/agent/{agentId}/converse")]
public void ParseText([FromRoute] string agentId, [FromQuery] string text, [FromQuery] string sessionId)
{

View file

@ -1,6 +1,7 @@
using BotSharp.Core;
using DotNetToolkit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using System;
@ -15,11 +16,13 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class ScenarioController : ControllerBase
{
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private readonly IConfiguration configuration;
private ArticulateAi<AgentModel> builder;
public ScenarioController()
public ScenarioController(IConfiguration configuration)
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpGet("/intent/{intentId}/scenario")]

View file

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Platform.Articulate.Models;
using System;
@ -12,6 +13,8 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class SettingsController : ControllerBase
{
private readonly IConfiguration configuration;
[HttpGet]
public SettingsModel GetSettings()
{

View file

@ -1,9 +1,11 @@
using BotSharp.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Platform.Articulate.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Platform.Articulate.Controllers
{
@ -11,20 +13,21 @@ namespace Platform.Articulate.Controllers
[Route("[controller]")]
public class TrainController : ControllerBase
{
private ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel> builder;
private readonly IConfiguration configuration;
private ArticulateAi<AgentModel> builder;
public TrainController()
public TrainController(IConfiguration configuration)
{
builder = new ArticulateAi<AgentStorageInRedis<AgentModel>, AgentModel>();
builder = new ArticulateAi<AgentModel>();
builder.PlatformConfig = configuration.GetSection("ArticulateAi");
}
[HttpGet("/agent/{agentId}/train")]
public AgentModel TrainAgent([FromRoute] string agentId)
public async Task<AgentModel> TrainAgent([FromRoute] string agentId)
{
var agent = builder.GetAgentById(agentId);
var corpus = builder.ExtractorCorpus(agent);
await builder.Train(agent, corpus);
agent.Status = "Ready";
return agent;