2018-08-14 22:21:09 +00:00
using BotSharp.Core.Agents ;
using BotSharp.Core.Engines ;
using BotSharp.Core.Engines.Rasa ;
using Microsoft.AspNetCore.Mvc ;
using Newtonsoft.Json ;
2018-08-22 15:45:50 +00:00
using Newtonsoft.Json.Linq ;
2018-08-14 22:21:09 +00:00
using Newtonsoft.Json.Serialization ;
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
namespace BotSharp.RestApi.Rasa
{
2018-08-21 22:37:09 +00:00
#if RASA_UI
2018-08-23 04:24:13 +00:00
/// <summary>
/// You can post your training data to this endpoint to train a new model for a project.
/// This request will wait for the server answer: either the model was trained successfully or the training exited with an error.
/// </summary>
2018-08-14 22:21:09 +00:00
[Route("[controller] ")]
public class TrainController : ControllerBase
{
private readonly IBotPlatform _platform ;
/// <summary>
/// Initialize dialog controller and get a platform instance
/// </summary>
/// <param name="platform"></param>
public TrainController ( IBotPlatform platform )
{
_platform = platform ;
}
2018-08-23 04:24:13 +00:00
/// <summary>
/// Using the HTTP server, you must specify the project you want to train a new model for to be able to use it during parse requests later on : /train?project=my_project.
/// </summary>
/// <param name="agent">Model name</param>
/// <param name="project"></param>
/// <returns></returns>
2018-08-14 22:21:09 +00:00
[HttpPost]
2018-08-23 04:24:13 +00:00
public async Task < ActionResult < String > > Train ( [ FromQuery ] string agent , [ FromQuery ] string project )
2018-08-22 15:45:50 +00:00
{
2018-08-23 04:24:13 +00:00
string body = "" ;
using ( var reader = new StreamReader ( Request . Body ) )
{
body = reader . ReadToEnd ( ) ;
}
var rasa_nlu_data = JsonConvert . DeserializeObject < RasaTrainRequestModel > ( body ) ;
rasa_nlu_data . Model = agent ;
var trainResult = await Train ( rasa_nlu_data , project ) ;
return trainResult ;
2018-08-22 15:45:50 +00:00
}
2018-08-23 04:24:13 +00:00
private async Task < ActionResult < String > > Train ( [ FromBody ] RasaTrainRequestModel request , [ FromQuery ] string project )
2018-08-14 22:21:09 +00:00
{
var trainer = new BotTrainer ( ) ;
if ( String . IsNullOrEmpty ( request . Project ) )
{
request . Project = project ;
}
// save corpus to agent dir
2018-08-23 12:25:55 +00:00
var projectPath = Path . Combine ( AppDomain . CurrentDomain . GetData ( "DataPath" ) . ToString ( ) , "Projects" , project ) ;
var modelPath = Path . Combine ( projectPath , request . Model ) ;
2018-08-14 22:21:09 +00:00
2018-08-23 12:25:55 +00:00
if ( ! Directory . Exists ( modelPath ) )
2018-08-14 22:21:09 +00:00
{
2018-08-23 12:25:55 +00:00
Directory . CreateDirectory ( modelPath ) ;
2018-08-14 22:21:09 +00:00
}
2018-08-23 04:24:13 +00:00
// Save raw data to file, then parse it to Agent instance.
// in order to unify the process.
2018-08-23 12:25:55 +00:00
var fileName = Path . Combine ( modelPath , "corpus.json" ) ;
2018-08-14 22:21:09 +00:00
System . IO . File . WriteAllText ( fileName , JsonConvert . SerializeObject ( request . Corpus , new JsonSerializerSettings
{
Formatting = Formatting . Indented ,
NullValueHandling = NullValueHandling . Ignore ,
ContractResolver = new CamelCasePropertyNamesContractResolver ( )
} ) ) ;
2018-08-23 12:25:55 +00:00
var agent = _platform . LoadAgentFromFile < AgentImporterInRasa > ( modelPath ,
2018-08-14 22:21:09 +00:00
new AgentImportHeader
{
Id = request . Project ,
Name = project
} ) ;
2018-08-23 04:24:13 +00:00
var info = await trainer . Train ( agent , new BotTrainOptions { Model = request . Model } ) ;
2018-08-14 22:21:09 +00:00
2018-08-15 10:46:53 +00:00
return Ok ( new { info = info . Model } ) ;
2018-08-23 04:24:13 +00:00
}
2018-08-14 22:21:09 +00:00
}
#endif
}